中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

鶴壁做網(wǎng)站的公司360搜索引擎地址

鶴壁做網(wǎng)站的公司,360搜索引擎地址,wordpress 側(cè)滑,做app網(wǎng)站公司STM32-01-認(rèn)識(shí)單片機(jī) STM32-02-基礎(chǔ)知識(shí) STM32-03-HAL庫(kù) STM32-04-時(shí)鐘樹 STM32-05-SYSTEM文件夾 STM32-06-GPIO STM32-07-外部中斷 STM32-08-串口 STM32-09-IWDG和WWDG 文章目錄 一、STM32 基礎(chǔ)定時(shí)器1. 基本定時(shí)器簡(jiǎn)介2. 基本定時(shí)器框圖3. 基本定時(shí)器相關(guān)寄存器4. 定時(shí)器溢出…

STM32-01-認(rèn)識(shí)單片機(jī)
STM32-02-基礎(chǔ)知識(shí)
STM32-03-HAL庫(kù)
STM32-04-時(shí)鐘樹
STM32-05-SYSTEM文件夾
STM32-06-GPIO
STM32-07-外部中斷
STM32-08-串口
STM32-09-IWDG和WWDG

文章目錄

  • 一、STM32 基礎(chǔ)定時(shí)器
    • 1. 基本定時(shí)器簡(jiǎn)介
    • 2. 基本定時(shí)器框圖
    • 3. 基本定時(shí)器相關(guān)寄存器
    • 4. 定時(shí)器溢出時(shí)間計(jì)算
    • 5. 基本定時(shí)器中斷配置步驟
    • 6. 代碼實(shí)現(xiàn)
  • 二、STM32通用定時(shí)器
    • 1. 通用定時(shí)器簡(jiǎn)介
    • 2. 通用定時(shí)器框圖
      • 1. 時(shí)鐘源
        • 1. 內(nèi)部時(shí)鐘(`CK_INT`)
        • 2. 外部時(shí)鐘模式1(TI1, TI2)
        • 3. 外部時(shí)鐘模式2(ETR)
        • 4. 內(nèi)部觸發(fā)輸入(ITRx)
      • 2. 控制器
      • 3. 時(shí)基單元
      • 4. 輸入捕獲
      • 5. 捕獲/比較(公共)
      • 6. 輸出比較
    • 3. 通用定時(shí)器相關(guān)寄存器
  • 三、 通用定時(shí)器輸出PWM波
    • 1. 通用定時(shí)器PWM輸出實(shí)驗(yàn)配置步驟
    • 2. 代碼實(shí)現(xiàn)
  • 四、通用定時(shí)器輸入捕獲實(shí)驗(yàn)
    • 1. 輸入捕獲測(cè)量脈沖寬度
    • 2. 輸入捕獲實(shí)驗(yàn)相關(guān)寄存器
    • 3. 通用定時(shí)器輸入捕獲配置步驟
    • 4. 代碼實(shí)現(xiàn)
  • 五、通用定時(shí)器脈沖計(jì)數(shù)實(shí)驗(yàn)
    • 1. 脈沖計(jì)數(shù)框圖
    • 2. 相關(guān)寄存器
    • 3. 通用定時(shí)器脈沖計(jì)數(shù)配置步驟
    • 4. 代碼實(shí)現(xiàn)
  • 六、高級(jí)定時(shí)器輸出指定個(gè)數(shù)PWM實(shí)驗(yàn)
    • 1. 高級(jí)定時(shí)器框圖
    • 2. 重復(fù)計(jì)數(shù)器特性
    • 3. 相關(guān)寄存器
    • 4. 高級(jí)定時(shí)器輸出指定個(gè)數(shù)PWM實(shí)驗(yàn)配置步驟
    • 5. 代碼實(shí)現(xiàn)
  • 七、高級(jí)定時(shí)器輸出比較模式實(shí)驗(yàn)
    • 1. 輸出比較模式功能
    • 2. 相關(guān)寄存器
    • 3. 高級(jí)定時(shí)器輸出比較模式實(shí)驗(yàn)配置步驟
    • 4. 代碼實(shí)現(xiàn)
  • 八、高級(jí)定時(shí)器互補(bǔ)輸出帶死區(qū)控制實(shí)驗(yàn)
    • 1. 互補(bǔ)死區(qū)的理解
    • 2. 相關(guān)寄存器
    • 3. 高級(jí)定時(shí)器互補(bǔ)輸出帶死區(qū)控制實(shí)驗(yàn)配置步驟
    • 4. 代碼實(shí)現(xiàn)
  • 九、高級(jí)定時(shí)器PWM輸入模式實(shí)驗(yàn)
    • 1. PWM輸入工作原理
    • 2. 輸入模式時(shí)序圖
    • 3. 相關(guān)寄存器
    • 4. 高級(jí)定時(shí)器PWM輸入模式實(shí)驗(yàn)配置步驟
    • 4. 代碼實(shí)現(xiàn)

一、STM32 基礎(chǔ)定時(shí)器

STM32定時(shí)器分類
在這里插入圖片描述

STM32定時(shí)器特性表:
在這里插入圖片描述

主要功能:

定時(shí)器類型主要功能
基本定時(shí)器沒有輸入輸出通道,常用作時(shí)基,即定時(shí)功能
通用定時(shí)器具有多路獨(dú)立通道,可用于輸入捕獲/輸出比較,也可用作時(shí)基
高級(jí)定時(shí)器除具備通用定時(shí)器所有功能外,還具備帶死區(qū)控制的互補(bǔ)信號(hào)輸出、剎車輸入等功能(可用于電機(jī)控制、數(shù)字電源設(shè)計(jì)等)

1. 基本定時(shí)器簡(jiǎn)介

  • STM32F103有兩個(gè)基本定時(shí)器TIM6TIM7,它們的功能完全相同,資源是完全獨(dú)立的,可以同時(shí)使用。

  • 主要特性

    • 16位自動(dòng)重載遞增計(jì)數(shù)器;
    • 16位可編程預(yù)分頻器,預(yù)分頻系數(shù)1~65536,用于對(duì)計(jì)數(shù)器時(shí)鐘頻率進(jìn)行分頻;
    • 觸發(fā)DAC的同步電路;
    • 生成中斷DMA請(qǐng)求。
  • 定時(shí)原理:
    在這里插入圖片描述

2. 基本定時(shí)器框圖

在這里插入圖片描述

  • 影子寄存器: 實(shí)際起作用的寄存器,用戶不可直接訪問。舉個(gè)例子:我們可以把預(yù)分頻系數(shù)寫入預(yù)分頻器寄存器(TIMx_PSC),但是預(yù)分頻器寄存器只是起到緩存數(shù)據(jù)的作用,只有等到更新事件發(fā)生時(shí),預(yù)分頻器寄存器的值才會(huì)被自動(dòng)寫入其影子寄存器中,這時(shí)才真正起作用。

  • 自動(dòng)重載寄存器:自動(dòng)重載寄存器及其影子寄存器的作用在于自動(dòng)重載寄存器是否具有緩沖作用還受到ARPE位的控制。

    • 當(dāng)該位置0時(shí),ARR寄存器不進(jìn)行緩沖,寫入新ARR值會(huì)立即傳送到ARR影子寄存器從而直接生效;
    • 當(dāng)該位置1時(shí),ARR寄存器進(jìn)行緩沖,寫入新ARR值時(shí)不會(huì)立即被寫入ARR影子寄存器,而是要等到更新事件發(fā)生才會(huì)被寫入ARR影子寄存器,這時(shí)才生效。預(yù)分頻器寄存器則沒有這樣相關(guān)的控制位,這就是它們不同點(diǎn)。
  • 更新事件的產(chǎn)生:

    1. 軟件產(chǎn)生,將 TIMx_EGR 寄存器的位UG置 1,產(chǎn)生更新事件后,硬件會(huì)自動(dòng)將 UG 位清零。
    2. 硬件產(chǎn)生,基本定時(shí)器的計(jì)數(shù)器(CNT)是一個(gè)遞增的計(jì)數(shù)器,當(dāng)寄存器(TIMx_CR1)的CEN位置 1,即使能定時(shí)器,每來一個(gè)CK_CNT脈沖,TIMx_CNT的值就會(huì)遞增加1。當(dāng)TIMx_CNT值與TIMx_ARR的設(shè)定值相等時(shí),TIMx_CNT的值就會(huì)被自動(dòng)清零并且會(huì)生成更新事件(如果開啟相應(yīng)的功能,就會(huì)產(chǎn)生DMA請(qǐng)求、產(chǎn)生中斷信號(hào)或者觸發(fā)DAC同步電路),然后下一個(gè) CK_CNT脈沖到來,TIMx_CNT的值就會(huì)遞增加1,如此循環(huán)。在此過程中,TIMx_CNT等于 TIMx_ARR時(shí),我們稱之為定時(shí)器溢出,因?yàn)槭沁f增計(jì)數(shù),故而又稱為定時(shí)器上溢。定時(shí)器溢出就伴隨著更新事件的發(fā)生。
  • 計(jì)數(shù)模式與溢出條件:
    在這里插入圖片描述

    • 遞增計(jì)數(shù)模式實(shí)例說明
      在這里插入圖片描述

    • 遞減計(jì)數(shù)模式實(shí)例說明
      在這里插入圖片描述

    • 中心對(duì)齊計(jì)數(shù)模式實(shí)例說明:
      在這里插入圖片描述

