Google Code Prettify

2019年2月19日 星期二

[STM32]使用Timer中斷

前一個實驗,使用IO來控制LED,並且運用Delay的副程式來讓LED一秒切換一次狀態,但是這樣的作法實際上並不理想,大多數Delay的副程式是使用while迴圈來讓程式空轉,達到延時或計時的效果,這意味著在這空轉的期間,系統的主程式沒辦法做讓何事情。

為了使程式在使用上更有效率,大部分類似的功能都是使用Timer來實現。

以下是Timer的設定步驟

選擇完晶片後,首先是設定外部震盪,如果要使用內部震盪可直接略過

選擇外部震盪

再來是選擇Clock source

選擇internal clock

再來跳到Clock configuration,設定頻率,這邊我是使用外部震盪,石英晶體的頻率為8M,最後APB1與APB2的頻率為24M。

Clock configuration
接下來是要設定Timer的中斷間隔,我使用的是Timer1來做示範,可以查看資料手冊中,Timer的Clock source 是APB2



接下來要計算Timer的中斷時間,以0.5s為範例,我時脈是24M,Prescaler應該要設定
24M/(2-1),但是Prescaler數值範圍只有16bit也就是0~65535所以我們要用一些變通的方法來做,Prescaler設定23999,也就是24K-1,然後把Period設定成500,也就是說計數器每秒可以計數1000次,在計數到第500次的時候發生中斷,執行中斷的內容。

Prescaler與Period的設定值


Main程式中新增
HAL_TIM_Base_Start_IT(&htim1);

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM1_Init();
  /* USER CODE BEGIN 2 */
 HAL_TIM_Base_Start_IT(&htim1);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
 
 

在TIM1_UP_TIM16_IRQHandler中加入IO狀態切換的副程式


void TIM1_UP_TIM16_IRQHandler(void)

{

  /* USER CODE BEGIN TIM1_UP_TIM16_IRQn 0 */

 HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_9);

  /* USER CODE END TIM1_UP_TIM16_IRQn 0 */

  HAL_TIM_IRQHandler(&htim1);

  /* USER CODE BEGIN TIM1_UP_TIM16_IRQn 1 */



  /* USER CODE END TIM1_UP_TIM16_IRQn 1 */

}



2019年1月22日 星期二

[STM32]STM32Cube改版

因為工作上忙碌,有很長的一段時間沒有更新,本來想說將剩下的基礎實驗範例補齊,發現CUBE有新版本,更新了之後.........怎變成這樣....

新版的起始畫面
當下感覺有點抗拒,仔細的看過並且體驗了一下之後,雖然需要適應一下,但是沒有想像中的這麼糟糕,整體來說,介面應該算是變得比較直覺,操作的流程原本一些比較瑣碎的地方也改善了
開啟新專案直接將透過MCU或Board的選項顯示出來了
改版後,功能選擇畫面也跟設定畫面整合在同一個頁面中,舊版需要將功能勾選完之後,再到設定頁面進行細部設定,改成這樣之後操作流程流暢多了,也比較不容易忘記去設定功能

GPIO細部設定
Timer細部設定

2018年8月17日 星期五

[STM32]第一支程式GPIO

 在學習任何程式語言的第一個作業,通常都是Hello world,讓Hello world的文字顯示在畫面上,原因是因為這程式簡單好懂,作為第一個作業可以讓初學者體驗程式語言的樂趣及建立信心,增進學習動機,而利用GPIO來點亮開發版上的LED,也因為簡單好懂常被作為教材的第一個程式。

上一篇文章有提到STM32Cube的基本操作,這篇就直接從設定晶片開始。

選完晶片後的開始畫面
設定晶片的單步除錯腳位
除錯腳位設定為SW


我使用的開發版上LED為PC8、PC9,選擇這兩個腳位將他設定成GPIO_output

設定腳位功能
可以從左邊的project,切換到Function,找到GPIO的檔案,使用方式裡面有官方提供的註解,這邊簡要的介紹一下。
GPIO常用的函式如下:
HAL_GPIO_WritePin(); 寫入PIN的狀態
HAL_GPIO_ReadPin();讀取PIN的狀態
HAL_GPIO_TogglePin();切換當前PIN的狀態,例如0->1、1->0

找到GPIO的library


LED閃爍實驗,一秒切換一次狀態。



  /* USER CODE BEGIN 2 */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {

  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */
 HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_9);
 HAL_Delay(1000);
  }
  /* USER CODE END 3 */

}
 
  /* USER CODE END 2 */

2018年6月20日 星期三

[STM32]如何使用STM32Cube

這是剛建立此Blog的第一篇文章,STM32Cube我本身其實已經使用了一段時間了,所以整理一些過程中比較容易遇到的問題或是一些小技巧來分享給大家。

開啟後的畫面如下
啟動後的畫面

找到Help的地方有個Manage embedded software package的選項,點下去會跳出管理package的頁面

點選Manage embedded software package

然後安裝自己使用的MCU所需要的Package,第一次使用如果忘記此步驟也沒關係,最後在產生專案時,它還是會跳出來要你安裝,由於檔案不小,加上ST的伺服器其實有點慢,安裝好的檔案會存放在C:\Users\UserName\STM32Cube\Repository,可以直接從其他已經安裝好的電腦Copy,若有複數的電腦需要安裝,可以省下不少時間。

安裝Package
 安裝完成後就可以開始使用,按下New Project會有MCU的清單,也可以點選左上角的Board Selector 以開發板來做選擇。

MCU選擇畫面

選擇完MCU或開發版後,會出現MCU的設定畫面,可以直接點選腳位來設定想要的功能,並由左列來設定相關參數,設定完成後,從Project裡點選Generate Code,細部功能該如何設定,之後會另外再寫一篇文章來做較詳細的介紹。

MCU腳位設定畫面
點選Generate Code後會出現下圖,設定完Project Name跟輸出路徑後,選擇自己的IDE。

選擇自己使用的IDE

打開專案後,記得設定自己的燒錄器及Port的類型。

把JTAG改成Single Wire
 如果有不能燒錄的情形,記得檢查一下Flash設定,早期的Cube產生的專案,會有沒有設定Flash的情形必須自行設定,目前新版本還沒有遇到這樣的問題。
Flash設定
程式是由Cube自動產生的,程式當中都會有Begin跟End的註解,寫在這兩者之間,使用Cube更改晶片設定,更新code的時候,使用者自行新增的部分就會保留了



  /* USER CODE BEGIN 2 */
 HAL_TIM_Base_Start_IT(&htim3);
 HAL_UART_Receive_IT(&huart1, (uint8_t *)&COM1.aRxBuffer, 1) ;
 HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,1);
 HAL_GPIO_WritePin(GPIOA,GPIO_PIN_6,1);
 
  /* USER CODE END 2 */

[STM32]使用Timer中斷

前一個實驗,使用IO來控制LED,並且運用Delay的副程式來讓LED一秒切換一次狀態,但是這樣的作法實際上並不理想,大多數Delay的副程式是使用while迴圈來讓程式空轉,達到延時或計時的效果,這意味著在這空轉的期間,系統的主程式沒辦法做讓何事情。 為了使程式在使用上更有...