1. 程式人生 > >STM32CubeMX學習教程之四:定時器中斷

STM32CubeMX學習教程之四:定時器中斷

完整原始碼下載:

https://github.com/simonliu009/STM32CubeMX-TIM1-Interrupt

軟體:

STM32CubeMX V4.25.0  

System Workbench V2.4

韌體庫版本:

STM32Cube FW_F1 V1.6.1

硬體:

OneNet 麒麟座V2.3

在STM32CubeMX中新建專案,選擇正確的MCU型號


首先設定RCC和SYS,如下圖


啟用TIM1,選擇內部時鐘源(Internal Clock)。

然後根據板子實際情況設定時鐘(麒麟座外部晶振是12M,STM32F103x的最高主頻是72M),如下圖


GPIO設定 PC7和 PC10為GPIO_OUTPUT, (這是麒麟座V2.3的四個LED管腳其中的兩個)



設定其中一個預設為高電平,另一個預設為低電平,User Label分別是LED1和LED4。


設定TIM1,啟用中斷


由於TIM1是掛在APB2總線上(如何判斷當前計時器在哪個匯流排,文章最後會描述方法),檢視時鐘樹我們知道APB2當前頻率為72MHz,我們希望每秒鐘發生2次中斷,就把預分頻係數設定為36000-1,自動過載值為1000-1,得到的計時器更新中斷頻率即為72,000,000/36000/1000=2Hz。


Project - setting ,ToolChain/IDE選擇 SW4STM32


勾選這裡


儲存以後,點選工作列的生成程式碼圖示


生成完畢以後在彈出的對話方塊點選"Open Project", System Workbench自動開啟Eclipse並匯入和打開了專案,然後展開專案樹,雙擊編輯main.c,在while(1)之前啟用TIM1並使能其中斷


  /* USER CODE BEGIN 2 */
 HAL_TIM_Base_Start_IT(&htim1);

  /* USER CODE END 2 */
然後新增如下程式碼(注意此回撥函式預設是__weak定義的,所以我們在這裡需要重新定義一下,而且此回撥函式是所有定時器共用的,所以我們需要先通過if (htim->Instance == htim1.Instance)判斷它是哪個定時器中斷在呼叫)

/* USER CODE BEGIN 4 */

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

{

if (htim->Instance

== htim1.Instance)

{

/* Toggle LED */

HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);

HAL_GPIO_TogglePin(LED4_GPIO_Port,LED4_Pin);

}

}

/* USER CODE END 4 */

然後右鍵點選專案,選擇Properties, Run-Debug Settings, 點選右側的New,在彈出對話方塊中選擇Ac6 STM32 Debugging。

然後工作列上點選Run圖,當然會報錯的,原因請檢視另一篇我的部落格(https://blog.csdn.net/toopoo/article/details/79680323),所以需要右鍵點選  專案名Run.cfg ,給它改個名字,

然後右鍵點選專案樹裡面的專案名稱,選擇“Propeties”,然後在Run/Debug Settings-選擇專案名-Edit-Main-C/C++Application那裡點選“Search Project”,然後選擇出現的預設的elf檔案:

然後在Debugger-User Defined-Browse 那裡選擇你自己改名的配置檔案:

然後右鍵點選那個新的cfg檔案,選擇"Open With - Text Editor", 進行如下更改:

source [find interface/stlink.cfg] 更改為 source [find interface/stlink-v2.cfg]

reset_config srst_only srst_nogate connect_assert_srst 這一行改為 reset_config none 

然後再Run一下,就可以了。

程式的作用是讓LED1和LED4交替閃爍,每0.5秒進行一次交替(2Hz)。

如前文所述,我們如何知道TIM1是連線到APB2上的呢?我們可以查程式碼,開啟main.c

看到

static void MX_GPIO_Init(void);

右鍵點選 MX_GPIO_Init(void),選擇選單的“Open Declaration”,然後跳轉到它的定義

static void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct;

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(LED4_GPIO_Port, LED4_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pins : LED1_Pin LED4_Pin */
  GPIO_InitStruct.Pin = LED1_Pin|LED4_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

}

在HAL_RCC_GPIOD_CLK_ENABLE( )上面點選右鍵,選擇選單的“Open Declaration”。會跳轉到 stm32f1xx_hal_rcc.h檔案,裡面程式碼如下:

#define __HAL_RCC_GPIOD_CLK_ENABLE()   do { \
                                        __IO uint32_t tmpreg; \
                                        SET_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPDEN);\
                                        /* Delay after an RCC peripheral clock enabling */\
                                        tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPDEN);\
                                        UNUSED(tmpreg); \
                                      } while(0U)