3. 基本定時(shí)器相關(guān)寄存器

  • 控制寄存器 1(TIMx_CR1)
    在這里插入圖片描述

  • DMA/中斷使能寄存器(TIMx_DIER)
    在這里插入圖片描述

  • 狀態(tài)寄存器(TIMx_SR)
    在這里插入圖片描述

  • 計(jì)數(shù)器(TIMx_CNT)
    在這里插入圖片描述

  • 預(yù)分頻器(TIMx_PSC)
    在這里插入圖片描述

  • 自動(dòng)重裝載寄存器(TIMx_ARR)
    在這里插入圖片描述

4. 定時(shí)器溢出時(shí)間計(jì)算

在這里插入圖片描述

5. 基本定時(shí)器中斷配置步驟

  1. 配置定時(shí)器基礎(chǔ)工作參數(shù)

    HAL_TIM_Base_Init()
    
  2. 定時(shí)器基礎(chǔ)MSP初始化

    HAL_TIM_Base_MspInit()     
    
  3. 使能更新中斷并啟動(dòng)計(jì)數(shù)器

    HAL_TIM_Base_Start_IT()
    
  4. 設(shè)置優(yōu)先級(jí),使能中斷

    HAL_NVIC_SetPriority()
    HAL_NVIC_EnableIRQ()    
    
  5. 編寫中斷服務(wù)函數(shù)

    TIMx_IRQHandler()
    HAL_TIM_IRQHandler()
    
  6. 編寫定時(shí)器更新中斷回調(diào)函數(shù)

    HAL_TIM_PeriodElapsedCallback()
    
  • 程序流程

    在這里插入圖片描述

6. 代碼實(shí)現(xiàn)

  • 功能:使用定時(shí)器中斷實(shí)現(xiàn)LED燈閃爍.

  • 定時(shí)器中斷初始化

    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);}
    
  • 定時(shí)器基礎(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);}
    }
    
  • 定時(shí)器6中斷服務(wù)函數(shù)

    void TIM6_IRQHandler()
    {HAL_TIM_IRQHandler(&g_timx_handle);
    }
    
  • 定時(shí)器溢出中斷回調(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庫(kù) */sys_stm32_clock_init(RCC_PLL_MUL9);     /* 設(shè)置時(shí)鐘, 72Mhz */delay_init(72);                         /* 延時(shí)初始化 */usart_init(115200);                     /* 串口初始化為115200 */led_init();                             /* 初始化LED */btim_timx_int_init(7199, 4999);while(1){}
    } 
    

二、STM32通用定時(shí)器

1. 通用定時(shí)器簡(jiǎn)介

  1. 通用定時(shí)器是一個(gè)通過可編程預(yù)分頻器驅(qū)動(dòng)的16位自動(dòng)裝載計(jì)數(shù)器構(gòu)成。
  2. 它適用于多種場(chǎng)合,包括測(cè)量輸入信號(hào)的脈沖寬度(輸入捕獲)或者產(chǎn)生輸出波形(輸出比較和PWM)。
  3. 使用定時(shí)器預(yù)分頻器和RCC時(shí)鐘控制器預(yù)分頻器,脈沖長(zhǎng)度和波形周期可以在幾個(gè)微秒到幾個(gè)毫秒間調(diào)整。
  4. 每個(gè)定時(shí)器都是完全獨(dú)立的,沒有互相共享任何資源,并且可以一起同步操作。
  • 主要特性

    • 16位遞增、遞減、中心對(duì)齊計(jì)數(shù)器(計(jì)數(shù)值:0~65535)

    • 16位預(yù)分頻器(分頻系數(shù):1~65536)

    • 4個(gè)獨(dú)立通道:輸入捕獲輸出比較PWM生成單脈沖模式輸出

    • 使用外部信號(hào)控制定時(shí)器且可實(shí)現(xiàn)多個(gè)定時(shí)器互連的同步電路

    • 支持針對(duì)定位的增量編碼器和霍爾傳感器電路

    • 觸發(fā)輸入作為外部時(shí)鐘或者按周期的電流管理

2. 通用定時(shí)器框圖

1. 時(shí)鐘源

在這里插入圖片描述

計(jì)數(shù)器時(shí)鐘選擇類型設(shè)置方法
內(nèi)部時(shí)鐘(CK_INT)設(shè)置TIMx_SMCR的SMS=000
外部時(shí)鐘模式1:外部輸入引腳(TIx)設(shè)置TIMx_SMCR的SMS=111
外部時(shí)鐘模式2:外部觸發(fā)輸入(ETR)設(shè)置TIMx_SMCR的ECE=1
內(nèi)部觸發(fā)輸入(ITRx)

在這里插入圖片描述

