鶴壁做網(wǎng)站的公司360搜索引擎地址
STM32-01-認(rèn)識單片機
STM32-02-基礎(chǔ)知識
STM32-03-HAL庫
STM32-04-時鐘樹
STM32-05-SYSTEM文件夾
STM32-06-GPIO
STM32-07-外部中斷
STM32-08-串口
STM32-09-IWDG和WWDG
文章目錄
- 一、STM32 基礎(chǔ)定時器
- 1. 基本定時器簡介
- 2. 基本定時器框圖
- 3. 基本定時器相關(guān)寄存器
- 4. 定時器溢出時間計算
- 5. 基本定時器中斷配置步驟
- 6. 代碼實現(xiàn)
- 二、STM32通用定時器
- 1. 通用定時器簡介
- 2. 通用定時器框圖
- 1. 時鐘源
- 1. 內(nèi)部時鐘(`CK_INT`)
- 2. 外部時鐘模式1(TI1, TI2)
- 3. 外部時鐘模式2(ETR)
- 4. 內(nèi)部觸發(fā)輸入(ITRx)
- 2. 控制器
- 3. 時基單元
- 4. 輸入捕獲
- 5. 捕獲/比較(公共)
- 6. 輸出比較
- 3. 通用定時器相關(guān)寄存器
- 三、 通用定時器輸出PWM波
- 1. 通用定時器PWM輸出實驗配置步驟
- 2. 代碼實現(xiàn)
- 四、通用定時器輸入捕獲實驗
- 1. 輸入捕獲測量脈沖寬度
- 2. 輸入捕獲實驗相關(guān)寄存器
- 3. 通用定時器輸入捕獲配置步驟
- 4. 代碼實現(xiàn)
- 五、通用定時器脈沖計數(shù)實驗
- 1. 脈沖計數(shù)框圖
- 2. 相關(guān)寄存器
- 3. 通用定時器脈沖計數(shù)配置步驟
- 4. 代碼實現(xiàn)
- 六、高級定時器輸出指定個數(shù)PWM實驗
- 1. 高級定時器框圖
- 2. 重復(fù)計數(shù)器特性
- 3. 相關(guān)寄存器
- 4. 高級定時器輸出指定個數(shù)PWM實驗配置步驟
- 5. 代碼實現(xiàn)
- 七、高級定時器輸出比較模式實驗
- 1. 輸出比較模式功能
- 2. 相關(guān)寄存器
- 3. 高級定時器輸出比較模式實驗配置步驟
- 4. 代碼實現(xiàn)
- 八、高級定時器互補輸出帶死區(qū)控制實驗
- 1. 互補死區(qū)的理解
- 2. 相關(guān)寄存器
- 3. 高級定時器互補輸出帶死區(qū)控制實驗配置步驟
- 4. 代碼實現(xiàn)
- 九、高級定時器PWM輸入模式實驗
- 1. PWM輸入工作原理
- 2. 輸入模式時序圖
- 3. 相關(guān)寄存器
- 4. 高級定時器PWM輸入模式實驗配置步驟
- 4. 代碼實現(xiàn)
一、STM32 基礎(chǔ)定時器
STM32定時器分類:
STM32定時器特性表:
主要功能:
定時器類型 | 主要功能 |
---|---|
基本定時器 | 沒有輸入輸出通道,常用作時基,即定時功能 |
通用定時器 | 具有多路獨立通道,可用于輸入捕獲/輸出比較,也可用作時基 |
高級定時器 | 除具備通用定時器所有功能外,還具備帶死區(qū)控制的互補信號輸出、剎車輸入等功能(可用于電機控制、數(shù)字電源設(shè)計等) |
1. 基本定時器簡介
-
STM32F103有兩個基本定時器
TIM6
和TIM7
,它們的功能完全相同,資源是完全獨立的,可以同時使用。 -
主要特性:
- 16位自動重載遞增計數(shù)器;
- 16位可編程預(yù)分頻器,預(yù)分頻系數(shù)
1~65536
,用于對計數(shù)器時鐘頻率進行分頻; - 觸發(fā)DAC的同步電路;
- 生成中斷 和DMA請求。
-
定時原理:
2. 基本定時器框圖
-
影子寄存器: 實際起作用的寄存器,用戶不可直接訪問。舉個例子:我們可以把預(yù)分頻系數(shù)寫入預(yù)分頻器寄存器(
TIMx_PSC
),但是預(yù)分頻器寄存器只是起到緩存數(shù)據(jù)的作用,只有等到更新事件發(fā)生時,預(yù)分頻器寄存器的值才會被自動寫入其影子寄存器中,這時才真正起作用。 -
自動重載寄存器:自動重載寄存器及其影子寄存器的作用在于自動重載寄存器是否具有緩沖作用還受到
ARPE
位的控制。- 當(dāng)該位置0時,ARR寄存器不進行緩沖,寫入新ARR值會立即傳送到ARR影子寄存器從而直接生效;
- 當(dāng)該位置1時,ARR寄存器進行緩沖,寫入新ARR值時不會立即被寫入ARR影子寄存器,而是要等到更新事件發(fā)生才會被寫入ARR影子寄存器,這時才生效。預(yù)分頻器寄存器則沒有這樣相關(guān)的控制位,這就是它們不同點。
-
更新事件的產(chǎn)生:
- 軟件產(chǎn)生,將
TIMx_EGR
寄存器的位UG
置 1,產(chǎn)生更新事件后,硬件會自動將UG
位清零。 - 硬件產(chǎn)生,基本定時器的計數(shù)器(
CNT
)是一個遞增的計數(shù)器,當(dāng)寄存器(TIMx_CR1
)的CEN
位置 1,即使能定時器,每來一個CK_CNT脈沖,TIMx_CNT
的值就會遞增加1。當(dāng)TIMx_CNT
值與TIMx_ARR
的設(shè)定值相等時,TIMx_CNT
的值就會被自動清零并且會生成更新事件(如果開啟相應(yīng)的功能,就會產(chǎn)生DMA請求、產(chǎn)生中斷信號或者觸發(fā)DAC同步電路),然后下一個 CK_CNT脈沖到來,TIMx_CNT
的值就會遞增加1,如此循環(huán)。在此過程中,TIMx_CNT
等于TIMx_ARR
時,我們稱之為定時器溢出,因為是遞增計數(shù),故而又稱為定時器上溢。定時器溢出就伴隨著更新事件的發(fā)生。
- 軟件產(chǎn)生,將
-
計數(shù)模式與溢出條件:
-
遞增計數(shù)模式實例說明:
-
遞減計數(shù)模式實例說明:
-
中心對齊計數(shù)模式實例說明:
-
3. 基本定時器相關(guān)寄存器
-
控制寄存器 1(
TIMx_CR1
)
-
DMA/中斷使能寄存器(
TIMx_DIER
)
-
狀態(tài)寄存器(
TIMx_SR
)
-
計數(shù)器(
TIMx_CNT
)
-
預(yù)分頻器(
TIMx_PSC
)
-
自動重裝載寄存器(
TIMx_ARR
)
4. 定時器溢出時間計算
5. 基本定時器中斷配置步驟
-
配置定時器基礎(chǔ)工作參數(shù)
HAL_TIM_Base_Init()
-
定時器基礎(chǔ)MSP初始化
HAL_TIM_Base_MspInit()
-
使能更新中斷并啟動計數(shù)器
HAL_TIM_Base_Start_IT()
-
設(shè)置優(yōu)先級,使能中斷
HAL_NVIC_SetPriority() HAL_NVIC_EnableIRQ()
-
編寫中斷服務(wù)函數(shù)
TIMx_IRQHandler() HAL_TIM_IRQHandler()
-
編寫定時器更新中斷回調(diào)函數(shù)
HAL_TIM_PeriodElapsedCallback()
-
程序流程
6. 代碼實現(xiàn)
-
功能:使用定時器中斷實現(xiàn)LED燈閃爍.
-
定時器中斷初始化
void btim_timx_int_init(uint16_t psc, uint16_t per) {g_timx_handle.Instance = TIM6;g_timx_handle.Init.Prescaler = psc;g_timx_handle.Init.Period = per;HAL_TIM_Base_Init(&g_timx_handle);HAL_TIM_Base_Start_IT(&g_timx_handle);}
-
定時器基礎(chǔ)MSP初始化函數(shù)
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim) {if (htim->Instance == TIM6){__HAL_RCC_TIM6_CLK_ENABLE();HAL_NVIC_SetPriority(TIM6_IRQn, 1, 3);HAL_NVIC_EnableIRQ(TIM6_IRQn);} }
-
定時器6中斷服務(wù)函數(shù)
void TIM6_IRQHandler() {HAL_TIM_IRQHandler(&g_timx_handle); }
-
定時器溢出中斷回調(diào)函數(shù)
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {if(htim->Instance == TIM6){LED0_TOGGLE();} }
-
主函數(shù)
#include "./SYSTEM/sys/sys.h" #include "./SYSTEM/usart/usart.h" #include "./SYSTEM/delay/delay.h" #include "./BSP/LED/led.h" #include "./BSP/KEY/key.h" #include "./BSP/BEEP/beep.h" #include "./BSP/EXTI/exti.h" #include "./BSP/WDG/wdg.h" #include "./BSP/TIMER/btim.h"int main(void) {HAL_Init(); /* 初始化HAL庫 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 設(shè)置時鐘, 72Mhz */delay_init(72); /* 延時初始化 */usart_init(115200); /* 串口初始化為115200 */led_init(); /* 初始化LED */btim_timx_int_init(7199, 4999);while(1){} }
二、STM32通用定時器
1. 通用定時器簡介
- 通用定時器是一個通過可編程預(yù)分頻器驅(qū)動的16位自動裝載計數(shù)器構(gòu)成。
- 它適用于多種場合,包括測量輸入信號的脈沖寬度(輸入捕獲)或者產(chǎn)生輸出波形(輸出比較和PWM)。
- 使用定時器預(yù)分頻器和RCC時鐘控制器預(yù)分頻器,脈沖長度和波形周期可以在幾個微秒到幾個毫秒間調(diào)整。
- 每個定時器都是完全獨立的,沒有互相共享任何資源,并且可以一起同步操作。
-
主要特性
-
16位遞增、遞減、中心對齊計數(shù)器(計數(shù)值:0~65535)
-
16位預(yù)分頻器(分頻系數(shù):1~65536)
-
4個獨立通道:輸入捕獲,輸出比較,PWM生成,單脈沖模式輸出
-
使用外部信號控制定時器且可實現(xiàn)多個定時器互連的同步電路
-
支持針對定位的增量編碼器和霍爾傳感器電路
-
觸發(fā)輸入作為外部時鐘或者按周期的電流管理
-
2. 通用定時器框圖
1. 時鐘源
計數(shù)器時鐘選擇類型 | 設(shè)置方法 |
---|---|
內(nèi)部時鐘(CK_INT) | 設(shè)置TIMx_SMCR的SMS=000 |
外部時鐘模式1:外部輸入引腳(TIx) | 設(shè)置TIMx_SMCR的SMS=111 |
外部時鐘模式2:外部觸發(fā)輸入(ETR) | 設(shè)置TIMx_SMCR的ECE=1 |
內(nèi)部觸發(fā)輸入(ITRx) |
1. 內(nèi)部時鐘(CK_INT
)
- 定時器TIM2~TIM7掛接在APB1總線上,這些定時器的內(nèi)部時鐘(CK_INT)實際上來自APB1總線提供的時鐘,然后經(jīng)過一個倍頻器之后,輸出的時鐘頻率為72MHz。
2. 外部時鐘模式1(TI1, TI2)
3. 外部時鐘模式2(ETR)
4. 內(nèi)部觸發(fā)輸入(ITRx)
2. 控制器
-
控制器包括:觸發(fā)控制器,從模式控制器,編碼器接口
-
觸發(fā)控制器:用來提供觸發(fā)信號給別的外設(shè)
-
從模式控制器:可以控制計數(shù)器復(fù)位、啟動、遞增/遞減、計數(shù)
-
編碼器接口:針對編碼器計數(shù)
-
3. 時基單元
4. 輸入捕獲
TIMx_CH1
~TIMx_CH4
表示定時器的4個通道,4個通道獨立工作。IO端口通過復(fù)用功能與這些通道相連。配置好IO端口的復(fù)用功能后,將需要測量的信號輸入到相應(yīng)的 IO端口,輸入捕獲部分可以對輸入的信號的上升沿,下降沿或者雙邊沿進行捕獲,常見的測量有:測量輸入信號的脈沖寬度、測量PWM輸入信號的頻率和占空比等。
5. 捕獲/比較(公共)
以通道1為例,對應(yīng)CCR1
寄存器,CC1G
位可以產(chǎn)生軟件捕獲事件,那么硬件捕獲事件如何產(chǎn)生的?以通道1輸入為例,CC1S[1:0]=01,即IC1映射到TI1上;CC1E位置1,使能輸入捕獲;比如不濾波、不分頻,ICF[3:0]=00,ICPS[1:0]=00;比如檢測上升沿,CC1P位置0:接著就是等待測量信號的上升沿到來。當(dāng)上升沿到來時,IC1PS信號就會觸發(fā)輸入捕獲事件發(fā)生,計數(shù)器的值就會被鎖存到捕獲/比較影子寄存器里。當(dāng)CCR1寄存器沒有被進行讀操作的時候,捕獲/比較影子寄存器里的值就會鎖存到CCR1寄存器中,那么程序員就可以讀取CCR1寄存器,得到計數(shù)器的計數(shù)值。檢測下降沿同理。
6. 輸出比較
首先程序員寫CCR1寄存器,即寫入比較值。這個比較值需要轉(zhuǎn)移到對應(yīng)的捕獲比較影子寄存器后才會真正生效。什么條件下才能轉(zhuǎn)移?compare transfer旁邊的與門,需要滿足三個條件:CCR1不在寫入操作期間、CC1S[1:0]=0配置為輸出、OC1PE位置 0(或者OC1PE位置1,并且需要發(fā)生更新事件,這個更新事件可以軟件產(chǎn)生或者硬件產(chǎn)生)。當(dāng)CCR1寄存器的值轉(zhuǎn)移到其影子寄存器后,新的值就會和計數(shù)器的值進行比較,它們的比較結(jié)果將會通過輸出比較影響定時器的輸出。
3. 通用定時器相關(guān)寄存器
-
控制寄存器1(
TIMx_CR1
)
-
從模式控制寄存器(
TIMx_SMCR
)
-
DMA/中斷使能寄存器(
TIMx_DIER
)
-
狀態(tài)寄存器(
TIMx_SR
)
-
計數(shù)寄存器(
TIMx_CNT
)
-
預(yù)分頻寄存器(
TIMx_PSC
)
-
自動重載寄存器(
TIMx_ARR
)
三、 通用定時器輸出PWM波
-
通用定時器輸出模式
PWM,即脈沖寬度調(diào)制,是利用微處理器的數(shù)字輸出對模擬電路進行控制的一種非常有效的技術(shù)。讓定時器產(chǎn)生PWM,在計數(shù)器頻率固定時,PWM頻率自動重載寄存器(TIMx_ARR)的值決定,其占空比由捕獲/比較寄存器(TIMx_CCRx)的值決定。
-
PWM模式
-
PWM控制寄存器
-
捕獲/比較模式寄存器1/2(
TIMx_CCMR1/2
)
-
捕獲/比較使能寄存器(
TIMx_CCER
)
-
捕獲/比較寄存器(
TIMx_CCR1/2/3/4
)
-
1. 通用定時器PWM輸出實驗配置步驟
-
配置定時器基礎(chǔ)工作參數(shù)
HAL_TIM_PWM_Init()
-
定時器PWM輸出MSP初始化
HAL_TIM_PWM_MspInit()
-
配置PWM模式/比較值等
HAL_TIM_PWM_ConfigChannel()
-
使能輸出并啟動計數(shù)器
HAL_TIM_PWM_Start()
-
修改比較值控制占空比(可選)
__HAL_TIM_SET_COMPARE()
-
使能通道預(yù)裝載(可選)
__HAL_TIM_ENABLE_OCxPRELOAD()
-
相關(guān)庫函數(shù)介紹
函數(shù) 主要寄存器 主要功能 HAL_TIM_PWM_Init() CR1、ARR、PSC 初始化定時器基礎(chǔ)參數(shù) HAL_TIM_PWM_MspInit() 無 存放NVIC、CLOCK、GPIO初始化代碼 HAL_TIM_PWM_ConfigChannel() CCMRx、CCRx、CCER 配置PWM模式、比較值、輸出極性等 HAL_TIM_PWM_Start() CCER、CR1 使能輸出比較并啟動計數(shù)器 __HAL_TIM_SET_COMPARE() CCRx 修改比較值 __HAL_TIM_ENABLE_OCxPRELOAD() CCER 使能通道預(yù)裝載
2. 代碼實現(xiàn)
-
功能:使用TM3通道2(由PB5復(fù)用)輸出PWM,PB5引腳連接了LED0,從而實現(xiàn)PWM輸出控制LED0亮度。
-
程序流程:
-
通用定時器PWM輸出初始化函數(shù)
void gtim_timx_pwm_chy_init(uint16_t arr, uint16_t psc) {TIM_OC_InitTypeDef timx_oc_pwm_chy;g_timx_pwm_chy_handle.Instance = TIM3; //定時器選擇g_timx_pwm_chy_handle.Init.Prescaler = psc; //定時器分頻g_timx_pwm_chy_handle.Init.Period = arr;g_timx_pwm_chy_handle.Init.CounterMode = TIM_COUNTERMODE_UP; //定時器計數(shù)模式HAL_TIM_PWM_Init(&g_timx_pwm_chy_handle); //初始化PWMtimx_oc_pwm_chy.OCMode = TIM_OCMODE_PWM1; //模式選擇PWM1timx_oc_pwm_chy.Pulse = arr/2; //占空比為50%timx_oc_pwm_chy.OCNPolarity = TIM_OCNPOLARITY_LOW; //輸出比較極性為低HAL_TIM_PWM_ConfigChannel(&g_timx_pwm_chy_handle, &timx_oc_pwm_chy, TIM_CHANNEL_2); //配置定時器3通道2HAL_TIM_PWM_Start(&g_timx_pwm_chy_handle, TIM_CHANNEL_2); //開啟PWM通道 }
-
定時器輸出PWM MSP初始化函數(shù)
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim) {if(htim->Instance == TIM3){GPIO_InitTypeDef gpio_init_struct;__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_TIM3_CLK_ENABLE();gpio_init_struct.Pin = GPIO_PIN_5;gpio_init_struct.Mode = GPIO_MODE_AF_PP;gpio_init_struct.Pull = GPIO_PULLUP;gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOB, &gpio_init_struct);__HAL_RCC_AFIO_CLK_ENABLE();__HAL_AFIO_REMAP_TIM3_PARTIAL(); //設(shè)置重映射,把TIM3通道2映射到PB5} }
-
主函數(shù)
int main(void) {uint16_t ledrpwmval = 0;uint8_t dir = 1;HAL_Init(); /* 初始化HAL庫 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 設(shè)置時鐘, 72Mhz */delay_init(72); /* 延時初始化 */usart_init(115200); /* 串口初始化為115200 */led_init(); /* 初始化LED */gtim_timx_pwm_chy_init(500 - 1, 72 - 1);while(1){delay_ms(10);if(dir) ledrpwmval++;else ledrpwmval--;if(ledrpwmval > 300) dir = 0;if(ledrpwmval == 0) dir = 1;__HAL_TIM_SET_COMPARE(&g_timx_pwm_chy_handle, TIM_CHANNEL_2, ledrpwmval);} }
四、通用定時器輸入捕獲實驗
1. 輸入捕獲測量脈沖寬度
測量方法:假定工作在遞增計數(shù)模式,首先設(shè)置通道x為上升沿捕獲,這樣在t1時刻上升沿到來時,就會發(fā)生捕獲事件(打開捕獲中斷,捕獲事件發(fā)生時會觸發(fā)捕獲中斷)。在捕獲中斷里將計數(shù)器值清零,并設(shè)置通道x為下降沿捕獲,這樣t2時刻下降沿到來時,就會發(fā)生捕獲事件和捕獲中斷。捕獲事件發(fā)生時,計數(shù)器的值會被鎖存到捕獲/比較寄存器中。在捕獲中斷內(nèi),讀取捕獲/比較寄存器就可以獲取高電平脈沖時間,計數(shù)器計數(shù)的個數(shù),從而可以算出高電平脈沖的時間(假定計數(shù)器沒有溢出)。
但是在t1到t2時間段,定時器可能會產(chǎn)生N次溢出,需要對定時器溢出做相應(yīng)的處理,防止高電平太長,導(dǎo)致測量出錯。在t1到t2時間內(nèi),假定定時器溢出N次,那么高電平時間內(nèi),計數(shù)器計數(shù)的個數(shù)計算方法為:N * (ARR + 1) + CCRx2
,CCRx2表示t2時間點,捕獲/比較寄存器的值。經(jīng)過計算得到高電平脈寬時間內(nèi)計數(shù)器計數(shù)個數(shù)后,用這個個數(shù)乘以計數(shù)器的計數(shù)周期,就可以得到高電平持續(xù)的時間。就是輸入捕獲測量高電平脈寬時間的整個過程。
STM32F103的定時器除了TM6和TM7,其他定時器都有輸入捕獲功能。輸入捕獲,簡單的說就是通過檢測TIMx_CHy
上的邊沿信號,在邊沿信號發(fā)生跳變(比如上升沿/下降沿)時,會發(fā)生捕獲事件,將當(dāng)前定時器的值(TIMx_CNT
)鎖存到對應(yīng)通道的捕獲/比較寄存器(TIMx_CCRy
)里,完成一次捕獲。同時還可以配置捕獲事件發(fā)生時是否觸發(fā)捕獲中斷/DMA。另外還要考慮測量的過程中是否可能發(fā)生定時器溢出,如果可能溢出,還要做溢出處理。
2. 輸入捕獲實驗相關(guān)寄存器
-
捕獲/比較模式寄存器1/2(
TIMx_CCMR1/2
)
-
捕獲/比較使能寄存器(
TIMx_CCER
)
3. 通用定時器輸入捕獲配置步驟
-
配置定時器基礎(chǔ)工作參數(shù)
HAL_TIM_IC_Init()
-
定時器輸入捕獲MSP初始化
HAL_TIM_IC_MspInit()
-
配置輸入通道映射、捕獲邊沿等
HAL_TIM_IC_ConfigChannel()
-
設(shè)置優(yōu)先級,使能中斷
HAL_NVIC_SetPriority() HAL_NVIC_EnableIRQ()
-
使能定時器更新中斷
__HAL_TIM_ENABLE_IT()
-
使能捕獲、捕獲中斷及計數(shù)器
HAL_TIM_IC_Start_IT()
-
編寫中斷服務(wù)函數(shù)
TIMx_IRQHandler() HAL_TIM_IRQHandler()
-
編寫更新中斷和捕獲回調(diào)函數(shù)
HAL_TIM_PeriodElapsedCallback() HAL_TIM_IC_CaptureCallback()
-
相關(guān)函數(shù)的功能
函數(shù) 主要寄存器 主要功能 HAL_TIM_IC_Init() CR1、ARR、PSC 初始化定時器基礎(chǔ)參數(shù) HAL_TIM_IC_MspInit() 無 存放NVIC、CLOCK、GPIO初始化代碼 HAL_TIM_IC_ConfigChannel() CCMRx、CCER 配置通道映射、捕獲邊沿、分頻、濾波等 __HAL_TIM_ENABLE_IT() DIER 使能更新中斷等 HAL_TIM_IC_Start_IT() CCER、DIER、CR1 使能輸入捕獲、捕獲中斷并啟動計數(shù)器 HAL_TIM_IRQHandler() SR 定時器中斷處理公用函數(shù),處理各種中斷 HAL_TIM_PeriodElapsedCallback() 無 定時器更新中斷回調(diào)函數(shù),由用戶重定義 HAL_TIM_IC_CaptureCallback() 無 定時器輸入捕獲回調(diào)函數(shù),由用戶重定義
4. 代碼實現(xiàn)
-
功能
1、使用TM5CH1來做輸入捕獲,捕獲PA0上的高電平脈寬,并將脈寬時間通過串口打印出來,然后通過按WKUP按鍵,模擬輸入高電平,例程中能測試的最長高電平脈寬時間為: 4194303us.
2、LED0閃爍指示程序運行。
-
通用定時器TIM5通道1輸入捕獲初始化函數(shù)
void gtim_timx_cap_chy_init(uint16_t arr, uint16_t psc) {TIM_IC_InitTypeDef timx_ic_cap_chy = {0};//初始化定時器參數(shù) g_timx_cap_chy_handle.Instance = TIM5; //定時器5的基地址g_timx_cap_chy_handle.Init.Prescaler = psc; //定時器的分頻系數(shù)g_timx_cap_chy_handle.Init.CounterMode = TIM_COUNTERMODE_UP; //遞增計數(shù)模式g_timx_cap_chy_handle.Init.Period = arr; //自動重裝載值HAL_TIM_IC_Init(&g_timx_cap_chy_handle); //初始化//配置通道映射、捕獲邊沿、分頻、濾波等timx_ic_cap_chy.ICPolarity = TIM_ICPOLARITY_RISING; //配置捕獲極性為上升沿timx_ic_cap_chy.ICSelection = TIM_ICSELECTION_DIRECTTI; //映射到通道1timx_ic_cap_chy.ICPrescaler = TIM_ICPSC_DIV1; //不進行分頻timx_ic_cap_chy.ICFilter = 0; //不進行濾波HAL_TIM_IC_ConfigChannel(&g_timx_cap_chy_handle, &timx_ic_cap_chy, TIM_CHANNEL_1); //初始化__HAL_TIM_ENABLE_IT(&g_timx_cap_chy_handle, TIM_IT_UPDATE); //使能更新中斷HAL_TIM_IC_Start_IT(&g_timx_cap_chy_handle, TIM_CHANNEL_1); //開始捕獲TIM5的通道1 }
-
通用定時器輸入捕獲初始化函數(shù)
void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim) {if(htim->Instance == TIM5) //判斷定時器是否正確{GPIO_InitTypeDef gpio_init_struct; //GPIO配置結(jié)構(gòu)體__HAL_RCC_TIM5_CLK_ENABLE(); //使能定時器時鐘__HAL_RCC_GPIOA_CLK_ENABLE(); //使能GPIOA時鐘gpio_init_struct.Pin = GPIO_PIN_0; //配置引腳號gpio_init_struct.Mode = GPIO_MODE_AF_PP; //配置復(fù)用推挽輸出gpio_init_struct.Pull = GPIO_PULLDOWN; //配置下拉模式gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; //配置輸出速度HAL_GPIO_Init(GPIOA, &gpio_init_struct); //初始化HAL_NVIC_SetPriority(TIM5_IRQn, 1, 3); //設(shè)置中斷優(yōu)先級HAL_NVIC_EnableIRQ(TIM5_IRQn); //使能TIM5中斷} }
-
定時器TIM5中斷服務(wù)函數(shù)
//定時器5中斷服務(wù)函數(shù) void TIM5_IRQHandler(void) {//HAL庫中斷公共處理函數(shù)HAL_TIM_IRQHandler(&g_timx_cap_chy_handle); }
-
定時器輸入捕獲中斷處理回調(diào)函數(shù)
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) {if(htim->Instance == TIM5){if((g_timxchy_cap_sta & 0x80) == 0) //未成功捕獲{if(g_timxchy_cap_sta & 0x40) //捕獲下降沿{g_timxchy_cap_sta |= 0x80; //位7置1 代表成功捕獲g_timxchy_cap_val = HAL_TIM_ReadCapturedValue(&g_timx_cap_chy_handle, TIM_CHANNEL_1); //保存當(dāng)前計數(shù)器的值TIM_RESET_CAPTUREPOLARITY(&g_timx_cap_chy_handle, TIM_CHANNEL_1); //失能通道TIM_SET_CAPTUREPOLARITY(&g_timx_cap_chy_handle, TIM_CHANNEL_1, TIM_ICPOLARITY_RISING); //使能通道1為上降沿捕獲}else //捕獲上升沿{g_timxchy_cap_sta = 0;g_timxchy_cap_val = 0;g_timxchy_cap_sta |= 0x40;__HAL_TIM_DISABLE(&g_timx_cap_chy_handle); //失能定時器5__HAL_TIM_SET_COUNTER(&g_timx_cap_chy_handle, 0); //計數(shù)器的值清0TIM_RESET_CAPTUREPOLARITY(&g_timx_cap_chy_handle, TIM_CHANNEL_1); //失能通道TIM_SET_CAPTUREPOLARITY(&g_timx_cap_chy_handle, TIM_CHANNEL_1, TIM_ICPOLARITY_FALLING); //使能通道1為下降沿捕獲__HAL_TIM_ENABLE(&g_timx_cap_chy_handle); //使能定時器5}}} }
-
定時器更新中斷回調(diào)函數(shù)
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {if(htim->Instance == TIM5){if((g_timxchy_cap_sta & 0x80) == 0) //未成功捕獲{if(g_timxchy_cap_sta & 0x40) //已經(jīng)成功捕獲{if((g_timxchy_cap_sta & 0X3F) == 0x3f) //高電平時間過長{TIM_RESET_CAPTUREPOLARITY(&g_timx_cap_chy_handle, TIM_CHANNEL_1); //失能通道TIM_SET_CAPTUREPOLARITY(&g_timx_cap_chy_handle, TIM_CHANNEL_1, TIM_ICPOLARITY_FALLING); //使能通道1為下降沿捕獲g_timxchy_cap_sta |= 0x80; //標(biāo)記成功捕獲一次g_timxchy_cap_val = 0xFFFF;}else //累積定時器溢出次數(shù){g_timxchy_cap_sta++;}}}}if(htim->Instance == TIM6){LED0_TOGGLE();}if(htim->Instance == TIM7){LED1_TOGGLE();} }
-
主函數(shù)
int main(void) {uint32_t temp = 0;uint8_t t= 0;HAL_Init(); /* 初始化HAL庫 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 設(shè)置時鐘, 72Mhz */delay_init(72); /* 延時初始化 */usart_init(115200); /* 串口初始化為115200 */led_init(); /* 初始化LED */gtim_timx_cap_chy_init(0xFFFF, 72 - 1); //1MHzwhile(1){if(g_timxchy_cap_sta & 0x80){temp = g_timxchy_cap_sta & 0x3F;temp = temp * 65536; //溢出時間總和temp += g_timxchy_cap_val; //溢出的總時間printf("HIGH:%d us\r\n", temp);g_timxchy_cap_sta = 0; //開啟下一次捕獲}t++;if(t > 20){t = 0;LED0_TOGGLE();}delay_ms(10);} }
-
主程序運行流程
-
中斷程序運行流程
五、通用定時器脈沖計數(shù)實驗
1. 脈沖計數(shù)框圖
脈沖計數(shù)實驗使用的時鐘源是外部時鐘模式1,外部輸入引腳(TIx)作為定時器的時鐘源。實驗中使用WK_UP按鍵按下產(chǎn)生的高電平脈沖作為定時器的計數(shù)器時鐘,每按下一次按鍵產(chǎn)生一次高電平脈沖,計數(shù)器的值加一。
外部時鐘模式1的外部輸入引腳只能是通道1或者通道2對應(yīng)的IO,通道3或者通道4不可以。以通道1輸入為例,外部時鐘源信號通過通道1輸入后,TI1分別要經(jīng)過濾波器、邊沿檢測器后,來到TI1FP1,被觸發(fā)輸入選擇器選擇為觸發(fā)源,接著來到從模式控制器。從模式選擇為外部時鐘模式1,這時候外部時鐘源信號就會到達時基單元的預(yù)分頻器,后面就是經(jīng)過分頻后就作為計數(shù)器的計數(shù)時鐘。
2. 相關(guān)寄存器
-
捕獲/比較模式寄存器1/2(
TIMx_CCMR1/2
)與輸入捕獲配置相同
-
捕獲/比較使能寄存器(
TIMx_CCER
)與輸入捕獲配置相同
-
從模式控制寄存器(
TIMx_SMCR
)
3. 通用定時器脈沖計數(shù)配置步驟
-
配置定時器基礎(chǔ)工作參數(shù)
HAL_TIM_IC_Init()
-
定時器輸入捕獲MSP初始化
HAL_TIM_IC_MspInit()
-
配置定時器從模式等
HAL_TIM_SlaveConfigSynchro()
-
使能輸入捕獲并啟動計數(shù)器
HAL_TIM_IC_Start()
-
獲取計數(shù)器的值
__HAL_TIM_GET_COUNTER()
-
設(shè)置計數(shù)器的值
__HAL_TIM_SET_COUNTER()
-
相關(guān)庫函數(shù)
函數(shù) 主要寄存器 主要功能 HAL_TIM_IC_Init() CR1、ARR、PSC 初始化定時器基礎(chǔ)參數(shù) HAL_TIM_IC_MspInit() 無 存放NVIC、CLOCK、GPIO初始化代碼 HAL_TIM_SlaveConfigSynchro() SMCR、CCMRx、CCER 配置定時器從模式、觸發(fā)選擇、分頻、濾波等 HAL_TIM_IC_Start() CCER、CR1 使能輸入捕獲、啟動計數(shù)器 __HAL_TIM_GET_COUNTER() CNT 獲取計數(shù)器當(dāng)前值 __HAL_TIM_SET_COUNTER() CNT 設(shè)置計數(shù)器的值
4. 代碼實現(xiàn)
-
功能:
使用TM2CH1做輸入捕獲,我們將捕獲PA0上的高電平脈寬,并將脈寬進行計數(shù),通過串口打印出來。大家可以通過按WKUP按鍵,輸入高電平脈沖,通過按KEY0重設(shè)當(dāng)前計數(shù)。 LED0閃爍,提示程序運行。
-
通用定時器脈沖計數(shù)初始化函數(shù)
void gtim_timx_cnt_chy_init(uint16_t psc) {TIM_SlaveConfigTypeDef timx_slave_config = {0};g_timx_cnt_chy_handle.Instance = TIM2; //定時器選擇g_timx_cnt_chy_handle.Init.Prescaler = psc; //定時器分頻g_timx_cnt_chy_handle.Init.Period = 65535;g_timx_cnt_chy_handle.Init.CounterMode = TIM_COUNTERMODE_UP; //定時器計數(shù)模式HAL_TIM_IC_Init(&g_timx_cnt_chy_handle); //初始化PWMtimx_slave_config.SlaveMode = TIM_SLAVEMODE_EXTERNAL1;timx_slave_config.InputTrigger = TIM_TS_TI1F_ED;timx_slave_config.TriggerPolarity = TIM_TRIGGERPOLARITY_RISING;timx_slave_config.TriggerFilter = 0;HAL_TIM_SlaveConfigSynchro(&g_timx_cnt_chy_handle, &timx_slave_config);HAL_TIM_IC_Start(&g_timx_cnt_chy_handle, TIM_CHANNEL_1); }
-
主函數(shù)
int main(void) {uint16_t curcnt; //存儲當(dāng)前的計數(shù)值uint16_t oldcnt; //存儲舊的計數(shù)值uint8_t key; //按鍵的鍵值uint8_t t; //延時時間HAL_Init(); /* 初始化HAL庫 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 設(shè)置時鐘, 72Mhz */delay_init(72); /* 延時初始化 */usart_init(115200); /* 串口初始化為115200 */led_init(); /* 初始化LED */key_init();gtim_timx_cnt_chy_init(0); while(1){key = key_scan(0);if(key == 1){__HAL_TIM_SET_COUNTER(&g_timx_cnt_chy_handle, 0);}curcnt = __HAL_TIM_GET_COUNTER(&g_timx_cnt_chy_handle);if(oldcnt != curcnt){oldcnt = curcnt;printf("CNT:%d\r\n", oldcnt);}t++;if(t > 20){t = 0;LED0_TOGGLE();}delay_ms(10);} }
六、高級定時器輸出指定個數(shù)PWM實驗
1. 高級定時器框圖
-
重復(fù)計數(shù)器
在基本定時器和通用定時器中,定時器發(fā)生上溢或者下溢時,會直接生成更新事件。但有重復(fù)計數(shù)器的定時器并不完全這樣,在定時器每次發(fā)生上溢或下溢時,重復(fù)計數(shù)器的值會減一,當(dāng)重復(fù)計數(shù)器的值為0時,再發(fā)生一次上溢或者下溢才會生成定時器更新事件。如果我們設(shè)置重復(fù)計數(shù)器寄存器的
RCR
的值為N
,那么更新事件將在定時器發(fā)生N+1
次上溢或下溢時發(fā)生。 -
輸出比較
與通用定時器相比,高級定時器多了帶死區(qū)控制的互補輸出功能。通道1、2、3都有互補輸出通道,
DTG
是死區(qū)發(fā)生器,死區(qū)時間由DTG[7:0]
位來配置。如果不使用互補通道和死區(qū)時間控制,那么高級定時器TIM1和TIM8和通用定時器的輸出比較部分使用方法基本一樣,只是要注意MOE
位得置1定時器才能輸出。 -
斷路功能
斷路功能也稱剎車功能,一般用于控制電機的剎車。F1系列有一個斷路通道,斷路源可以是剎車輸入引腳(
TIMx_BKIN
),也可以是一個時鐘失敗事件。時鐘失敗事件由復(fù)位時鐘控制器中的時鐘安全系統(tǒng)產(chǎn)生。系統(tǒng)復(fù)位后,斷路功能默認(rèn)被禁止,MOE
位為低。
2. 重復(fù)計數(shù)器特性
-
計數(shù)器每次上溢或下溢都能使重復(fù)計數(shù)器減1,減到0時,再發(fā)生一次溢出就會產(chǎn)生更新事件。
-
如果設(shè)置RCR為N,更新事件將在N+1次溢出時發(fā)生。
3. 相關(guān)寄存器
-
控制寄存器1(
TIMx_CR1
)
-
捕獲/比較模式寄存器1/2(
TIMx_CCMR1/2
)
-
捕獲/比較使能寄存器(
TIMx_CCER
)
-
事件產(chǎn)生寄存器(
TIMx_EGR
)
-
重復(fù)計數(shù)器寄存器(
TIMx_RCR
)
-
捕獲/比較寄存器1/2/3/4(
TIMx_CCR1/2/3/4
)
-
斷路和死區(qū)寄存器(
TIMx_BDTR
)
4. 高級定時器輸出指定個數(shù)PWM實驗配置步驟
-
配置定時器基礎(chǔ)工作參數(shù)
HAL_TIM_PWM_Init()
-
定時器PWM輸出MSP初始化
HAL_TIM_PWM_MspInit()
-
配置PWM模式/比較值等
HAL_TIM_PWM_ConfigChannel()
-
設(shè)置優(yōu)先級,使能中斷
HAL_NVIC_SetPriority() HAL_NVIC_EnableIRQ()
-
使能定時器更新中斷
__HAL_TIM_ENABLE_IT()
-
使能輸出、主輸出、計數(shù)器
HAL_TIM_PWM_Start()
-
編寫中斷服務(wù)函數(shù)
TIMx_IRQHandler() HAL_TIM_IRQHandler()
-
編寫更新中斷回調(diào)函數(shù)
HAL_TIM_PeriodElapsedCallback()
-
具體函數(shù)功能
函數(shù) 主要寄存器 主要功能 HAL_TIM_PWM_Init() CR1、ARR、PSC 初始化定時器基礎(chǔ)參數(shù) HAL_TIM_PWM_MspInit() 無 存放NVIC、CLOCK、GPIO初始化代碼 HAL_TIM_PWM_ConfigChannel() CCMRx、CCRx、CCER 配置PWM模式、比較值、輸出極性等 __HAL_TIM_ENABLE_IT() CCER 使能更新中斷等 HAL_TIM_PWM_Start() CCER、CR1 使能輸出、主輸出、啟動計數(shù)器 HAL_TIM_IRQHandler() SR 定時器中斷處理公用函數(shù),處理各種中斷 HAL_TIM_PeriodElapsedCallback() 無 定時器更新中斷回調(diào)函數(shù),由用戶重定義 HAL_TIM_GenerateEvent() EGR 通過軟件產(chǎn)生事件 __HAL_TIM_ENABLE() CR1 啟動計數(shù)器
5. 代碼實現(xiàn)
-
功能:
通過TIM8CH1(由PC6復(fù)用)輸出PWM,然后為了指示PWM的輸出情況,我們用杜邦線將PC6和PE5引腳的排針連接起來,從而實現(xiàn)PWM輸出控制LED1(硬件已連接在PPE5引腳上)的亮滅。注意的點是:PE5要設(shè)置成浮空輸入,避免引腳沖突,我們在main函數(shù)中設(shè)置好了,請看源碼。上電默認(rèn)輸出5個PWM波,連接好杜邦線后可以看見LED1亮滅五次。之后按一下按鍵KEYO,就會輸出5個PWM波控制LED1亮滅五次。LED0閃爍提示系統(tǒng)正在運行。
-
高級定時器輸出指定個數(shù)PWM初始化
void atim_timx_npwm_chy_init(uint16_t arr, uint16_t psc) {TIM_OC_InitTypeDef timx_oc_npwm_chy = {0};g_timx_npwm_chy_handle.Instance = TIM8;g_timx_npwm_chy_handle.Init.Prescaler = psc;g_timx_npwm_chy_handle.Init.CounterMode = TIM_COUNTERMODE_UP; //向上計數(shù)模式g_timx_npwm_chy_handle.Init.Period = arr;g_timx_npwm_chy_handle.Init.RepetitionCounter = 0; //重復(fù)計數(shù)器初始值g_timx_npwm_chy_handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; /*使能TIMx_ARR進行緩沖 */HAL_TIM_PWM_Init(&g_timx_npwm_chy_handle);timx_oc_npwm_chy.OCMode = TIM_OCMODE_PWM1; //使用PWM1工作模式timx_oc_npwm_chy.Pulse = arr / 2; //占空比設(shè)置為50%timx_oc_npwm_chy.OCPolarity = TIM_OCPOLARITY_HIGH; //高電平有效HAL_TIM_PWM_ConfigChannel(&g_timx_npwm_chy_handle, &timx_oc_npwm_chy, TIM_CHANNEL_1); //進行初始化__HAL_TIM_ENABLE_IT(&g_timx_npwm_chy_handle, TIM_IT_UPDATE); //允許更新中斷HAL_TIM_PWM_Start(&g_timx_npwm_chy_handle, TIM_CHANNEL_1); //開啟對應(yīng)的PWM通道 }
-
高級定時器輸出指定個數(shù)PWM MSP回調(diào)函數(shù)
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim) {if(htim->Instance == TIM8){GPIO_InitTypeDef gpio_init_struct;__HAL_RCC_GPIOC_CLK_ENABLE();__HAL_RCC_TIM8_CLK_ENABLE();gpio_init_struct.Pin = GPIO_PIN_6;gpio_init_struct.Pull = GPIO_PULLUP;gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;gpio_init_struct.Mode = GPIO_MODE_AF_PP;HAL_GPIO_Init(GPIOC, &gpio_init_struct);HAL_NVIC_SetPriority(TIM8_UP_IRQn, 1, 3);HAL_NVIC_EnableIRQ(TIM8_UP_IRQn);} }
-
高級定時器設(shè)置PWM個數(shù)函數(shù)
void atim_timx_npwm_chy_set(uint8_t npwm) {if(npwm == 0) return;g_npwm_remain = npwm; //保存脈沖個數(shù)HAL_TIM_GenerateEvent(&g_timx_npwm_chy_handle, TIM_EVENTSOURCE_UPDATE); //產(chǎn)生一次軟件更新事件,在中斷里面處理脈沖輸出__HAL_TIM_ENABLE(&g_timx_npwm_chy_handle); //使能定時器TIM8 }
-
定時器8中斷服務(wù)函數(shù)
void TIM8_UP_IRQHandler(void) {HAL_TIM_IRQHandler(&g_timx_npwm_chy_handle); }
-
定時器更新中斷回調(diào)函數(shù)
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {if(htim->Instance == TIM8){if(g_npwm_remain){TIM8->RCR = g_npwm_remain - 1;HAL_TIM_GenerateEvent(&g_timx_npwm_chy_handle, TIM_EVENTSOURCE_UPDATE);__HAL_TIM_ENABLE(&g_timx_npwm_chy_handle);g_npwm_remain = 0;}else{TIM8->CR1 &= ~(1 << 0);}} }
-
主函數(shù)
void LED_init(void) {GPIO_InitTypeDef gpio_init_struct;gpio_init_struct.Pin = GPIO_PIN_5;gpio_init_struct.Mode = GPIO_MODE_INPUT; //設(shè)置為輸入,防止沖突(PC6)gpio_init_struct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOE, &gpio_init_struct); }int main(void) {uint8_t t = 0;uint8_t key = 0;HAL_Init(); /* 初始化HAL庫 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 設(shè)置時鐘, 72Mhz */delay_init(72); /* 延時初始化 */ // usart_init(115200); /* 串口初始化為115200 */led_init(); /* 初始化LED */key_init();LED_init(); //需要重新配置PE5為輸入模式防止沖突atim_timx_npwm_chy_init(5000 -1, 7200 - 1);atim_timx_npwm_chy_set(5); while(1){key = key_scan(0);if(key == 4){atim_timx_npwm_chy_set(6);}t++;if(t > 50){t = 0;LED0_TOGGLE();}delay_ms(10);} }
七、高級定時器輸出比較模式實驗
1. 輸出比較模式功能
輸出比較模式下翻轉(zhuǎn)功能作用是:當(dāng)計數(shù)器的值等于捕獲/比較寄存器影子寄存器的值時, OC1REF
發(fā)生翻轉(zhuǎn),進而控制通道輸出(OCx
)翻轉(zhuǎn)。通過翻轉(zhuǎn)功能實現(xiàn)輸出PWM的具體原理如下:PWM頻率由自動重載寄存器(TIMx_ARR
)的值決定,在這個過程中,只要自動重載寄存器的值不變,那么PWM占空比就固定為50%??梢酝ㄟ^捕獲/比較寄存器(TIMx_CCRx
)的值改變PWM的相位。
2. 相關(guān)寄存器
-
控制寄存器1(
TIMx_CR1
)
-
捕獲/比較模式寄存器1/2(
TIMx_CCMR1/2
)
-
捕獲/比較使能寄存器(
TIMx_CCER
)
-
捕獲/比較寄存器1/2/3/4(
TIMx_CCR1/2/3/4
)
-
TIM1/TIM8斷路和死區(qū)寄存器(
TIMx_BDTR
)
3. 高級定時器輸出比較模式實驗配置步驟
-
配置定時器基礎(chǔ)工作參數(shù)
HAL_TIM_OC_Init()
-
定時器輸出比較MSP初始化
HAL_TIM_OC_MspInit()
-
配置輸出比較模式等
HAL_TIM_OC_ConfigChannel()
-
使能通道預(yù)裝載
__HAL_TIM_ENABLE_OCxPRELOAD()
-
使能輸出、主輸出、計數(shù)器
HAL_TIM_OC_Start()
-
修改捕獲/比較寄存器的值
__HAL_TIM_SET_COMPARE()
-
具體函數(shù)功能
函數(shù) 主要寄存器 主要功能 HAL_TIM_OC_Init() CR1、ARR、PSC 初始化定時器基礎(chǔ)參數(shù) HAL_TIM_OC_MspInit 無 存放NVIC、CLOCK、GPIO初始化代碼 HAL_TIM_OC_ConfigChannel() CCMRx、CCRx、CCER 設(shè)置輸出比較模式、比較值、輸出極性等 __HAL_TIM_ENABLE_OCxPRELOAD() CCMRx 使能通道預(yù)裝載 HAL_TIM_OC_Start() CR1、CCER、BDTR 使能輸出比較、主輸出、啟動計數(shù)器 __HAL_TIM_SET_COMPARE() CCRx 修改捕獲/比較寄存器的值
4. 代碼實現(xiàn)
-
功能:
使用輸出比較模式的翻轉(zhuǎn)功能,通過定時器8的4路通道輸出占空比固定為50%、相位分別是25%、50%、75%和100%的PWM。
-
高級定時器輸出比較初始化
void atim_timx_comp_pwm_init(uint16_t arr, uint16_t psc) {TIM_OC_InitTypeDef timx_oc_comp_pwm = {0};g_timx_comp_pwm_handle.Instance = TIM8;g_timx_comp_pwm_handle.Init.Prescaler = psc;g_timx_comp_pwm_handle.Init.CounterMode = TIM_COUNTERMODE_UP; //向上計數(shù)模式g_timx_comp_pwm_handle.Init.Period = arr;g_timx_comp_pwm_handle.Init.RepetitionCounter = 0; //重復(fù)計數(shù)器初始值HAL_TIM_PWM_Init(&g_timx_comp_pwm_handle);timx_oc_comp_pwm.OCMode = TIM_OCMODE_TOGGLE; //模式選擇翻轉(zhuǎn)timx_oc_comp_pwm.OCPolarity = TIM_OCPOLARITY_HIGH; //極性選擇高電平HAL_TIM_OC_ConfigChannel(&g_timx_comp_pwm_handle, &timx_oc_comp_pwm, TIM_CHANNEL_1);HAL_TIM_OC_ConfigChannel(&g_timx_comp_pwm_handle, &timx_oc_comp_pwm, TIM_CHANNEL_2);HAL_TIM_OC_ConfigChannel(&g_timx_comp_pwm_handle, &timx_oc_comp_pwm, TIM_CHANNEL_3);HAL_TIM_OC_ConfigChannel(&g_timx_comp_pwm_handle, &timx_oc_comp_pwm, TIM_CHANNEL_4);//使能通道預(yù)裝載__HAL_TIM_ENABLE_OCxPRELOAD(&g_timx_comp_pwm_handle, TIM_CHANNEL_1);__HAL_TIM_ENABLE_OCxPRELOAD(&g_timx_comp_pwm_handle, TIM_CHANNEL_2);__HAL_TIM_ENABLE_OCxPRELOAD(&g_timx_comp_pwm_handle, TIM_CHANNEL_3);__HAL_TIM_ENABLE_OCxPRELOAD(&g_timx_comp_pwm_handle, TIM_CHANNEL_4);//使能輸出、主輸出、計數(shù)器HAL_TIM_OC_Start(&g_timx_comp_pwm_handle, TIM_CHANNEL_1);HAL_TIM_OC_Start(&g_timx_comp_pwm_handle, TIM_CHANNEL_2);HAL_TIM_OC_Start(&g_timx_comp_pwm_handle, TIM_CHANNEL_3);HAL_TIM_OC_Start(&g_timx_comp_pwm_handle, TIM_CHANNEL_4); }
-
定時器輸出比較MSP函數(shù)
void HAL_TIM_OC_MspInit(TIM_HandleTypeDef *htim) {if(htim->Instance == TIM8){GPIO_InitTypeDef gpio_init_struct;__HAL_RCC_TIM8_CLK_ENABLE();__HAL_RCC_GPIOC_CLK_ENABLE();gpio_init_struct.Mode = GPIO_MODE_AF_PP; //推挽復(fù)用gpio_init_struct.Pin = GPIO_PIN_6;gpio_init_struct.Pull = GPIO_NOPULL; //沒有上下拉gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOC, &gpio_init_struct);gpio_init_struct.Pin = GPIO_PIN_7;HAL_GPIO_Init(GPIOC, &gpio_init_struct);gpio_init_struct.Pin = GPIO_PIN_8;HAL_GPIO_Init(GPIOC, &gpio_init_struct);gpio_init_struct.Pin = GPIO_PIN_9;HAL_GPIO_Init(GPIOC, &gpio_init_struct);} }
-
主函數(shù)
int main(void) {uint8_t t = 0;HAL_Init(); /* 初始化HAL庫 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 設(shè)置時鐘, 72Mhz */delay_init(72); /* 延時初始化 */usart_init(115200); /* 串口初始化為115200 */led_init(); /* 初始化LED */key_init();atim_timx_comp_pwm_init(1000 - 1, 72 - 1);__HAL_TIM_SET_COMPARE(&g_timx_comp_pwm_handle, TIM_CHANNEL_1, 250 - 1);__HAL_TIM_SET_COMPARE(&g_timx_comp_pwm_handle, TIM_CHANNEL_2, 500 - 1);__HAL_TIM_SET_COMPARE(&g_timx_comp_pwm_handle, TIM_CHANNEL_3, 750 - 1);__HAL_TIM_SET_COMPARE(&g_timx_comp_pwm_handle, TIM_CHANNEL_3, 1000 - 1);while(1){ t++;if(t > 50){t = 0;LED0_TOGGLE();}delay_ms(10);} }
-
程序運行結(jié)果
八、高級定時器互補輸出帶死區(qū)控制實驗
1. 互補死區(qū)的理解
- 互補輸出
? CH1輸出黃色的PWM,互補通道CH1N輸出綠色的PWM,兩個信號恰好是相反的,CH1的PWM為高電平期 間,CH1N的PWM則是低電平,反之亦然,這就是互補輸出。
-
帶死區(qū)控制的互補輸出
CH1輸出的PWM和CH1N輸出的PWM在高低電平轉(zhuǎn)換期間,插入了一段時間才實現(xiàn)互補輸出。這段時間稱為死區(qū)時間。上圖箭頭所指的區(qū)域就是死區(qū)時間,兩段時間相同。
-
死區(qū)互補控制H橋
- 當(dāng)Q1和Q4導(dǎo)通,電流的方向是從左到右;當(dāng)Q2和Q3導(dǎo)通,電流的方向是從右到左。
- 因為元器件具有延時特性,控制信號經(jīng)過OC1傳輸?shù)诫姍C需要一定的時間。由于元器件的特性,就會直接導(dǎo)致直接使用互補輸出信號驅(qū)動H橋存在短路現(xiàn)象。為了避免這種情況,就有了帶死區(qū)控制的互補輸出來驅(qū)動H橋。用戶必須根據(jù)與輸出相連接的器件及其特性(電平轉(zhuǎn)換器的固有延遲、開關(guān)器件產(chǎn)生的延遲)來調(diào)整死區(qū)時間。
-
死區(qū)時間計算
2. 相關(guān)寄存器
-
控制寄存器1(
TIMx_CR1
)
-
捕獲/比較模式寄存器1/2(
TIMx_CCMR1/2
)
-
捕獲/比較使能寄存器(
TIMx_CCER
)
-
捕獲/比較寄存器1/2/3/4(
TIMx_CCR1/2/3/4
)
-
TIM1/TIM8斷路和死區(qū)寄存器(
TIMx_BDTR
)
對應(yīng)的結(jié)構(gòu)框圖
-
剎車斷路功能
發(fā)生剎車后:
3. 高級定時器互補輸出帶死區(qū)控制實驗配置步驟
-
配置定時器基礎(chǔ)工作參數(shù)
HAL_TIM_PWM_Init()
-
定時器PWM輸出MSP初始化
HAL_TIM_PWM_MspInit()
-
配置PWM模式/比較值等
HAL_TIM_PWM_ConfigChannel()
-
配置剎車功能、死區(qū)時間等
HAL_TIMEx_ConfigBreakDeadTime()
-
使能輸出、主輸出、計數(shù)器
HAL_TIM_PWM_Start()
-
使能互補輸出、主輸出、計數(shù)器
HAL_TIMEx_PWMN_Start()
-
相關(guān)函數(shù)功能
函數(shù) 主要寄存器 主要功能 HAL_TIM_PWM_Init() CR1、ARR、PSC 初始化定時器基礎(chǔ)參數(shù) HAL_TIM_PWM_MspInit() 無 存放NVIC、CLOCK、GPIO初始化代碼 HAL_TIM_PWM_ConfigChannel() CCMRx、CCRx、CCER 配置PWM模式、比較值、輸出極性等 HAL_TIMEx_ConfigBreakDeadTime() BDTR 配置剎車功能、死區(qū)時間等 HAL_TIM_PWM_Start() CCER、CR1 使能輸出、主輸出、啟動計數(shù)器 HAL_TIMEx_PWMN_Start() CCER、CR1 使能互補輸出、主輸出、啟動計數(shù)器
4. 代碼實現(xiàn)
-
功能:
- 利用TIM1_CH1(PE9)輸出70%占空比的PWM波,它的互補輸出通道(PE8)則是輸出30%占空比的PWM波。
- 剎車功能,當(dāng)給剎車輸入引腳(PE15)輸入高電平時,進行剎車,即PE8和PE9停止輸出PWM波。
- LED0閃爍指示程序運行。
-
高級定時器互補輸出初始化函數(shù)
void atim_timx_cplm_pwm_init(uint16_t arr, uint16_t psc) {TIM_OC_InitTypeDef timx_oc_cplm_pwm = {0};g_timx_cplm_pwm_handle.Instance = TIM1; //定時器選擇g_timx_cplm_pwm_handle.Init.Prescaler = psc; //定時器分頻g_timx_cplm_pwm_handle.Init.Period = arr;g_timx_cplm_pwm_handle.Init.CounterMode = TIM_COUNTERMODE_UP; //定時器計數(shù)模式g_timx_comp_pwm_handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV4; //CKD[1:0] = 10HAL_TIM_PWM_Init(&g_timx_cplm_pwm_handle); //初始化PWMtimx_oc_cplm_pwm.OCMode = TIM_OCMODE_PWM1; //模式選擇PWM模式1timx_oc_cplm_pwm.OCPolarity = TIM_OCPOLARITY_HIGH; //OC1高電平有效timx_oc_cplm_pwm.OCNPolarity = TIM_OCPOLARITY_HIGH; //OC1N高電平有效timx_oc_cplm_pwm.OCIdleState = TIM_OCIDLESTATE_RESET; //當(dāng)MOE = 0, OC1 = 1;timx_oc_cplm_pwm.OCNIdleState = TIM_OCNIDLESTATE_RESET;//當(dāng)MOE = 0, OC1x = 1;HAL_TIM_PWM_ConfigChannel(&g_timx_cplm_pwm_handle, &timx_oc_cplm_pwm, TIM_CHANNEL_1);//設(shè)置死區(qū)參數(shù)g_sbreak_dead_time_config.OffStateRunMode = TIM_OSSR_DISABLE; //運行模式下的關(guān)閉狀態(tài)選擇g_sbreak_dead_time_config.OffStateIDLEMode = TIM_OSSI_DISABLE; //空閑模式下的關(guān)閉狀態(tài)選擇g_sbreak_dead_time_config.LockLevel = TIM_LOCKLEVEL_OFF; //寄存器鎖定配置g_sbreak_dead_time_config.BreakState = TIM_BREAK_ENABLE; //斷路輸入使能控制g_sbreak_dead_time_config.BreakPolarity = TIM_BREAKPOLARITY_HIGH; //斷路輸入極性g_sbreak_dead_time_config.AutomaticOutput = TIM_AUTOMATICOUTPUT_ENABLE; //自動恢復(fù)輸出使能控制HAL_TIMEx_ConfigBreakDeadTime(&g_timx_cplm_pwm_handle, &g_sbreak_dead_time_config);HAL_TIM_PWM_Start(&g_timx_cplm_pwm_handle, TIM_CHANNEL_1); //啟動定時器的正常輸出HAL_TIMEx_PWMN_Start(&g_timx_cplm_pwm_handle, TIM_CHANNEL_1); //啟動定時器的互補輸出 }
-
定時器設(shè)置輸出比較值死區(qū)時間
void atim_timx_cplm_pwm_set(uint16_t ccr, uint8_t dtg) {//設(shè)置比較寄存器的值__HAL_TIM_SET_COMPARE(&g_timx_cplm_pwm_handle, TIM_CHANNEL_1, ccr);//單獨進行死區(qū)時間的設(shè)置g_sbreak_dead_time_config.DeadTime = dtg;HAL_TIMEx_ConfigBreakDeadTime(&g_timx_cplm_pwm_handle, &g_sbreak_dead_time_config); }
-
主函數(shù)
int main(void) {uint8_t t = 0;HAL_Init(); /* 初始化HAL庫 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 設(shè)置時鐘, 72Mhz */delay_init(72); /* 延時初始化 */usart_init(115200); /* 串口初始化為115200 */led_init(); /* 初始化LED */key_init();//設(shè)置1khz的周期atim_timx_cplm_pwm_init(1000 - 1, 72 - 1);//設(shè)置TIM捕獲比較寄存器值,從而控制占空比為70%atim_timx_cplm_pwm_set(700 - 1, 100);while(1){ t++;if(t > 50){t = 0;LED0_TOGGLE();}delay_ms(10);} }
-
程序運行流程
-
程序運行結(jié)果
九、高級定時器PWM輸入模式實驗
1. PWM輸入工作原理
- 確定定時器的時鐘源:本代碼使用內(nèi)部時鐘(CK_INT),時鐘頻率為72MHz,計數(shù)頻率確定了測量精度。
- 確定PWM輸入的通道:PWM輸入模式下測量PWM,PWM信號輸入只能從通道1或通道2輸入。
- 確定IC1和IC2的捕獲邊沿:以通道 1(CH1)輸入 PWM 為例,一般設(shè)置 IC1 捕獲邊沿為上升沿捕獲,IC2 捕獲邊沿為下降沿捕獲。
- 選擇觸發(fā)輸入信號:選擇TI1FP1或TI2FP2。
- 從模式選擇:復(fù)位模式,在出現(xiàn)所選觸發(fā)輸入(TRGI)上升沿時,重新初始化計數(shù)器并生成一個寄存器更新事件。
- 讀取一個PWM周期內(nèi)計數(shù)器的計數(shù)個數(shù),以及高電平期間計數(shù)個數(shù),再結(jié)合計數(shù)器的計數(shù)周期,最終通過計算得到輸入的PWM周期和占空比等參數(shù)。
2. 輸入模式時序圖
假設(shè)計數(shù)器的計數(shù)頻率是72MHz,那我們就可以計算出PWM的周期、頻率和占空比等參數(shù)。由計數(shù)器的計數(shù)頻率為72Hz,可以得到計數(shù)器計一個數(shù)的時間是13.8ns(即測量的精度是13.8ns)。知道了測量精度,再來計算PWM的周期,PWM周期=(4+1)*(1/72000000)=69.4ns,那么PWM的頻率就是14.4MHz。占空比= (2+1)/(4+1)=3/5(即占空比為60%)。
3. 相關(guān)寄存器
-
從模式控制寄存器(
TIMx_SMCR
)
-
捕獲/比較模式寄存器1/2(
TIMx_CCMR1/2
)
-
捕獲/比較使能寄存器(
TIMx_CCER
)
-
捕獲/比較寄存器1/2/3/4(
TIMx_CCR1/2/3/4
)
-
DMA中斷使能寄存器(
TIMx_DIER
)
4. 高級定時器PWM輸入模式實驗配置步驟
-
配置定時器基礎(chǔ)工作參數(shù)
HAL_TIM_IC_Init()
-
定時器捕獲輸入MSP初始化
HAL_TIM_IC_MspInit()
-
配置IC1/2映射、捕獲邊沿等
HAL_TIM_IC_ConfigChannel()
-
配置從模式,觸發(fā)源等
HAL_TIM_SlaveConfigSynchro()
-
設(shè)置優(yōu)先級,使能中斷
HAL_NVIC_SetPriority() HAL_NVIC_EnableIRQ()
-
使能捕獲、捕獲中斷及計數(shù)器
HAL_TIM_IC_Start_IT() HAL_TIM_IC_Start()
-
編寫中斷服務(wù)函數(shù)
TIMx_IRQHandler()
-
編寫輸入捕獲回調(diào)函數(shù)
HAL_TIM_IC_CaptureCallback()
-
函數(shù)具體功能
函數(shù) 主要寄存器 主要功能 HAL_TIM_IC_Init() CR1、ARR、PSC 初始化定時器基礎(chǔ)參數(shù) HAL_TIM_IC_MspInit() 無 存放NVIC、CLOCK、GPIO初始化代碼 HAL_TIM_IC_ConfigChannel() CCMRx、CCER 配置通道映射、捕獲邊沿、分頻、濾波等 HAL_TIM_SlaveConfigSynchro() SMCR、CCER 配置從模式、觸發(fā)源、觸發(fā)邊沿等 HAL_TIM_IC_Start_IT() CCER、DIER、CR1 使能輸入捕獲、捕獲中斷并啟動計數(shù)器 HAL_TIM_IRQHandler() SR 定時器中斷處理公用函數(shù),處理各種中斷 HAL_TIM_IC_CaptureCallback() 無 定時器輸入捕獲回調(diào)函數(shù),由用戶重定義
4. 代碼實現(xiàn)
-
功能:
首先通過TM3_CH2(PB5)輸出PWM波。然后把PB5輸出的PWM波用杜邦線接入PC6(定時器8通道1),最后通過串口打印PWM波的脈寬和頻率等信息。通過LED1閃爍來提示程序正在運行。
-
通用定時器PWM輸出初始化函數(shù)
void gtim_timx_pwm_chy_init(uint16_t arr, uint16_t psc) {TIM_OC_InitTypeDef timx_oc_pwm_chy;g_timx_pwm_chy_handle.Instance = TIM3;g_timx_pwm_chy_handle.Init.Prescaler = psc;g_timx_pwm_chy_handle.Init.Period = arr;g_timx_pwm_chy_handle.Init.CounterMode = TIM_COUNTERMODE_UP;HAL_TIM_PWM_Init(&g_timx_pwm_chy_handle);timx_oc_pwm_chy.OCMode = TIM_OCMODE_PWM1;timx_oc_pwm_chy.Pulse = arr / 2;timx_oc_pwm_chy.OCPolarity = TIM_OCPOLARITY_LOW;HAL_TIM_PWM_ConfigChannel(&g_timx_pwm_chy_handle, &timx_oc_pwm_chy, TIM_CHANNEL_2);HAL_TIM_PWM_Start(&g_timx_pwm_chy_handle, TIM_CHANNEL_2); }
-
定時器輸出PWM MSP初始化函數(shù)
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim) {if(htim->Instance == TIM3){GPIO_InitTypeDef gpio_init_struct;__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_TIM3_CLK_ENABLE();gpio_init_struct.Pin = GPIO_PIN_5;gpio_init_struct.Mode = GPIO_MODE_AF_PP; /* 推挽復(fù)用 */gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */HAL_GPIO_Init(GPIOB, &gpio_init_struct);__HAL_RCC_AFIO_CLK_ENABLE();__HAL_AFIO_REMAP_TIM3_PARTIAL();} }
-
PWM輸入模式初始化函數(shù)
void atim_timx_pwmin_chy_init(void) {TIM_SlaveConfigTypeDef slave_config = {0};TIM_IC_InitTypeDef tim_ic_pwmin_chy = {0};g_timx_pwmin_chy_handle.Instance = TIM8; /* 定時器8 */g_timx_pwmin_chy_handle.Init.Prescaler = 0; /* 定時器預(yù)分頻系數(shù) */g_timx_pwmin_chy_handle.Init.CounterMode = TIM_COUNTERMODE_UP; /* 遞增計數(shù)模式 */g_timx_pwmin_chy_handle.Init.Period = 65535; /* 自動重裝載值 */HAL_TIM_IC_Init(&g_timx_pwmin_chy_handle);/* 從模式配置,IT1觸發(fā)更新 */slave_config.SlaveMode = TIM_SLAVEMODE_RESET; /* 從模式:復(fù)位模式 */slave_config.InputTrigger = TIM_TS_TI1FP1; /* 定時器輸入觸發(fā)源:TI1FP1 */slave_config.TriggerPolarity = TIM_TRIGGERPOLARITY_RISING; /* 上升沿檢測 */slave_config.TriggerFilter = 0; /* 不濾波 */HAL_TIM_SlaveConfigSynchro(&g_timx_pwmin_chy_handle, &slave_config);/* IC1捕獲:上升沿觸發(fā)TI1FP1 */tim_ic_pwmin_chy.ICPolarity = TIM_ICPOLARITY_RISING; /* 上升沿檢測 */tim_ic_pwmin_chy.ICSelection = TIM_ICSELECTION_DIRECTTI; /* 選擇輸入端IC1映射到TI1 */tim_ic_pwmin_chy.ICPrescaler = TIM_ICPSC_DIV1; /* 不分頻 */tim_ic_pwmin_chy.ICFilter = 0; /* 不濾波 */HAL_TIM_IC_ConfigChannel(&g_timx_pwmin_chy_handle, &tim_ic_pwmin_chy, TIM_CHANNEL_1);/* IC2捕獲:下降沿觸發(fā)TI1FP2 */tim_ic_pwmin_chy.ICPolarity = TIM_ICPOLARITY_FALLING; /* 下降沿檢測 */tim_ic_pwmin_chy.ICSelection = TIM_ICSELECTION_INDIRECTTI; /* 選擇輸入端IC2映射到TI1 */HAL_TIM_IC_ConfigChannel(&g_timx_pwmin_chy_handle, &tim_ic_pwmin_chy, TIM_CHANNEL_2);HAL_TIM_IC_Start_IT(&g_timx_pwmin_chy_handle, TIM_CHANNEL_1);HAL_TIM_IC_Start(&g_timx_pwmin_chy_handle, TIM_CHANNEL_2); }
-
定時器輸入捕獲MSP初始化函數(shù)
void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim) {if(htim->Instance == TIM8){GPIO_InitTypeDef gpio_init_struct = {0};__HAL_RCC_TIM8_CLK_ENABLE();__HAL_RCC_GPIOC_CLK_ENABLE();gpio_init_struct.Pin = GPIO_PIN_6;gpio_init_struct.Mode = GPIO_MODE_AF_PP;gpio_init_struct.Pull = GPIO_PULLDOWN;gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOC, &gpio_init_struct);/* TIM1/TIM8有獨立的輸入捕獲中斷服務(wù)函數(shù) */HAL_NVIC_SetPriority(TIM8_CC_IRQn, 1, 3);HAL_NVIC_EnableIRQ(TIM8_CC_IRQn);} }
-
定時器8輸入捕獲中斷服務(wù)函數(shù)
void TIM8_CC_IRQHandler(void) {HAL_TIM_IRQHandler(&g_timx_pwmin_chy_handle); /* 定時器共用處理函數(shù) */ }
-
PWM輸入模式重新啟動捕獲函數(shù)
void atim_timx_pwmin_chy_restart(void) {sys_intx_disable(); /* 關(guān)閉中斷 */g_timxchy_pwmin_sta = 0; /* 清零狀態(tài),重新開始檢測 */g_timxchy_pwmin_hval=0;g_timxchy_pwmin_cval=0;sys_intx_enable(); /* 打開中斷 */ }
-
定時器輸入捕獲中斷處理回調(diào)函數(shù)
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) {if(htim->Instance == TIM8){if(g_timxchy_pwmin_sta == 0){if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1){g_timxchy_pwmin_hval = HAL_TIM_ReadCapturedValue(&g_timx_pwmin_chy_handle, TIM_CHANNEL_2) + 1 + 1;g_timxchy_pwmin_cval = HAL_TIM_ReadCapturedValue(&g_timx_pwmin_chy_handle, TIM_CHANNEL_1) + 1 + 1;g_timxchy_pwmin_sta = 1;}}} }
-
主函數(shù)
int main(void) {uint8_t t = 0;double ht, ct, f, tpsc;HAL_Init(); /* 初始化HAL庫 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 設(shè)置時鐘, 72Mhz */delay_init(72); /* 延時初始化 */usart_init(115200); /* 串口初始化為115200 */led_init(); /* 初始化LED */gtim_timx_pwm_chy_init(10 - 1, 72 - 1);TIM3->CCR2 = 3;atim_timx_pwmin_chy_init();while (1){delay_ms(10);t++;if (t >= 20) /* 每200ms輸出一次結(jié)果,并閃爍LED0,提示程序運行 */{if (g_timxchy_pwmin_sta) /* 捕獲了一次數(shù)據(jù) */{printf("\r\n"); /* 輸出空,另起一行 */printf("PWM PSC :%d\r\n", g_timxchy_pwmin_psc); /* 打印分頻系數(shù) */printf("PWM Hight:%d\r\n", g_timxchy_pwmin_hval); /* 打印高電平脈寬 */printf("PWM Cycle:%d\r\n", g_timxchy_pwmin_cval); /* 打印周期 */tpsc = ((double)g_timxchy_pwmin_psc + 1) / 72; /* 得到PWM采樣時鐘周期時間 */ ht = g_timxchy_pwmin_hval * tpsc; /* 計算高電平時間 */ct = g_timxchy_pwmin_cval * tpsc; /* 計算周期長度 */f = (1 / ct) * 1000000; /* 計算頻率 */printf("PWM Hight time:%.3fus\r\n", ht); /* 打印高電平脈寬長度 */printf("PWM Cycle time:%.3fus\r\n", ct); /* 打印周期時間長度 */printf("PWM Frequency :%.3fHz\r\n", f); /* 打印頻率 */ atim_timx_pwmin_chy_restart(); /* 重啟PWM輸入檢測 */} LED1_TOGGLE(); /* LED1(GREEN)閃爍 */t = 0;}} }
聲明:資料來源(戰(zhàn)艦STM32F103ZET6開發(fā)板資源包)
- Cortex-M3權(quán)威指南(中文).pdf
- STM32F10xxx參考手冊_V10(中文版).pdf
- STM32F103 戰(zhàn)艦開發(fā)指南V1.3.pdf
- STM32F103ZET6(中文版).pdf
- 戰(zhàn)艦V4 硬件參考手冊_V1.0.pdf