系統(tǒng)滴答定時(shí)器一般用來提供“心跳”作用,而STM32定時(shí)器最基本功能也是定時(shí),可以設(shè)置不同時(shí)間長(zhǎng)度的定時(shí)。定時(shí)器除了最基本的定時(shí)功能外,定時(shí)器與GPIO有掛鉤使得它可以發(fā)揮強(qiáng)大的作用,比如可以輸出不同頻率、不同占空比的方波信號(hào)、PWM信號(hào),同時(shí)做為輸入捕獲功能時(shí),可以測(cè)量脈沖寬度、實(shí)現(xiàn)電容按鍵檢測(cè)等等。
一、輸入捕獲概念
輸入捕獲模式可以用來測(cè)量脈沖寬度或者測(cè)量頻率。STM32 的定時(shí)器,除了 TIM6 和 TIM7,其他定時(shí)器都有輸入捕獲功能。 STM32的輸入捕獲,簡(jiǎn)單的說就是通過檢測(cè) TIMx_CHx (定時(shí)器X的通道X)上的 邊沿信號(hào),在邊沿信號(hào)發(fā)生跳變(比如上升沿/下降沿)的時(shí)候,將當(dāng)前定時(shí)器的值(TIMx_CNT) 存放到對(duì)應(yīng)的通道的捕獲/比較寄存器(TIMx_CCRx)里面,完成一次捕獲。同時(shí)還可以配置捕獲時(shí)是否觸發(fā)中斷/DMA 等。
本文使用 TIM2_CH1 來捕獲高電平脈寬,也就是要先設(shè)置輸入捕獲為上升沿檢測(cè),記錄發(fā)生上升沿的時(shí)候 TIM2_CNT 的值。然后配置捕獲信號(hào)為下降沿捕獲,當(dāng)下降沿到來時(shí),發(fā)生捕獲,并記錄此時(shí)的 TIM2_CNT 值。這樣,前后兩次 TIM2_CNT 之差,就是高電平的脈寬,同時(shí) TIM2 的計(jì)數(shù)頻率我們是知道的,從而可以計(jì)算出高電平脈寬的準(zhǔn)確時(shí)間。
至于為什么TIM2_CH1來測(cè)量WK_UP的脈寬。。看圖:
顯然,TIM_CH1是連在PA0上的。
二、輸入捕獲流程:
例如,要配置向上計(jì)數(shù)器在T12輸入端的上升沿計(jì)數(shù),使用下列步驟:
1、配置TIMx_CCMR1寄存器CC2S=’01’,配置通道2檢測(cè)TI2輸入的上升沿
2、配置TIMx_CCMR1寄存器的IC2F[3:0],選擇輸入濾波器帶寬(如果不需要濾波器,保持 IC2F=0000即無濾波器,以fDTS 采樣)
3、配置TIMx_CCER寄存器的CC2P=’0’,選定上升沿極性
4、 配置TIMx_SMCR寄存器的SMS=’111’,選擇定時(shí)器外部時(shí)鐘模式1
5、 配置TIMx_SMCR寄存器中的TS=’110’,選定TI2作為觸發(fā)輸入
6、 設(shè)置TIMx_CR1寄存器的CEN=’1’,啟動(dòng)計(jì)數(shù)器
當(dāng)上升沿出現(xiàn)在TI2,計(jì)數(shù)器計(jì)數(shù)一次,且TIF標(biāo)志被設(shè)置。 在TI2的上升沿和計(jì)數(shù)器實(shí)際時(shí)鐘之間的延時(shí),取決于在TI2輸入端的重新同步電路。
三、輸入捕獲程序設(shè)計(jì)步驟:
1)開啟 TIM5 時(shí)鐘和 GPIOA 時(shí)鐘,配置 PA0 為下拉輸入。
要使用 TIM5,我們必須先開啟 TIM5 的時(shí)鐘。這里我們還要配置 PA0 為下拉輸入,因?yàn)?我們要捕獲 TIM5_CH1 上面的高電平脈寬,而 TIM5_CH1 是連接在 PA0 上面的。所以要進(jìn)行GPIO_Init();
2)初始化 TIM5,設(shè)置 TIM5 的 ARR 和 PSC。
在開啟了 TIM5 的時(shí)鐘之后,我們要設(shè)置 ARR 和 PSC 兩個(gè)寄存器的值來設(shè)置輸入捕獲的自動(dòng)重裝載值和計(jì)數(shù)頻率。這在庫函數(shù)中是通過 TIM_TimeBaseInit 函數(shù)實(shí)現(xiàn)的
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period = arr; //設(shè)定計(jì)數(shù)器自動(dòng)重裝值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //設(shè)置預(yù)分頻值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//TIM 向上計(jì)數(shù)模式
TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure); //根據(jù)指定的參數(shù)初始化 Tim5
3)設(shè)置 TIM5 的輸入比較參數(shù),開啟輸入捕獲
輸入比較參數(shù)的設(shè)置包括映射關(guān)系,濾波,分頻以及捕獲方式等。這里我們需要設(shè)置通道 1 為輸入模式,且 IC1 映射到 TI1(通道 1)上面,并且不使用濾波(提高響應(yīng)速度)器,上升沿捕 獲。庫函數(shù)是通過 TIM_ICInit 函數(shù)來初始化輸入比較參數(shù)的:
void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);
同樣,我們來看看參數(shù)設(shè)置結(jié)構(gòu)體 TIM_ICInitTypeDef 的定義:
typedef struct
{
uint16_t TIM_Channel; //用來設(shè)置通道
uint16_t TIM_ICPolarity; //用來設(shè)置輸入信號(hào)的有效捕獲極性
uint16_t TIM_ICSelection; //
uint16_t TIM_ICPrescaler;
uint16_t TIM_ICFilter;
} TIM_ICInitTypeDef;
參數(shù) TIM_Channel 很好理解,用來設(shè)置通道。我們?cè)O(shè)置為通道 1,為 TIM_Channel_1。
參數(shù) TIM_ICPolarit 是用來設(shè)置輸入信號(hào)的有效捕獲極性,這里我們?cè)O(shè)置為 TIM_ICPolarity_Rising,上升沿捕獲。
同時(shí)庫函數(shù)還提供了單獨(dú)設(shè)置通道 1 捕獲極性的函數(shù)為:
TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling);
這表示通道 1 為上升沿捕獲,我們后面會(huì)用到,同時(shí)對(duì)于其他三個(gè)通道也有一個(gè)類似的函數(shù), 使用的時(shí)候一定要分清楚使用的是哪個(gè)通道該調(diào)用哪個(gè)函數(shù),格式為 TIM_OCxPolarityConfig()。 參數(shù) TIM_ICSelection 是用來設(shè)置映射關(guān)系,我們配置 IC1 直接映射在 TI1 上,選擇 TIM_ICSelection_DirectTI。
參數(shù) TIM_ICPrescaler 用來設(shè)置輸入捕獲分頻系數(shù),我們這里不分頻,所以選中 TIM_ICPSC_DIV1,還有 2,4,8 分頻可選。
參數(shù) TIM_ICFilter 設(shè)置濾波器長(zhǎng)度,這里我們不使用濾波器,所以設(shè)置為 0。 配置代碼是:
TIM_ICInitTypeDef TIM5_ICInitStructure;
TIM5_ICInitStructure.TIM_Channel = TIM_Channel_1; //選擇輸入端 IC1 映射到
TI1 上 TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕獲
TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到
TI1 上 TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置輸入分頻,不分頻
TIM5_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置輸入濾波器 不濾波
TIM_ICInit(TIM5, &TIM5_ICInitStructure);
4)使能捕獲和更新中斷(設(shè)置 TIM5 的 DIER 寄存器)
因?yàn)槲覀円东@的是高電平信號(hào)的脈寬,所以,第一次捕獲是上升沿,第二次捕獲時(shí)下降沿,必須在捕獲上升沿之后,設(shè)置捕獲邊沿為下降沿,同時(shí),如果脈寬比較長(zhǎng),那么定時(shí)器就
會(huì)溢出,對(duì)溢出必須做處理,否則結(jié)果就不準(zhǔn)了。這兩件事,我們都在中斷里面做,所以必須
開啟捕獲中斷和更新中斷。
這里我們使用定時(shí)器的開中斷函數(shù) TIM_ITConfig 即可使能捕獲和更新中斷: 允許更新中斷和捕獲中斷
TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC1,ENABLE);
5)設(shè)置中斷分組,編寫中斷服務(wù)函數(shù)
設(shè)置中斷分組的方法我們不做講解,主要是通過函數(shù) NVIC_Init()來完成。分組完成后,我們還需要在中斷函數(shù)里面完成數(shù)據(jù)處理和捕獲設(shè)置等關(guān)鍵操作,從而實(shí)現(xiàn)高電平脈寬統(tǒng)計(jì)。在中斷服務(wù)函數(shù)里面,跟以前的外部中斷和定時(shí)器中斷實(shí)驗(yàn)中一樣,我們?cè)?中斷開始的時(shí)候要進(jìn)行中斷類型判斷,在中斷結(jié)束的時(shí)候要清除中斷標(biāo)志位。使用到的函數(shù)在 上面的實(shí)驗(yàn)已經(jīng)講解過,分別為 TIM_GetITStatus()函數(shù)和 TIM_ClearITPendingBit()函數(shù)。
6)使能定時(shí)器(設(shè)置 TIM5 的 CR1 寄存器)
最后,必須打開定時(shí)器的計(jì)數(shù)器開關(guān), 啟動(dòng) TIM5 的計(jì)數(shù)器,開始輸入捕獲。 使能定時(shí)器 6 步設(shè)置,定時(shí)器 5 的通道 1 就可以開始輸入捕獲了。
TIM_Cmd(TIM5,ENABLE);
本實(shí)驗(yàn)用到的硬件資源有:
1) 指示燈 DS0
2) WK_UP 按鍵
3) 串口
4) 定時(shí)器 TIM3
5) 定時(shí)器 TIM5
我們將捕獲 TIM5_CH1(PA0)上的高電平脈寬,通過 WK_UP 按鍵輸入高電平,并從串口打印高電平脈寬。同時(shí)我們保留上節(jié)的 PWM 輸 出,通過用杜邦線連接 PB5 和 PA0,來測(cè)量 PWM 輸出的高電平脈寬。
timer.h 文件:
timer.c 文件:
main.c文件:
TIM5_IRQHandler 是 TIM5 的中斷服務(wù)函數(shù),該函數(shù)用到了兩個(gè)全局變量,用于輔助實(shí)現(xiàn) 高電平捕獲。其中 TIM5CH1_CAPTURE_STA,是用來記錄捕獲狀態(tài),該變量類似我們?cè)?usart.c 里面自行定義的 USART_RX_STA 寄存器(其實(shí)就是個(gè)變量,只是我們把它當(dāng)成一個(gè)寄存器那樣 來使用)。另外一個(gè)變量 TIM5CH1_CAPTURE_VAL,則用來記錄捕獲到下降沿的時(shí)候,TIM5_CNT的值。
現(xiàn)在我們來介紹一下,捕獲高電平脈寬的思路:首先,設(shè)置 TIM5_CH1 捕獲上升沿,這在TIM5_Cap_Init 函數(shù)執(zhí)行的時(shí)候就設(shè)置好了,然后等待上升沿中斷到來,當(dāng)捕獲到上升沿中斷, 此時(shí)如果 TIM5CH1_CAPTURE_STA 的第 6 位為 0,則表示還沒有捕獲到新的上升沿,就先把 TIM5CH1_CAPTURE_STA、TIM5CH1_CAPTURE_VAL 和 TIM5-》CNT 等清零,然后再設(shè)置TIM5CH1_CAPTURE_STA 的第 6 位為 1,標(biāo)記捕獲到高電平,最后設(shè)置為下降沿捕獲,等待 下降沿到來。如果等待下降沿到來期間,定時(shí)器發(fā)生了溢出,就在 TIM5CH1_CAPTURE_STA 里面對(duì)溢出次數(shù)進(jìn)行計(jì)數(shù),當(dāng)最大溢出次數(shù)來到的時(shí)候,就強(qiáng)制標(biāo)記捕獲完成(雖然此時(shí)還沒 有捕獲到下降沿)。當(dāng)下降沿到來的時(shí)候,先設(shè)置 TIM5CH1_CAPTURE_STA 的第 7 位為 1,標(biāo) 記成功捕獲一次高電平,然后讀取此時(shí)的定時(shí)器值到 TIM5CH1_CAPTURE_VAL 里面,最后設(shè)置為上升沿捕獲,回到初始狀態(tài)。這樣,我們就完成一次高電平捕獲了,只要 TIM5CH1_CAPTURE_STA 的第 7 位一直為 1,那么就不會(huì)進(jìn)行第二次捕獲,我們?cè)?main 函數(shù)處理完捕獲數(shù)據(jù)后,將 TIM5CH1_CAPTURE_STA 置零,就可以開啟第二次捕獲。
將程序下載,連接窗口,波特率設(shè)置為9600,當(dāng)給PA0脈沖信號(hào)時(shí),即可通過串口顯示其脈沖寬度,同時(shí)也可以將PB5連接至PA0,即可以測(cè)試輸出的PWM的寬度。
評(píng)論
查看更多