1. 內(nèi)部時(shí)鐘(CK_INT
  • 定時(shí)器TIM2~TIM7掛接在APB1總線上,這些定時(shí)器的內(nèi)部時(shí)鐘(CK_INT)實(shí)際上來自APB1總線提供的時(shí)鐘,然后經(jīng)過一個(gè)倍頻器之后,輸出的時(shí)鐘頻率為72MHz。
2. 外部時(shí)鐘模式1(TI1, TI2)

在這里插入圖片描述

3. 外部時(shí)鐘模式2(ETR)

在這里插入圖片描述

4. 內(nèi)部觸發(fā)輸入(ITRx)

在這里插入圖片描述

2. 控制器

在這里插入圖片描述

  • 控制器包括:觸發(fā)控制器,從模式控制器,編碼器接口

    • 觸發(fā)控制器:用來提供觸發(fā)信號(hào)給別的外設(shè)

    • 從模式控制器:可以控制計(jì)數(shù)器復(fù)位、啟動(dòng)、遞增/遞減、計(jì)數(shù)

    • 編碼器接口:針對(duì)編碼器計(jì)數(shù)

3. 時(shí)基單元

在這里插入圖片描述

4. 輸入捕獲

在這里插入圖片描述

  • TIMx_CH1~TIMx_CH4表示定時(shí)器的4個(gè)通道,4個(gè)通道獨(dú)立工作。IO端口通過復(fù)用功能與這些通道相連。配置好IO端口的復(fù)用功能后,將需要測(cè)量的信號(hào)輸入到相應(yīng)的 IO端口,輸入捕獲部分可以對(duì)輸入的信號(hào)的上升沿,下降沿或者雙邊沿進(jìn)行捕獲,常見的測(cè)量有:測(cè)量輸入信號(hào)的脈沖寬度、測(cè)量PWM輸入信號(hào)的頻率和占空比等。
    在這里插入圖片描述

5. 捕獲/比較(公共)

在這里插入圖片描述

以通道1為例,對(duì)應(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;比如檢測(cè)上升沿,CC1P位置0:接著就是等待測(cè)量信號(hào)的上升沿到來。當(dāng)上升沿到來時(shí),IC1PS信號(hào)就會(huì)觸發(fā)輸入捕獲事件發(fā)生,計(jì)數(shù)器的值就會(huì)被鎖存到捕獲/比較影子寄存器里。當(dāng)CCR1寄存器沒有被進(jìn)行讀操作的時(shí)候,捕獲/比較影子寄存器里的值就會(huì)鎖存到CCR1寄存器中,那么程序員就可以讀取CCR1寄存器,得到計(jì)數(shù)器的計(jì)數(shù)值。檢測(cè)下降沿同理。

6. 輸出比較

在這里插入圖片描述

首先程序員寫CCR1寄存器,即寫入比較值。這個(gè)比較值需要轉(zhuǎn)移到對(duì)應(yīng)的捕獲比較影子寄存器后才會(huì)真正生效。什么條件下才能轉(zhuǎn)移?compare transfer旁邊的與門,需要滿足三個(gè)條件:CCR1不在寫入操作期間、CC1S[1:0]=0配置為輸出、OC1PE位置 0(或者OC1PE位置1,并且需要發(fā)生更新事件,這個(gè)更新事件可以軟件產(chǎn)生或者硬件產(chǎn)生)。當(dāng)CCR1寄存器的值轉(zhuǎn)移到其影子寄存器后,新的值就會(huì)和計(jì)數(shù)器的值進(jìn)行比較,它們的比較結(jié)果將會(huì)通過輸出比較影響定時(shí)器的輸出。
在這里插入圖片描述

3. 通用定時(shí)器相關(guān)寄存器

  • 控制寄存器1TIMx_CR1
    在這里插入圖片描述

  • 從模式控制寄存器TIMx_SMCR
    在這里插入圖片描述

  • DMA/中斷使能寄存器TIMx_DIER
    在這里插入圖片描述

  • 狀態(tài)寄存器TIMx_SR
    在這里插入圖片描述

  • 計(jì)數(shù)寄存器TIMx_CNT
    在這里插入圖片描述

  • 預(yù)分頻寄存器TIMx_PSC
    在這里插入圖片描述

  • 自動(dòng)重載寄存器TIMx_ARR
    在這里插入圖片描述

三、 通用定時(shí)器輸出PWM波

  • 通用定時(shí)器輸出模式

    PWM,即脈沖寬度調(diào)制,是利用微處理器的數(shù)字輸出對(duì)模擬電路進(jìn)行控制的一種非常有效的技術(shù)。讓定時(shí)器產(chǎn)生PWM,在計(jì)數(shù)器頻率固定時(shí),PWM頻率自動(dòng)重載寄存器(TIMx_ARR)的值決定,其占空比由捕獲/比較寄存器(TIMx_CCRx)的值決定。
    在這里插入圖片描述

  • PWM模式
    在這里插入圖片描述

  • PWM控制寄存器

    • 捕獲/比較模式寄存器1/2TIMx_CCMR1/2
      在這里插入圖片描述

    • 捕獲/比較使能寄存器TIMx_CCER
      在這里插入圖片描述

    • 捕獲/比較寄存器TIMx_CCR1/2/3/4
      在這里插入圖片描述

1. 通用定時(shí)器PWM輸出實(shí)驗(yàn)配置步驟

  1. 配置定時(shí)器基礎(chǔ)工作參數(shù)

    HAL_TIM_PWM_Init()
    
  2. 定時(shí)器PWM輸出MSP初始化

    HAL_TIM_PWM_MspInit()     
    
  3. 配置PWM模式/比較值等

    HAL_TIM_PWM_ConfigChannel()
    
  4. 使能輸出并啟動(dòng)計(jì)數(shù)器

    HAL_TIM_PWM_Start()
    
  5. 修改比較值控制占空比(可選)

    __HAL_TIM_SET_COMPARE()
    
  6. 使能通道預(yù)裝載(可選)

    __HAL_TIM_ENABLE_OCxPRELOAD()
    
  • 相關(guān)庫(kù)函數(shù)介紹

    函數(shù)主要寄存器主要功能
    HAL_TIM_PWM_Init()CR1、ARR、PSC初始化定時(shí)器基礎(chǔ)參數(shù)
    HAL_TIM_PWM_MspInit()存放NVIC、CLOCK、GPIO初始化代碼
    HAL_TIM_PWM_ConfigChannel()CCMRx、CCRx、CCER配置PWM模式、比較值、輸出極性等
    HAL_TIM_PWM_Start()CCER、CR1使能輸出比較并啟動(dòng)計(jì)數(shù)器
    __HAL_TIM_SET_COMPARE()CCRx修改比較值
    __HAL_TIM_ENABLE_OCxPRELOAD()CCER使能通道預(yù)裝載

2. 代碼實(shí)現(xiàn)

  • 功能:使用TM3通道2(由PB5復(fù)用)輸出PWM,PB5引腳連接了LED0,從而實(shí)現(xiàn)PWM輸出控制LED0亮度。

  • 程序流程:
    在這里插入圖片描述

  • 通用定時(shí)器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;                       //定時(shí)器選擇g_timx_pwm_chy_handle.Init.Prescaler = psc;                  //定時(shí)器分頻g_timx_pwm_chy_handle.Init.Period = arr;g_timx_pwm_chy_handle.Init.CounterMode = TIM_COUNTERMODE_UP; //定時(shí)器計(jì)數(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);   //配置定時(shí)器3通道2HAL_TIM_PWM_Start(&g_timx_pwm_chy_handle, TIM_CHANNEL_2);  //開啟PWM通道  
    }
    
  • 定時(shí)器輸出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庫(kù) */sys_stm32_clock_init(RCC_PLL_MUL9);     /* 設(shè)置時(shí)鐘, 72Mhz */delay_init(72);                         /* 延時(shí)初始化 */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);}
    }
    

四、通用定時(shí)器輸入捕獲實(shí)驗(yàn)

1. 輸入捕獲測(cè)量脈沖寬度

在這里插入圖片描述

測(cè)量方法:假定工作在遞增計(jì)數(shù)模式,首先設(shè)置通道x為上升沿捕獲,這樣在t1時(shí)刻上升沿到來時(shí),就會(huì)發(fā)生捕獲事件(打開捕獲中斷,捕獲事件發(fā)生時(shí)會(huì)觸發(fā)捕獲中斷)。在捕獲中斷里將計(jì)數(shù)器值清零,并設(shè)置通道x為下降沿捕獲,這樣t2時(shí)刻下降沿到來時(shí),就會(huì)發(fā)生捕獲事件和捕獲中斷。捕獲事件發(fā)生時(shí),計(jì)數(shù)器的值會(huì)被鎖存到捕獲/比較寄存器中。在捕獲中斷內(nèi),讀取捕獲/比較寄存器就可以獲取高電平脈沖時(shí)間,計(jì)數(shù)器計(jì)數(shù)的個(gè)數(shù),從而可以算出高電平脈沖的時(shí)間(假定計(jì)數(shù)器沒有溢出)。

但是在t1到t2時(shí)間段,定時(shí)器可能會(huì)產(chǎn)生N次溢出,需要對(duì)定時(shí)器溢出做相應(yīng)的處理,防止高電平太長(zhǎng),導(dǎo)致測(cè)量出錯(cuò)。在t1到t2時(shí)間內(nèi),假定定時(shí)器溢出N次,那么高電平時(shí)間內(nèi),計(jì)數(shù)器計(jì)數(shù)的個(gè)數(shù)計(jì)算方法為:N * (ARR + 1) + CCRx2,CCRx2表示t2時(shí)間點(diǎn),捕獲/比較寄存器的值。經(jīng)過計(jì)算得到高電平脈寬時(shí)間內(nèi)計(jì)數(shù)器計(jì)數(shù)個(gè)數(shù)后,用這個(gè)個(gè)數(shù)乘以計(jì)數(shù)器的計(jì)數(shù)周期,就可以得到高電平持續(xù)的時(shí)間。就是輸入捕獲測(cè)量高電平脈寬時(shí)間的整個(gè)過程。

