MCU微課堂
CKS32F107xx TIM(三)
第四十八期 2024.11.08
PWM輸入捕獲
上節(jié)課我們介紹了高級定時器互補PWM輸出的配置方法,這節(jié)課我們將向大家介紹高級定時器的另一個常見應(yīng)用——PWM輸入模式。在本節(jié)課中,我們將先圍繞輸入捕獲模式展開,并重點描述PWM輸入模式和涉及的寄存器,最后通過一個實驗例程去介紹PWM輸入模式的配置方法。
輸入捕獲模式簡介
1、普通輸入模式
除基本定時器外,其余定時器的部分通道都可以對輸入信號的上升沿、下降沿或者雙邊沿進行捕獲,并且計數(shù)器CNT的值會被鎖存到捕獲/比較寄存器CCR中。當(dāng)我們需要同時捕獲PWM波的頻率和占空比時,僅需要測出一個周期中高電平和低電平持續(xù)的時間即可。我們可嘗試如下步驟:首先將定時器的某一通道初始設(shè)置為上升沿捕獲,當(dāng)發(fā)生第一次捕獲到上升沿的中斷,以此中斷時刻作為一個起點,讀取CCR中值為Value1,此時將捕獲模式設(shè)置為下降沿捕獲,在發(fā)生第二次中斷的時候,捕獲到了下降沿,讀取CCR中值為Value2,那么Value2和Value1之間的差值,就是一個周期中高電平持續(xù)的時間,然后我們在中斷中又將捕獲的方式設(shè)置為上升沿捕獲,那么在第三次產(chǎn)生中斷的時候,讀取CCR中值為Value3,那么Value3和Value2之間的差值就是一個周期中低電平的時間。至此,PWM波的頻率可由Value3和Value1之間的差值計算出,正占空比則可通過高電平占整個周期的比值獲得。如下圖1所示:
圖1 普通輸入捕獲概覽圖
2、PWM輸入模式
PWM輸入模式是普通輸入模式的一種特例,以輸入通道TI1為例,PWM信號進入該通道后,信號被分成TI1FP1和TI1FP2兩路,最終分別映射到了IC1和IC2捕獲通道,其中一個捕獲上升沿,另一個捕獲下降沿。這樣用戶可以在中斷中去讀上升沿和下降沿對應(yīng)寄存器中的計數(shù),從而得出周期和占空比。并且用戶在設(shè)計之初,需要先選定哪一路為觸發(fā)信號以及觸發(fā)極性,一旦選定某一路為觸發(fā)信號則對應(yīng)的即為周期,另一路則對應(yīng)為占空比,兩路捕獲極性也是相反的,并且因為是PWM輸入捕獲的緣故,當(dāng)其中一路配置完成,另一路由硬件自動配置,無需軟件來配置。圖2為PWM輸入模式時序圖。
圖2 PWM輸入模式時序圖
其中,IC1捕獲通道計算兩次都是上升沿的時間,即周期T;而IC2通道則計算一次下降沿和之前上升沿之差,這樣得到高電平時長,從而可以求得周期T和占空比。需要注意的是,PWM輸入模式需要占用兩個捕獲寄存器,且只有TI1FP1和TI2FP2連接到了從模式控制器(使用PWM輸入捕獲時,需要配置從模式控制器為復(fù)位模式),所以只能使用定時器的通道1或通道2。
寄存器和輸入捕獲結(jié)構(gòu)體概述
1、捕獲/比較寄存器CCMR
關(guān)于CCMR寄存器,上節(jié)課我們介紹了輸出比較模式,這節(jié)課我們來介紹下輸入捕獲模式,該寄存器的各位描述圖如下:
圖3 CCMR1寄存器各位描述圖
該16位寄存器CCMR的下層對應(yīng)輸入捕獲(上層對應(yīng)輸出比較),其中CCMR1用于捕獲通道1和2的控制,CCMR2用于捕獲通道3和4的控制。下圖為低8位詳細(xì)描述圖,用于捕獲通道1。
圖4 CCMR1寄存器低7位描述圖
參數(shù)CC1S,用于輸入捕獲/輸出比較通道的引腳選擇,若我們設(shè)置CCIS[1:0] = 01,表明CC1通道(對應(yīng)定時器的通道1)被配置為輸入,IC1映射在TI1上。
參數(shù)IC1PSC,配置為00時,表明每1個邊沿觸發(fā)1次捕獲。
參數(shù)IC1F,用來設(shè)置TI1輸入采樣頻率和數(shù)字濾波器長度,本課中我們不做濾波處理。
2、捕獲/比較使能寄存器CCER
在本課中我們僅用到低2位CC1E和CC1P,由于我們需要在中斷中處理捕獲的數(shù)據(jù),所以配置CC1E為1,CC1P配置為不反相,故設(shè)置為0。CCER低2位圖如下描述。
圖5 CCMR1寄存器低7位描述圖
3、輸入捕獲結(jié)構(gòu)體TIM_ICInitTypeDef
可配合TIM_PWMIConfig函數(shù)完成定時器輸入通道各參數(shù)的初始化配置。輸入捕獲結(jié)構(gòu)體的各參數(shù)定義如下:
typedef struct
{
uint16_t TIM_Channel;
uint16_t TIM_ICPolarity;
uint16_t TIM_ICSelection;
uint16_t TIM_ICPrescaler;
uint16_t TIM_ICFilter;
} TIM_ICInitTypeDef;
1)參數(shù)TIM_Channel:設(shè)定CCMRx寄存器CCxS位,用于捕獲通道ICx選擇。
2)參數(shù)TIM_ICPolarity:設(shè)定CCER寄存器CCxP位和CCxNP位,用于輸入捕獲邊沿觸發(fā)選擇。
3)參數(shù)TIM_ICSelection:設(shè)定CCRMx寄存器的CCxS[1:0]位,用于輸入通道選擇,輸入通道共有三個來源,分別為:TIM_ICSelection_DirectTI、TIM_ICSelection_IndirectTI或TIM_ICSelection_TRC。若為普通輸入模式,4個通道均能使用;若為PWM輸入模式,只能使用通道1和2。輸入通道和捕獲通道的映射關(guān)系詳見下圖。
圖6 輸入通道和捕獲通道的映射關(guān)系
4)參數(shù)TIM_ ICPrescaler:設(shè)定CCMRx寄存器的ICxPSC[1:0]位的值,用來設(shè)置輸入捕獲分頻系數(shù),有1、2、4、8分頻可選。這里我們需要捕獲輸入信號的每個有效邊沿,故設(shè)置為1分頻即可。
5)參數(shù)TIM_ ICFilter:設(shè)定CCMRx寄存器ICxF[3:0]位,用于設(shè)置輸入捕獲濾波器。
本課中我們配置的示例代碼如下:
TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x0;
TIM_PWMIConfig(TIM1, &TIM_ICInitStructure);
上述代碼中,我們設(shè)置定時器的通道1為上升沿捕獲,且輸入通道1(TI1)與捕獲通道1(IC1)為直接映射,不分頻,不使用濾波器。
PWM模式輸入配置實驗
本實驗配置高級定時器的通道1,即PA8,用于捕獲信號發(fā)生器輸出PWM信號,最后通過串口調(diào)試助手打印捕獲到的PWM的頻率和占空比。主要的編程要點如下。
1、高級定時器引腳初始化
由于TIM1_CH1是連接在PA8上,這里需要開啟GPIOA時鐘,并配置引腳為浮空輸入,我們配置的代碼如下:
void TIM1_GPIO_Configuration(void)
{
GPIO_InitTypeDefGPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
2、高級定時器中斷優(yōu)先級設(shè)置
之前的課程中讓我們對中斷優(yōu)先級已經(jīng)有了深入了解,這里因為我們只有一個捕獲/比較中斷源,所以優(yōu)先級隨便設(shè)置,我們配置的代碼如下:
void TIM1_NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
3、高級定時器PWM輸入模式配置
我們主要對時基和輸入捕獲結(jié)構(gòu)體初始化,配置代碼如下:
void TIM1_Input_Capture_Mode_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
/* Time Base Configuration */
TIM_TimeBaseStructure.TIM_Period = 65535-1;
TIM_TimeBaseStructure.TIM_Prescaler = 72-1;
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
/* PWM Input Capture Configuration */
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x0;
TIM_PWMIConfig(TIM1, &TIM_ICInitStructure);
TIM_SelectInputTrigger(TIM1, TIM_TS_TI1FP1);
TIM_SelectSlaveMode(TIM1, TIM_SlaveMode_Reset);
TIM_SelectMasterSlaveMode(TIM1,TIM_MasterSlaveMode_Enable);
TIM_ITConfig(TIM1, TIM_IT_CC1, ENABLE);
TIM_ClearITPendingBit(TIM1, TIM_IT_CC1);
TIM_Cmd(TIM1, ENABLE);
}
從上述示例代碼來看,我們首先將TIM1_CH1的捕獲計數(shù)器設(shè)置為1us計數(shù)一次,重裝載值為65535,所以可以捕獲的時間精度為1us,最低可捕獲的頻率為15.3Hz。其次,我們選擇TIM1的通道1(TI1)作為PWM信號輸入,并選擇TI1FP1為觸發(fā)信號(輸入的信號被分為TI1FP1和TI1FP2),因此IC1捕獲PWM信號周期,IC2捕獲PWM信號占空比。而且由于PWM輸入模式下,當(dāng)捕獲開始時,需要將CNT復(fù)位,所以我們需要配置定時器以從模式工作在復(fù)位模式下,最后使能捕獲中斷和高級定時器。
4、高級定時器中斷服務(wù)函數(shù)配置
在函數(shù)TIM1_CC_IRQHandler中,如果是第一個上升沿中斷,計數(shù)器CNT會被復(fù)位,鎖存到CCR1寄存器的值是0,CCR2寄存器的值也是0,無法計算頻率和占空比。當(dāng)?shù)诙紊仙氐絹淼臅r候,CCR1和CCR2捕獲到的才是有效的值。其中CCR1對應(yīng)的是周期,CCR2對應(yīng)的是占空比。我們配置的代碼如下:
void TIM1_CC_IRQHandler(void)
{
TIM_ClearITPendingBit(TIM1, TIM_IT_CC1);
IC1Value = TIM_GetCapture1(TIM1);
IC2Value = TIM_GetCapture2(TIM1);
if (IC1Value != 0)
{
DutyCycle = (float)((IC2Value+1) * 100) / (IC1Value+1);
Frequency = (72000000/((72-1)+1))/(float)(IC1Value+1);
printf("占空比:%0.2f%% 頻率:%0.2fHz ", DutyCycle, Frequency);
}
else
{
DutyCycle = 0;
Frequency = 0;
}
}
5、主函數(shù)配置
main函數(shù)就是對上述函數(shù)的調(diào)用,配置示例如下:
int main(void)
{
CKS_USART_Init();
printf("CKS Timer Input Capture Demo start running... ");
TIM1_GPIO_Configuration();
TIM1_NVIC_Configuration();
TIM1_Input_Capture_Mode_Configuration();
while(1){}
}
至此,我們配置已完成。
6、下載驗證
我們將編譯好的程序下載至CKS32F107xx開發(fā)板,信號發(fā)生器和PWM輸入引腳PA8通過杜邦線連接,USB轉(zhuǎn)TTL模塊分別與UART1—PA9和電腦相連,然后打開串口調(diào)試助手,查看打印信息。
-
mcu
+關(guān)注
關(guān)注
146文章
17194瀏覽量
351863 -
寄存器
+關(guān)注
關(guān)注
31文章
5358瀏覽量
120771 -
PWM
+關(guān)注
關(guān)注
114文章
5194瀏覽量
214329 -
定時器
+關(guān)注
關(guān)注
23文章
3253瀏覽量
115063 -
捕獲模式
+關(guān)注
關(guān)注
0文章
2瀏覽量
819
原文標(biāo)題:MCU微課堂|CKS32F107xx TIM(三)
文章出處:【微信號:中科芯MCU,微信公眾號:中科芯MCU】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論