#define __HAL_RCC_ADC1_CLK_ENABLE()   do { \
                                        __IO uint32_t tmpreg; \
                                        SET_BIT(RCC->APB2ENR, RCC_APB2ENR_ADC1EN);\
                                        /* Delay after an RCC peripheral clock enabling */\
                                        tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_ADC1EN);\
                                        UNUSED(tmpreg); \
                                      } while(0U)

#define __HAL_RCC_TIM1_CLK_ENABLE()   do { \
                                        __IO uint32_t tmpreg; \
                                        SET_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM1EN);\
                                        /* Delay after an RCC peripheral clock enabling */\
                                        tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM1EN);\
                                        UNUSED(tmpreg); \
                                      } while(0U)

可以看到TIM_CLK相關暫存器是APB2ENR,說明它是掛在APB2總線上的。

或者我們也可以檢視資料手冊


可以看到TIM1和TIM8是掛在APB2上的。

相關推薦

STM32CubeMX學習教程定時中斷

完整原始碼下載:https://github.com/simonliu009/STM32CubeMX-TIM1-Interrupt軟體:STM32CubeMX V4.25.0  System Workbench V2.4韌體庫版本:STM32Cube FW_F1 V1.6.1

Linux時間子系統定時的引擎clock_event_device

到來 開始 register 工作模式 統一 10個 net 說過 序列 早期的內核版本中,進程的調度基於一個稱之為tick的時鐘滴答,通常使用時鐘中斷來定時地產生tick信號,每次tick定時中斷都會進行進程的統計和調度,並對tick進行計數,記錄在一個jiffies變量

STM32CubeMX學習教程ADC讀取電壓並輸出到串列埠

完整原始碼下載:https://github.com/simonliu009/STM32CubeMX-ADC軟體:STM32CubeMX V4.25.0  System Workbench V2.4韌體庫版本:STM32Cube FW_F1 V1.6.1硬體:OneNet 麒

STM32CubeMX學習教程硬體I2C讀寫AT24C02

完整原始碼下載:https://github.com/simonliu009/STM32CubeMX-hardware-I2C-AT24C02網上有流傳已久一種說法,就是STM的I2C有bug,不好用。確實很多人在實際應用中都遇到了各種問題,所以絕大部分人都是在用軟體模擬II

STM32CubeMX學習教程PWM實現呼吸燈效果

完整原始碼下載:https://github.com/simonliu009/STM32CubeMX-PWM-Output軟體:STM32CubeMX V4.25.0  System Workbench V2.4韌體庫版本:STM32Cube FW_F1 V1.6.1硬體:O

STM32CubeMX學習教程DAC輸出電壓,ADC讀取電壓並輸出到串列埠

完整原始碼下載:https://github.com/simonliu009/STM32CubeMX-DAC-and-ADC這一篇教程目標是由DAC輸出一個階梯電壓,把它連線到一個ADC,由ADC讀取這個電壓並輸出到串列埠。軟體:STM32CubeMX V4.25.0  Sy

STM32CubeMX學習教程GPIO輸入利用SysTick中斷給按鍵去抖

完整原始碼下載:https://github.com/simonliu009/STM32CubeMX-GPIO-Debounce上一篇博文講述瞭如何使用GPIO的外部中斷檢測按鍵控制LED。但是實際情況是,物理按鍵通常會有抖動,導致中斷多次被觸發。較好的設計,應該是在硬體上做

CAN匯流排學習記錄定時與同步

一、位定時 1.1 位元率和波特率 1)位速率:又叫做位元率(bit rata)、資訊傳輸率,表示的是單位時間內,總線上傳輸的資訊量,即每秒能夠傳輸的二進位制位的數量,單位是bit per second。 2)波特率:又叫做傳位元速率、訊號傳輸率,表示的是單位時間內傳輸的碼元的數量,當兩相調製時,一個碼