STM32F103的定時(shí)器除了TM6和TM7,其他定時(shí)器都有輸入捕獲功能。輸入捕獲,簡(jiǎn)單的說就是通過檢測(cè)TIMx_CHy上的邊沿信號(hào),在邊沿信號(hào)發(fā)生跳變(比如上升沿/下降沿)時(shí),會(huì)發(fā)生捕獲事件,將當(dāng)前定時(shí)器的值(TIMx_CNT)鎖存到對(duì)應(yīng)通道的捕獲/比較寄存器(TIMx_CCRy)里,完成一次捕獲。同時(shí)還可以配置捕獲事件發(fā)生時(shí)是否觸發(fā)捕獲中斷/DMA。另外還要考慮測(cè)量的過程中是否可能發(fā)生定時(shí)器溢出,如果可能溢出,還要做溢出處理。

2. 輸入捕獲實(shí)驗(yàn)相關(guān)寄存器

  • 捕獲/比較模式寄存器1/2TIMx_CCMR1/2
    在這里插入圖片描述

  • 捕獲/比較使能寄存器TIMx_CCER
    在這里插入圖片描述

3. 通用定時(shí)器輸入捕獲配置步驟

  1. 配置定時(shí)器基礎(chǔ)工作參數(shù)

    HAL_TIM_IC_Init()
    
  2. 定時(shí)器輸入捕獲MSP初始化

    HAL_TIM_IC_MspInit() 
    
  3. 配置輸入通道映射、捕獲邊沿等

    HAL_TIM_IC_ConfigChannel()
    
  4. 設(shè)置優(yōu)先級(jí),使能中斷

    HAL_NVIC_SetPriority()
    HAL_NVIC_EnableIRQ()
    
  5. 使能定時(shí)器更新中斷

    __HAL_TIM_ENABLE_IT()
    
  6. 使能捕獲、捕獲中斷及計(jì)數(shù)器

    HAL_TIM_IC_Start_IT()
    
  7. 編寫中斷服務(wù)函數(shù)

    TIMx_IRQHandler()
    HAL_TIM_IRQHandler()
    
  8. 編寫更新中斷和捕獲回調(diào)函數(shù)

    HAL_TIM_PeriodElapsedCallback() 
    HAL_TIM_IC_CaptureCallback()
    
  • 相關(guān)函數(shù)的功能

    函數(shù)主要寄存器主要功能
    HAL_TIM_IC_Init()CR1、ARR、PSC初始化定時(shí)器基礎(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使能輸入捕獲、捕獲中斷并啟動(dòng)計(jì)數(shù)器
    HAL_TIM_IRQHandler()SR定時(shí)器中斷處理公用函數(shù),處理各種中斷
    HAL_TIM_PeriodElapsedCallback()定時(shí)器更新中斷回調(diào)函數(shù),由用戶重定義
    HAL_TIM_IC_CaptureCallback()定時(shí)器輸入捕獲回調(diào)函數(shù),由用戶重定義

4. 代碼實(shí)現(xiàn)

  • 功能

    1、使用TM5CH1來做輸入捕獲,捕獲PA0上的高電平脈寬,并將脈寬時(shí)間通過串口打印出來,然后通過按WKUP按鍵,模擬輸入高電平,例程中能測(cè)試的最長(zhǎng)高電平脈寬時(shí)間為: 4194303us.

    2、LED0閃爍指示程序運(yùn)行。

  • 通用定時(shí)器TIM5通道1輸入捕獲初始化函數(shù)

    void gtim_timx_cap_chy_init(uint16_t arr, uint16_t psc)
    {TIM_IC_InitTypeDef timx_ic_cap_chy = {0};//初始化定時(shí)器參數(shù) g_timx_cap_chy_handle.Instance = TIM5;        //定時(shí)器5的基地址g_timx_cap_chy_handle.Init.Prescaler = psc;   //定時(shí)器的分頻系數(shù)g_timx_cap_chy_handle.Init.CounterMode = TIM_COUNTERMODE_UP;   //遞增計(jì)數(shù)模式g_timx_cap_chy_handle.Init.Period = arr;    //自動(dòng)重裝載值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;           //不進(jìn)行分頻timx_ic_cap_chy.ICFilter = 0;                           //不進(jìn)行濾波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í)器輸入捕獲初始化函數(shù)

    void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim)
    {if(htim->Instance == TIM5)    //判斷定時(shí)器是否正確{GPIO_InitTypeDef gpio_init_struct;     //GPIO配置結(jié)構(gòu)體__HAL_RCC_TIM5_CLK_ENABLE();    //使能定時(shí)器時(shí)鐘__HAL_RCC_GPIOA_CLK_ENABLE();   //使能GPIOA時(shí)鐘gpio_init_struct.Pin = GPIO_PIN_0;              //配置引腳號(hào)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)先級(jí)HAL_NVIC_EnableIRQ(TIM5_IRQn);                  //使能TIM5中斷}
    }
    
  • 定時(shí)器TIM5中斷服務(wù)函數(shù)

    //定時(shí)器5中斷服務(wù)函數(shù)
    void TIM5_IRQHandler(void)
    {//HAL庫(kù)中斷公共處理函數(shù)HAL_TIM_IRQHandler(&g_timx_cap_chy_handle);
    }
    
  • 定時(shí)器輸入捕獲中斷處理回調(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)前計(jì)數(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);   //失能定時(shí)器5__HAL_TIM_SET_COUNTER(&g_timx_cap_chy_handle, 0);   //計(jì)數(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);   //使能定時(shí)器5}}}
    }
    
  • 定時(shí)器更新中斷回調(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)  //高電平時(shí)間過長(zhǎng){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í)器溢出次數(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庫(kù) */sys_stm32_clock_init(RCC_PLL_MUL9);     /* 設(shè)置時(shí)鐘, 72Mhz */delay_init(72);                         /* 延時(shí)初始化 */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;    //溢出時(shí)間總和temp += g_timxchy_cap_val;   //溢出的總時(shí)間printf("HIGH:%d us\r\n", temp);g_timxchy_cap_sta = 0;  //開啟下一次捕獲}t++;if(t > 20){t = 0;LED0_TOGGLE();}delay_ms(10);}
    }  
    
  • 主程序運(yùn)行流程
    在這里插入圖片描述

  • 中斷程序運(yùn)行流程
    在這里插入圖片描述

五、通用定時(shí)器脈沖計(jì)數(shù)實(shí)驗(yàn)

1. 脈沖計(jì)數(shù)框圖

脈沖計(jì)數(shù)實(shí)驗(yàn)使用的時(shí)鐘源是外部時(shí)鐘模式1,外部輸入引腳(TIx)作為定時(shí)器的時(shí)鐘源。實(shí)驗(yàn)中使用WK_UP按鍵按下產(chǎn)生的高電平脈沖作為定時(shí)器的計(jì)數(shù)器時(shí)鐘,每按下一次按鍵產(chǎn)生一次高電平脈沖,計(jì)數(shù)器的值加一。
在這里插入圖片描述

外部時(shí)鐘模式1的外部輸入引腳只能是通道1或者通道2對(duì)應(yīng)的IO,通道3或者通道4不可以。以通道1輸入為例,外部時(shí)鐘源信號(hào)通過通道1輸入后,TI1分別要經(jīng)過濾波器邊沿檢測(cè)器后,來到TI1FP1,被觸發(fā)輸入選擇器選擇為觸發(fā)源,接著來到從模式控制器。從模式選擇為外部時(shí)鐘模式1,這時(shí)候外部時(shí)鐘源信號(hào)就會(huì)到達(dá)時(shí)基單元的預(yù)分頻器,后面就是經(jīng)過分頻后就作為計(jì)數(shù)器的計(jì)數(shù)時(shí)鐘。

2. 相關(guān)寄存器

  • 捕獲/比較模式寄存器1/2TIMx_CCMR1/2

    與輸入捕獲配置相同

  • 捕獲/比較使能寄存器TIMx_CCER

    與輸入捕獲配置相同

  • 從模式控制寄存器TIMx_SMCR
    在這里插入圖片描述

3. 通用定時(shí)器脈沖計(jì)數(shù)配置步驟

  1. 配置定時(shí)器基礎(chǔ)工作參數(shù)

    HAL_TIM_IC_Init()
    
  2. 定時(shí)器輸入捕獲MSP初始化

    HAL_TIM_IC_MspInit()
    
  3. 配置定時(shí)器從模式等

    HAL_TIM_SlaveConfigSynchro()
    
  4. 使能輸入捕獲并啟動(dòng)計(jì)數(shù)器

    HAL_TIM_IC_Start()
    
  5. 獲取計(jì)數(shù)器的值

    __HAL_TIM_GET_COUNTER()
    
  6. 設(shè)置計(jì)數(shù)器的值

    __HAL_TIM_SET_COUNTER()
    
  • 相關(guān)庫(kù)函數(shù)

    函數(shù)主要寄存器主要功能
    HAL_TIM_IC_Init()CR1、ARR、PSC初始化定時(shí)器基礎(chǔ)參數(shù)
    HAL_TIM_IC_MspInit()存放NVIC、CLOCK、GPIO初始化代碼
    HAL_TIM_SlaveConfigSynchro()SMCR、CCMRx、CCER配置定時(shí)器從模式、觸發(fā)選擇、分頻、濾波等
    HAL_TIM_IC_Start()CCER、CR1使能輸入捕獲、啟動(dòng)計(jì)數(shù)器
    __HAL_TIM_GET_COUNTER()CNT獲取計(jì)數(shù)器當(dāng)前值
    __HAL_TIM_SET_COUNTER()CNT設(shè)置計(jì)數(shù)器的值

4. 代碼實(shí)現(xiàn)

  • 功能

    使用TM2CH1做輸入捕獲,我們將捕獲PA0上的高電平脈寬,并將脈寬進(jìn)行計(jì)數(shù),通過串口打印出來。大家可以通過按WKUP按鍵,輸入高電平脈沖,通過按KEY0重設(shè)當(dāng)前計(jì)數(shù)。 LED0閃爍,提示程序運(yùn)行。

  • 通用定時(shí)器脈沖計(jì)數(shù)初始化函數(shù)

    void gtim_timx_cnt_chy_init(uint16_t psc)
    {TIM_SlaveConfigTypeDef timx_slave_config = {0};g_timx_cnt_chy_handle.Instance = TIM2;                       //定時(shí)器選擇g_timx_cnt_chy_handle.Init.Prescaler = psc;                  //定時(shí)器分頻g_timx_cnt_chy_handle.Init.Period = 65535;g_timx_cnt_chy_handle.Init.CounterMode = TIM_COUNTERMODE_UP; //定時(shí)器計(jì)數(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;  //存儲(chǔ)當(dāng)前的計(jì)數(shù)值uint16_t oldcnt;   //存儲(chǔ)舊的計(jì)數(shù)值uint8_t key;      //按鍵的鍵值uint8_t t;        //延時(shí)時(shí)間HAL_Init();                             /* 初始化HAL庫(kù) */sys_stm32_clock_init(RCC_PLL_MUL9);     /* 設(shè)置時(shí)鐘, 72Mhz */delay_init(72);                         /* 延時(shí)初始化 */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);}
    }  
    

六、高級(jí)定時(shí)器輸出指定個(gè)數(shù)PWM實(shí)驗(yàn)

1. 高級(jí)定時(shí)器框圖

在這里插入圖片描述

  1. 重復(fù)計(jì)數(shù)器

    在基本定時(shí)器和通用定時(shí)器中,定時(shí)器發(fā)生上溢或者下溢時(shí),會(huì)直接生成更新事件。但有重復(fù)計(jì)數(shù)器的定時(shí)器并不完全這樣,在定時(shí)器每次發(fā)生上溢或下溢時(shí),重復(fù)計(jì)數(shù)器的值會(huì)減一,當(dāng)重復(fù)計(jì)數(shù)器的值為0時(shí),再發(fā)生一次上溢或者下溢才會(huì)生成定時(shí)器更新事件。如果我們?cè)O(shè)置重復(fù)計(jì)數(shù)器寄存器的RCR的值為N,那么更新事件將在定時(shí)器發(fā)生N+1次上溢或下溢時(shí)發(fā)生。

  2. 輸出比較

    與通用定時(shí)器相比,高級(jí)定時(shí)器多了帶死區(qū)控制的互補(bǔ)輸出功能。通道1、2、3都有互補(bǔ)輸出通道,DTG死區(qū)發(fā)生器,死區(qū)時(shí)間由DTG[7:0]位來配置。如果不使用互補(bǔ)通道和死區(qū)時(shí)間控制,那么高級(jí)定時(shí)器TIM1和TIM8和通用定時(shí)器的輸出比較部分使用方法基本一樣,只是要注意MOE位得置1定時(shí)器才能輸出。

  3. 斷路功能

    斷路功能也稱剎車功能,一般用于控制電機(jī)的剎車。F1系列有一個(gè)斷路通道,斷路源可以是剎車輸入引腳TIMx_BKIN),也可以是一個(gè)時(shí)鐘失敗事件。時(shí)鐘失敗事件由復(fù)位時(shí)鐘控制器中的時(shí)鐘安全系統(tǒng)產(chǎn)生。系統(tǒng)復(fù)位后,斷路功能默認(rèn)被禁止,MOE位為低。

2. 重復(fù)計(jì)數(shù)器特性

在這里插入圖片描述

  1. 計(jì)數(shù)器每次上溢或下溢都能使重復(fù)計(jì)數(shù)器減1,減到0時(shí),再發(fā)生一次溢出就會(huì)產(chǎn)生更新事件。

  2. 如果設(shè)置RCR為N,更新事件將在N+1次溢出時(shí)發(fā)生。

3. 相關(guān)寄存器

  • 控制寄存器1TIMx_CR1
    在這里插入圖片描述

  • 捕獲/比較模式寄存器1/2TIMx_CCMR1/2
    在這里插入圖片描述

  • 捕獲/比較使能寄存器TIMx_CCER
    在這里插入圖片描述

  • 事件產(chǎn)生寄存器TIMx_EGR
    在這里插入圖片描述

  • 重復(fù)計(jì)數(shù)器寄存器TIMx_RCR
    在這里插入圖片描述

  • 捕獲/比較寄存器1/2/3/4TIMx_CCR1/2/3/4
    在這里插入圖片描述

  • 斷路和死區(qū)寄存器TIMx_BDTR
    在這里插入圖片描述