Linux時間子系統定時的應用--msleep(),hrtimer_nanosleep()

get 關系 警告 mov signed num wakeup sch switch 我們已經在前面幾章介紹了低分辨率定時器和高精度定時器的實現原理,內核為了方便其它子系統,在時間子系統中提供了一些用於延時或調度的API,例如msleep,hrtimer_nanosleep

機器學習入門機器學習的方法-神經網絡(轉載)

轉載 bsp 圖像 src nbsp 加速 數值 str 我們   轉自 飛鳥各投林   神經網絡      神經網絡(也稱之為人工神經網絡,ANN)算法是80年代機器學習界非常流行的算法,不過在90年代中途衰落。現在,攜著“深度學習”之勢,神

Android異步載入學習筆記利用緩存優化網絡載入圖片及ListView載入優化

角度 thread 下午 出發 easy code cat height back 假設不做不論什麽處理。直接用網絡載入圖片在網速快的情況下可能沒什麽不好的感覺。可是假設使用移動流量或是網絡不好的時候。問題就來了,要麽用戶會抱怨流量使用太多。要麽抱怨圖

Spring 基礎教程JavaBean基本配置詳解

一:xml 裝配JavaBean屬性含義: 1.id:指定該Bean 的唯一標識。 2.class:指定該Bean 的全限定名。 3.name:為該Bean 指定一到多個別名。多個別名可以用“,”和“;”分割。

Memcached學習筆記Memcache應用場景介紹

對於高併發高訪問的Web應用程式來說,資料庫存取瓶頸一直是個令人頭疼的問題。特別當你的程式架構還是建立在單資料庫模式,而一個數據池連線數峰 值已經達到500的時候,那你的程式執行離崩潰的邊緣也不遠了。很多小網站的開發人員一開始都將注意力放在了產品需求設計上,缺忽視了程式整體效能,可擴 展性等方面的考

MongoDB最簡單的入門教程使用Spring Boot操作MongoDB

Spring Boot 是一個輕量級框架,可以完成基於 Spring 的應用程式的大部分配置工作。Spring Boot的目的是提供一組工具,以便快速構建容易配置的Spring應用程式,省去大量傳統Spring專案的繁瑣配置。 MongoDB是一個基於分散式檔

SpringSecurity學習筆記攔截請求

在任何應用中,並不是所有請求都需要同等程度地保護起來。有些請求需要認證,有些則不需要。 對每個請求進行細粒度安全性控制的關鍵在於過載configure(HttpSecurity)方法。如下程式碼片段展現了過載的configure(HttpSecurity)方法,它為不同的UR

[HAL庫學習路]7.定時中斷

記錄自己的STM32的HAL庫的學習之路,不定期更新… 一、Pinout 二、Clock Configuration 三、Configuration 定時器溢位時

[VB學習中]陣列與結構

靜態一維陣列 Dim 陣列名(下標) [As 型別] 說明: (1)下標必須為常數,不可以為表示式或變數。 (2)下標下界最小為-32768,最大上界為32767。 (3)省略下界,其預設值為為0,一維陣列的大小為:上界-下界+1。 靜態多維陣列 Dim 陣列名(下標1[,下

mongodb學習記錄聚合

group這個一直是迷迷糊糊的,上網找了好多例子,慢慢分析,慢慢消化。 下面兩個例子都是mongodb權威指南一本書上給的。 下面使用一個例子來消化group,先準備資料: db.blog.insert({title:"J2EE實戰",author:"li",day:"2012-12-12",tags:["

OpenGL系列教程OpenGL 變換

概述 在OpenGL渲染管線中幾何資料(頂點位置和法向量)在光柵化處理之前會先經過頂點操作和圖元裝配。 OpenGL 頂點變換 物體座標系(Object Coordinates) 這是物體的區域性座標系,並且表示物體未經過任何變換前的初始位置和朝向。為了變換物體,使

android學習筆記四大元件BroadcastReceiver

1.定義廣播接收者 定義一個類繼承BroadcastReceiver,並重寫onReceive()方法。 @Override public class SMSBroadCastReceiver