4. 高級(jí)定時(shí)器輸出指定個(gè)數(shù)PWM實(shí)驗(yàn)配置步驟

  1. 配置定時(shí)器基礎(chǔ)工作參數(shù)

    HAL_TIM_PWM_Init()
    
  2. 定時(shí)器PWM輸出MSP初始化

    HAL_TIM_PWM_MspInit()   
    
  3. 配置PWM模式/比較值等

    HAL_TIM_PWM_ConfigChannel()
    
  4. 設(shè)置優(yōu)先級(jí),使能中斷

    HAL_NVIC_SetPriority()
    HAL_NVIC_EnableIRQ()
    
  5. 使能定時(shí)器更新中斷

    __HAL_TIM_ENABLE_IT()
    
  6. 使能輸出、主輸出、計(jì)數(shù)器

    HAL_TIM_PWM_Start()
    
  7. 編寫中斷服務(wù)函數(shù)

    TIMx_IRQHandler()
    HAL_TIM_IRQHandler()
    
  8. 編寫更新中斷回調(diào)函數(shù)

    HAL_TIM_PeriodElapsedCallback()
    
  • 具體函數(shù)功能

    函數(shù)主要寄存器主要功能
    HAL_TIM_PWM_Init()CR1、ARR、PSC初始化定時(shí)器基礎(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使能輸出、主輸出、啟動(dòng)計(jì)數(shù)器
    HAL_TIM_IRQHandler()SR定時(shí)器中斷處理公用函數(shù),處理各種中斷
    HAL_TIM_PeriodElapsedCallback()定時(shí)器更新中斷回調(diào)函數(shù),由用戶重定義
    HAL_TIM_GenerateEvent()EGR通過軟件產(chǎn)生事件
    __HAL_TIM_ENABLE()CR1啟動(dòng)計(jì)數(shù)器

5. 代碼實(shí)現(xiàn)

  • 功能:

    通過TIM8CH1(由PC6復(fù)用)輸出PWM,然后為了指示PWM的輸出情況,我們用杜邦線將PC6和PE5引腳的排針連接起來,從而實(shí)現(xiàn)PWM輸出控制LED1(硬件已連接在PPE5引腳上)的亮滅。注意的點(diǎn)是:PE5要設(shè)置成浮空輸入,避免引腳沖突,我們?cè)趍ain函數(shù)中設(shè)置好了,請(qǐng)看源碼。上電默認(rèn)輸出5個(gè)PWM波,連接好杜邦線后可以看見LED1亮滅五次。之后按一下按鍵KEYO,就會(huì)輸出5個(gè)PWM波控制LED1亮滅五次。LED0閃爍提示系統(tǒng)正在運(yùn)行。

  • 高級(jí)定時(shí)器輸出指定個(gè)數(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;  //向上計(jì)數(shù)模式g_timx_npwm_chy_handle.Init.Period = arr;g_timx_npwm_chy_handle.Init.RepetitionCounter = 0;  //重復(fù)計(jì)數(shù)器初始值g_timx_npwm_chy_handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; /*使能TIMx_ARR進(jìn)行緩沖 */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);  //進(jìn)行初始化__HAL_TIM_ENABLE_IT(&g_timx_npwm_chy_handle, TIM_IT_UPDATE);  //允許更新中斷HAL_TIM_PWM_Start(&g_timx_npwm_chy_handle, TIM_CHANNEL_1);    //開啟對(duì)應(yīng)的PWM通道
    }
    
  • 高級(jí)定時(shí)器輸出指定個(gè)數(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);}
    }
    
  • 高級(jí)定時(shí)器設(shè)置PWM個(gè)數(shù)函數(shù)

    void atim_timx_npwm_chy_set(uint8_t npwm)
    {if(npwm == 0) return;g_npwm_remain = npwm;   //保存脈沖個(gè)數(shù)HAL_TIM_GenerateEvent(&g_timx_npwm_chy_handle, TIM_EVENTSOURCE_UPDATE);  //產(chǎn)生一次軟件更新事件,在中斷里面處理脈沖輸出__HAL_TIM_ENABLE(&g_timx_npwm_chy_handle);   //使能定時(shí)器TIM8
    }
    
  • 定時(shí)器8中斷服務(wù)函數(shù)

    void TIM8_UP_IRQHandler(void)
    {HAL_TIM_IRQHandler(&g_timx_npwm_chy_handle);
    }
    
  • 定時(shí)器更新中斷回調(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庫(kù) */sys_stm32_clock_init(RCC_PLL_MUL9);     /* 設(shè)置時(shí)鐘, 72Mhz */delay_init(72);                         /* 延時(shí)初始化 */
    //    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);}
    }  
    

七、高級(jí)定時(shí)器輸出比較模式實(shí)驗(yàn)

1. 輸出比較模式功能

輸出比較模式下翻轉(zhuǎn)功能作用是:當(dāng)計(jì)數(shù)器的值等于捕獲/比較寄存器影子寄存器的值時(shí), OC1REF發(fā)生翻轉(zhuǎn),進(jìn)而控制通道輸出(OCx)翻轉(zhuǎn)。通過翻轉(zhuǎn)功能實(shí)現(xiàn)輸出PWM的具體原理如下:PWM頻率自動(dòng)重載寄存器(TIMx_ARR)的值決定,在這個(gè)過程中,只要自動(dòng)重載寄存器的值不變,那么PWM占空比就固定為50%??梢酝ㄟ^捕獲/比較寄存器(TIMx_CCRx)的值改變PWM的相位。
在這里插入圖片描述

2. 相關(guān)寄存器

  • 控制寄存器1TIMx_CR1
    在這里插入圖片描述

  • 捕獲/比較模式寄存器1/2TIMx_CCMR1/2
    在這里插入圖片描述

  • 捕獲/比較使能寄存器TIMx_CCER
    在這里插入圖片描述

  • 捕獲/比較寄存器1/2/3/4TIMx_CCR1/2/3/4
    在這里插入圖片描述

  • TIM1/TIM8斷路和死區(qū)寄存器TIMx_BDTR
    在這里插入圖片描述

3. 高級(jí)定時(shí)器輸出比較模式實(shí)驗(yàn)配置步驟

  1. 配置定時(shí)器基礎(chǔ)工作參數(shù)

    HAL_TIM_OC_Init()
    
  2. 定時(shí)器輸出比較MSP初始化

    HAL_TIM_OC_MspInit() 
    
  3. 配置輸出比較模式等

    HAL_TIM_OC_ConfigChannel()
    
  4. 使能通道預(yù)裝載

    __HAL_TIM_ENABLE_OCxPRELOAD()
    
  5. 使能輸出、主輸出、計(jì)數(shù)器

    HAL_TIM_OC_Start()
    
  6. 修改捕獲/比較寄存器的值

    __HAL_TIM_SET_COMPARE()
    
  • 具體函數(shù)功能

    函數(shù)主要寄存器主要功能
    HAL_TIM_OC_Init()CR1、ARR、PSC初始化定時(shí)器基礎(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使能輸出比較、主輸出、啟動(dòng)計(jì)數(shù)器
    __HAL_TIM_SET_COMPARE()CCRx修改捕獲/比較寄存器的值

4. 代碼實(shí)現(xiàn)

  • 功能:

    使用輸出比較模式的翻轉(zhuǎn)功能,通過定時(shí)器8的4路通道輸出占空比固定為50%、相位分別是25%、50%、75%和100%的PWM。

  • 高級(jí)定時(shí)器輸出比較初始化

    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;  //向上計(jì)數(shù)模式g_timx_comp_pwm_handle.Init.Period = arr;g_timx_comp_pwm_handle.Init.RepetitionCounter = 0;  //重復(fù)計(jì)數(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);//使能輸出、主輸出、計(jì)數(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);
    }
    
  • 定時(shí)器輸出比較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庫(kù) */sys_stm32_clock_init(RCC_PLL_MUL9);     /* 設(shè)置時(shí)鐘, 72Mhz */delay_init(72);                         /* 延時(shí)初始化 */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);}
    }  
    
  • 程序運(yùn)行結(jié)果
    在這里插入圖片描述

八、高級(jí)定時(shí)器互補(bǔ)輸出帶死區(qū)控制實(shí)驗(yàn)

1. 互補(bǔ)死區(qū)的理解

  • 互補(bǔ)輸出
    在這里插入圖片描述

? CH1輸出黃色的PWM,互補(bǔ)通道CH1N輸出綠色的PWM,兩個(gè)信號(hào)恰好是相反的,CH1的PWM為高電平期 間,CH1N的PWM則是低電平,反之亦然,這就是互補(bǔ)輸出

  • 帶死區(qū)控制的互補(bǔ)輸出
    在這里插入圖片描述

    CH1輸出的PWM和CH1N輸出的PWM在高低電平轉(zhuǎn)換期間,插入了一段時(shí)間才實(shí)現(xiàn)互補(bǔ)輸出。這段時(shí)間稱為死區(qū)時(shí)間。上圖箭頭所指的區(qū)域就是死區(qū)時(shí)間,兩段時(shí)間相同。

  • 死區(qū)互補(bǔ)控制H橋
    在這里插入圖片描述

    • 當(dāng)Q1和Q4導(dǎo)通,電流的方向是從左到右;當(dāng)Q2和Q3導(dǎo)通,電流的方向是從右到左。
    • 因?yàn)樵骷哂醒訒r(shí)特性,控制信號(hào)經(jīng)過OC1傳輸?shù)诫姍C(jī)需要一定的時(shí)間。由于元器件的特性,就會(huì)直接導(dǎo)致直接使用互補(bǔ)輸出信號(hào)驅(qū)動(dòng)H橋存在短路現(xiàn)象。為了避免這種情況,就有了帶死區(qū)控制的互補(bǔ)輸出來驅(qū)動(dòng)H橋。用戶必須根據(jù)與輸出相連接的器件及其特性(電平轉(zhuǎn)換器的固有延遲、開關(guān)器件產(chǎn)生的延遲)來調(diào)整死區(qū)時(shí)間。
  • 死區(qū)時(shí)間計(jì)算
    在這里插入圖片描述

2. 相關(guān)寄存器

  • 控制寄存器1TIMx_CR1
    在這里插入圖片描述

  • 捕獲/比較模式寄存器1/2TIMx_CCMR1/2
    在這里插入圖片描述

  • 捕獲/比較使能寄存器TIMx_CCER
    在這里插入圖片描述

  • 捕獲/比較寄存器1/2/3/4TIMx_CCR1/2/3/4
    在這里插入圖片描述

  • TIM1/TIM8斷路和死區(qū)寄存器TIMx_BDTR
    在這里插入圖片描述

    對(duì)應(yīng)的結(jié)構(gòu)框圖
    在這里插入圖片描述

  • 剎車斷路功能
    在這里插入圖片描述

    發(fā)生剎車后:
    在這里插入圖片描述

3. 高級(jí)定時(shí)器互補(bǔ)輸出帶死區(qū)控制實(shí)驗(yàn)配置步驟

  1. 配置定時(shí)器基礎(chǔ)工作參數(shù)

    HAL_TIM_PWM_Init()
    
  2. 定時(shí)器PWM輸出MSP初始化

    HAL_TIM_PWM_MspInit()  
    
  3. 配置PWM模式/比較值等

    HAL_TIM_PWM_ConfigChannel()
    
  4. 配置剎車功能、死區(qū)時(shí)間等

    HAL_TIMEx_ConfigBreakDeadTime()
    
  5. 使能輸出、主輸出、計(jì)數(shù)器

    HAL_TIM_PWM_Start()
    
  6. 使能互補(bǔ)輸出、主輸出、計(jì)數(shù)器

    HAL_TIMEx_PWMN_Start()
    
  • 相關(guān)函數(shù)功能

    函數(shù)主要寄存器主要功能
    HAL_TIM_PWM_Init()CR1、ARR、PSC初始化定時(shí)器基礎(chǔ)參數(shù)
    HAL_TIM_PWM_MspInit()存放NVIC、CLOCK、GPIO初始化代碼
    HAL_TIM_PWM_ConfigChannel()CCMRx、CCRx、CCER配置PWM模式、比較值、輸出極性等
    HAL_TIMEx_ConfigBreakDeadTime()BDTR配置剎車功能、死區(qū)時(shí)間等
    HAL_TIM_PWM_Start()CCER、CR1使能輸出、主輸出、啟動(dòng)計(jì)數(shù)器
    HAL_TIMEx_PWMN_Start()CCER、CR1使能互補(bǔ)輸出、主輸出、啟動(dòng)計(jì)數(shù)器

4. 代碼實(shí)現(xiàn)

  • 功能:

    1. 利用TIM1_CH1(PE9)輸出70%占空比的PWM波,它的互補(bǔ)輸出通道(PE8)則是輸出30%占空比的PWM波。
    2. 剎車功能,當(dāng)給剎車輸入引腳(PE15)輸入高電平時(shí),進(jìn)行剎車,即PE8和PE9停止輸出PWM波。
    3. LED0閃爍指示程序運(yùn)行。
  • 高級(jí)定時(shí)器互補(bǔ)輸出初始化函數(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;                       //定時(shí)器選擇g_timx_cplm_pwm_handle.Init.Prescaler = psc;                  //定時(shí)器分頻g_timx_cplm_pwm_handle.Init.Period = arr;g_timx_cplm_pwm_handle.Init.CounterMode = TIM_COUNTERMODE_UP; //定時(shí)器計(jì)數(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;           //運(yùn)行模式下的關(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; //自動(dòng)恢復(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);    //啟動(dòng)定時(shí)器的正常輸出HAL_TIMEx_PWMN_Start(&g_timx_cplm_pwm_handle, TIM_CHANNEL_1); //啟動(dòng)定時(shí)器的互補(bǔ)輸出
    }
    
  • 定時(shí)器設(shè)置輸出比較值死區(qū)時(shí)間

    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);//單獨(dú)進(jìn)行死區(qū)時(shí)間的設(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庫(kù) */sys_stm32_clock_init(RCC_PLL_MUL9);     /* 設(shè)置時(shí)鐘, 72Mhz */delay_init(72);                         /* 延時(shí)初始化 */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);}
    }  
    
  • 程序運(yùn)行流程
    在這里插入圖片描述

  • 程序運(yùn)行結(jié)果
    在這里插入圖片描述

九、高級(jí)定時(shí)器PWM輸入模式實(shí)驗(yàn)

1. PWM輸入工作原理

在這里插入圖片描述

  1. 確定定時(shí)器的時(shí)鐘源:本代碼使用內(nèi)部時(shí)鐘(CK_INT),時(shí)鐘頻率為72MHz,計(jì)數(shù)頻率確定了測(cè)量精度。
  2. 確定PWM輸入的通道:PWM輸入模式下測(cè)量PWM,PWM信號(hào)輸入只能從通道1或通道2輸入。
  3. 確定IC1和IC2的捕獲邊沿:以通道 1(CH1)輸入 PWM 為例,一般設(shè)置 IC1 捕獲邊沿為上升沿捕獲,IC2 捕獲邊沿為下降沿捕獲。
  4. 選擇觸發(fā)輸入信號(hào):選擇TI1FP1或TI2FP2。
  5. 從模式選擇:復(fù)位模式,在出現(xiàn)所選觸發(fā)輸入(TRGI)上升沿時(shí),重新初始化計(jì)數(shù)器并生成一個(gè)寄存器更新事件。
  6. 讀取一個(gè)PWM周期內(nèi)計(jì)數(shù)器的計(jì)數(shù)個(gè)數(shù),以及高電平期間計(jì)數(shù)個(gè)數(shù),再結(jié)合計(jì)數(shù)器的計(jì)數(shù)周期,最終通過計(jì)算得到輸入的PWM周期和占空比等參數(shù)。

2. 輸入模式時(shí)序圖

在這里插入圖片描述

假設(shè)計(jì)數(shù)器的計(jì)數(shù)頻率是72MHz,那我們就可以計(jì)算出PWM的周期、頻率和占空比等參數(shù)。由計(jì)數(shù)器的計(jì)數(shù)頻率為72Hz,可以得到計(jì)數(shù)器計(jì)一個(gè)數(shù)的時(shí)間是13.8ns(即測(cè)量的精度是13.8ns)。知道了測(cè)量精度,再來計(jì)算PWM的周期,PWM周期=(4+1)*(1/72000000)=69.4ns,那么PWM的頻率就是14.4MHz。占空比= (2+1)/(4+1)=3/5(即占空比為60%)。

3. 相關(guān)寄存器

  • 從模式控制寄存器TIMx_SMCR
    在這里插入圖片描述

  • 捕獲/比較模式寄存器1/2TIMx_CCMR1/2
    在這里插入圖片描述

  • 捕獲/比較使能寄存器TIMx_CCER
    在這里插入圖片描述

  • 捕獲/比較寄存器1/2/3/4TIMx_CCR1/2/3/4
    在這里插入圖片描述

  • DMA中斷使能寄存器TIMx_DIER
    在這里插入圖片描述

4. 高級(jí)定時(shí)器PWM輸入模式實(shí)驗(yàn)配置步驟

  1. 配置定時(shí)器基礎(chǔ)工作參數(shù)

    HAL_TIM_IC_Init()
    
  2. 定時(shí)器捕獲輸入MSP初始化

    HAL_TIM_IC_MspInit()
    
  3. 配置IC1/2映射、捕獲邊沿等

    HAL_TIM_IC_ConfigChannel()
    
  4. 配置從模式,觸發(fā)源等

    HAL_TIM_SlaveConfigSynchro()
    
  5. 設(shè)置優(yōu)先級(jí),使能中斷

    HAL_NVIC_SetPriority() 
    HAL_NVIC_EnableIRQ()
    
  6. 使能捕獲、捕獲中斷及計(jì)數(shù)器

    HAL_TIM_IC_Start_IT() 
    HAL_TIM_IC_Start()
    
  7. 編寫中斷服務(wù)函數(shù)

    TIMx_IRQHandler()
    
  8. 編寫輸入捕獲回調(diào)函數(shù)

    HAL_TIM_IC_CaptureCallback()
    
  • 函數(shù)具體功能

    函數(shù)主要寄存器主要功能
    HAL_TIM_IC_Init()CR1、ARR、PSC初始化定時(shí)器基礎(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使能輸入捕獲、捕獲中斷并啟動(dòng)計(jì)數(shù)器
    HAL_TIM_IRQHandler()SR定時(shí)器中斷處理公用函數(shù),處理各種中斷
    HAL_TIM_IC_CaptureCallback()定時(shí)器輸入捕獲回調(diào)函數(shù),由用戶重定義

4. 代碼實(shí)現(xiàn)

  • 功能:

    首先通過TM3_CH2(PB5)輸出PWM波。然后把PB5輸出的PWM波用杜邦線接入PC6(定時(shí)器8通道1),最后通過串口打印PWM波的脈寬和頻率等信息。通過LED1閃爍來提示程序正在運(yùn)行。

  • 通用定時(shí)器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);
    }
    
  • 定時(shí)器輸出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;                        /* 定時(shí)器8 */g_timx_pwmin_chy_handle.Init.Prescaler = 0;                     /* 定時(shí)器預(yù)分頻系數(shù) */g_timx_pwmin_chy_handle.Init.CounterMode = TIM_COUNTERMODE_UP;  /* 遞增計(jì)數(shù)模式 */g_timx_pwmin_chy_handle.Init.Period = 65535;                    /* 自動(dòng)重裝載值 */HAL_TIM_IC_Init(&g_timx_pwmin_chy_handle);/* 從模式配置,IT1觸發(fā)更新 */slave_config.SlaveMode = TIM_SLAVEMODE_RESET;                   /* 從模式:復(fù)位模式 */slave_config.InputTrigger = TIM_TS_TI1FP1;                      /* 定時(shí)器輸入觸發(fā)源:TI1FP1 */slave_config.TriggerPolarity = TIM_TRIGGERPOLARITY_RISING;      /* 上升沿檢測(cè) */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;            /* 上升沿檢測(cè) */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;           /* 下降沿檢測(cè) */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);
    }
    
  • 定時(shí)器輸入捕獲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有獨(dú)立的輸入捕獲中斷服務(wù)函數(shù) */HAL_NVIC_SetPriority(TIM8_CC_IRQn, 1, 3);HAL_NVIC_EnableIRQ(TIM8_CC_IRQn);}
    }
    
  • 定時(shí)器8輸入捕獲中斷服務(wù)函數(shù)

    void TIM8_CC_IRQHandler(void)
    {HAL_TIM_IRQHandler(&g_timx_pwmin_chy_handle); /* 定時(shí)器共用處理函數(shù) */
    }
    
  • PWM輸入模式重新啟動(dòng)捕獲函數(shù)

    void atim_timx_pwmin_chy_restart(void)
    {sys_intx_disable();                     /* 關(guān)閉中斷 */g_timxchy_pwmin_sta = 0;                /* 清零狀態(tài),重新開始檢測(cè) */g_timxchy_pwmin_hval=0;g_timxchy_pwmin_cval=0;sys_intx_enable();                      /* 打開中斷 */
    }
    
  • 定時(shí)器輸入捕獲中斷處理回調(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庫(kù) */sys_stm32_clock_init(RCC_PLL_MUL9);         /* 設(shè)置時(shí)鐘, 72Mhz */delay_init(72);                             /* 延時(shí)初始化 */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,提示程序運(yùn)行 */{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采樣時(shí)鐘周期時(shí)間 */ ht = g_timxchy_pwmin_hval * tpsc;                   /* 計(jì)算高電平時(shí)間 */ct = g_timxchy_pwmin_cval * tpsc;                   /* 計(jì)算周期長(zhǎng)度 */f = (1 / ct) * 1000000;                             /* 計(jì)算頻率 */printf("PWM Hight time:%.3fus\r\n", ht);            /* 打印高電平脈寬長(zhǎng)度 */printf("PWM Cycle time:%.3fus\r\n", ct);            /* 打印周期時(shí)間長(zhǎng)度 */printf("PWM Frequency :%.3fHz\r\n", f);             /* 打印頻率 */ atim_timx_pwmin_chy_restart(); /* 重啟PWM輸入檢測(cè) */} LED1_TOGGLE();  /* LED1(GREEN)閃爍 */t = 0;}}
    }
    

聲明:資料來源(戰(zhàn)艦STM32F103ZET6開發(fā)板資源包)

  1. Cortex-M3權(quán)威指南(中文).pdf
  2. STM32F10xxx參考手冊(cè)_V10(中文版).pdf
  3. STM32F103 戰(zhàn)艦開發(fā)指南V1.3.pdf
  4. STM32F103ZET6(中文版).pdf
  5. 戰(zhàn)艦V4 硬件參考手冊(cè)_V1.0.pdf
http://www.risenshineclean.com/news/39806.html

相關(guān)文章:

  • 順義做網(wǎng)站公司百度指數(shù)的網(wǎng)址
  • 哪家公司做網(wǎng)站好新區(qū)seo整站優(yōu)化公司
  • 如何拿qq空間做網(wǎng)站推廣搜索怎么選關(guān)鍵詞
  • wordpress創(chuàng)建單頁(yè)seo優(yōu)化方法有哪些
  • 哈爾濱網(wǎng)站建設(shè)推廣公司網(wǎng)站備案信息查詢
  • 廣州做網(wǎng)站比較有名的公司網(wǎng)站seo檢測(cè)工具
  • wordpress 網(wǎng)頁(yè)排版錯(cuò)誤寧波seo鏈接優(yōu)化
  • wordpress排行榜模板seo排名點(diǎn)擊軟件推薦
  • 哪些網(wǎng)站可以用來做百科參考西安關(guān)鍵詞優(yōu)化軟件
  • 醫(yī)院網(wǎng)站建設(shè)目的萬(wàn)網(wǎng)域名查詢接口
  • 長(zhǎng)沙網(wǎng)站建設(shè)開發(fā)seo百度網(wǎng)站排名軟件
  • 西安網(wǎng)站建設(shè)陜icp投廣告哪個(gè)平臺(tái)好
  • 網(wǎng)站源碼分享網(wǎng)google服務(wù)框架
  • 怎樣建俄文網(wǎng)站濟(jì)南網(wǎng)站推廣優(yōu)化
  • 本地手機(jī)網(wǎng)站建設(shè)灰色行業(yè)推廣平臺(tái)
  • wordpress 插入音樂浙江seo公司
  • 優(yōu)化外包顧問青島seo網(wǎng)站排名優(yōu)化
  • 深圳網(wǎng)站seo教程簡(jiǎn)述提升關(guān)鍵詞排名的方法
  • 網(wǎng)站備案負(fù)責(zé)人幕布照無憂seo博客
  • 成都企業(yè)模板建站線上銷售方案
  • 阜康網(wǎng)站建設(shè)軟件推廣方案經(jīng)典范文
  • 濟(jì)南做網(wǎng)站0531soso做網(wǎng)站多少錢一年
  • 武漢建設(shè)信息網(wǎng)站嘉興網(wǎng)站建設(shè)制作
  • 壽光市住房和建設(shè)局網(wǎng)站地推app推廣賺傭金
  • 用自己的照片做頭像的網(wǎng)站aso優(yōu)化師工作很賺錢嗎
  • 湖北省住房和城鄉(xiāng)建設(shè)廳網(wǎng)站的公示公告考研培訓(xùn)班集訓(xùn)營(yíng)
  • 常州市網(wǎng)站建設(shè)seo單頁(yè)面優(yōu)化
  • 做網(wǎng)站的開題報(bào)告怎么寫百度應(yīng)用商店app下載安裝
  • 建設(shè)網(wǎng)站建站公司軟件外包公司有前途嗎
  • 網(wǎng)站 php .net佛山網(wǎng)站建設(shè)排名