MCU微課堂
CKS32F107xx TIM(三)
第四十八期 2024.11.08
PWM輸入捕獲
上節(jié)課我們介紹了高級(jí)定時(shí)器互補(bǔ)PWM輸出的配置方法,這節(jié)課我們將向大家介紹高級(jí)定時(shí)器的另一個(gè)常見應(yīng)用——PWM輸入模式。在本節(jié)課中,我們將先圍繞輸入捕獲模式展開,并重點(diǎn)描述PWM輸入模式和涉及的寄存器,最后通過一個(gè)實(shí)驗(yàn)例程去介紹PWM輸入模式的配置方法。
輸入捕獲模式簡(jiǎn)介
1、普通輸入模式
除基本定時(shí)器外,其余定時(shí)器的部分通道都可以對(duì)輸入信號(hào)的上升沿、下降沿或者雙邊沿進(jìn)行捕獲,并且計(jì)數(shù)器CNT的值會(huì)被鎖存到捕獲/比較寄存器CCR中。當(dāng)我們需要同時(shí)捕獲PWM波的頻率和占空比時(shí),僅需要測(cè)出一個(gè)周期中高電平和低電平持續(xù)的時(shí)間即可。我們可嘗試如下步驟:首先將定時(shí)器的某一通道初始設(shè)置為上升沿捕獲,當(dāng)發(fā)生第一次捕獲到上升沿的中斷,以此中斷時(shí)刻作為一個(gè)起點(diǎn),讀取CCR中值為Value1,此時(shí)將捕獲模式設(shè)置為下降沿捕獲,在發(fā)生第二次中斷的時(shí)候,捕獲到了下降沿,讀取CCR中值為Value2,那么Value2和Value1之間的差值,就是一個(gè)周期中高電平持續(xù)的時(shí)間,然后我們?cè)谥袛嘀杏謱⒉东@的方式設(shè)置為上升沿捕獲,那么在第三次產(chǎn)生中斷的時(shí)候,讀取CCR中值為Value3,那么Value3和Value2之間的差值就是一個(gè)周期中低電平的時(shí)間。至此,PWM波的頻率可由Value3和Value1之間的差值計(jì)算出,正占空比則可通過高電平占整個(gè)周期的比值獲得。如下圖1所示:
圖1 普通輸入捕獲概覽圖
2、PWM輸入模式
PWM輸入模式是普通輸入模式的一種特例,以輸入通道TI1為例,PWM信號(hào)進(jìn)入該通道后,信號(hào)被分成TI1FP1和TI1FP2兩路,最終分別映射到了IC1和IC2捕獲通道,其中一個(gè)捕獲上升沿,另一個(gè)捕獲下降沿。這樣用戶可以在中斷中去讀上升沿和下降沿對(duì)應(yīng)寄存器中的計(jì)數(shù),從而得出周期和占空比。并且用戶在設(shè)計(jì)之初,需要先選定哪一路為觸發(fā)信號(hào)以及觸發(fā)極性,一旦選定某一路為觸發(fā)信號(hào)則對(duì)應(yīng)的即為周期,另一路則對(duì)應(yīng)為占空比,兩路捕獲極性也是相反的,并且因?yàn)槭荘WM輸入捕獲的緣故,當(dāng)其中一路配置完成,另一路由硬件自動(dòng)配置,無需軟件來配置。圖2為PWM輸入模式時(shí)序圖。
圖2 PWM輸入模式時(shí)序圖
其中,IC1捕獲通道計(jì)算兩次都是上升沿的時(shí)間,即周期T;而IC2通道則計(jì)算一次下降沿和之前上升沿之差,這樣得到高電平時(shí)長(zhǎng),從而可以求得周期T和占空比。需要注意的是,PWM輸入模式需要占用兩個(gè)捕獲寄存器,且只有TI1FP1和TI2FP2連接到了從模式控制器(使用PWM輸入捕獲時(shí),需要配置從模式控制器為復(fù)位模式),所以只能使用定時(shí)器的通道1或通道2。
寄存器和輸入捕獲結(jié)構(gòu)體概述
1、捕獲/比較寄存器CCMR
關(guān)于CCMR寄存器,上節(jié)課我們介紹了輸出比較模式,這節(jié)課我們來介紹下輸入捕獲模式,該寄存器的各位描述圖如下:
圖3 CCMR1寄存器各位描述圖
該16位寄存器CCMR的下層對(duì)應(yīng)輸入捕獲(上層對(duì)應(yīng)輸出比較),其中CCMR1用于捕獲通道1和2的控制,CCMR2用于捕獲通道3和4的控制。下圖為低8位詳細(xì)描述圖,用于捕獲通道1。
圖4 CCMR1寄存器低7位描述圖
參數(shù)CC1S,用于輸入捕獲/輸出比較通道的引腳選擇,若我們?cè)O(shè)置CCIS[1:0] = 01,表明CC1通道(對(duì)應(yīng)定時(shí)器的通道1)被配置為輸入,IC1映射在TI1上。
參數(shù)IC1PSC,配置為00時(shí),表明每1個(gè)邊沿觸發(fā)1次捕獲。
參數(shù)IC1F,用來設(shè)置TI1輸入采樣頻率和數(shù)字濾波器長(zhǎng)度,本課中我們不做濾波處理。
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í)器輸入通道各參數(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]位,用于輸入通道選擇,輸入通道共有三個(gè)來源,分別為:TIM_ICSelection_DirectTI、TIM_ICSelection_IndirectTI或TIM_ICSelection_TRC。若為普通輸入模式,4個(gè)通道均能使用;若為PWM輸入模式,只能使用通道1和2。輸入通道和捕獲通道的映射關(guān)系詳見下圖。
圖6 輸入通道和捕獲通道的映射關(guān)系
4)參數(shù)TIM_ ICPrescaler:設(shè)定CCMRx寄存器的ICxPSC[1:0]位的值,用來設(shè)置輸入捕獲分頻系數(shù),有1、2、4、8分頻可選。這里我們需要捕獲輸入信號(hào)的每個(gè)有效邊沿,故設(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);
上述代碼中,我們?cè)O(shè)置定時(shí)器的通道1為上升沿捕獲,且輸入通道1(TI1)與捕獲通道1(IC1)為直接映射,不分頻,不使用濾波器。
PWM模式輸入配置實(shí)驗(yàn)
本實(shí)驗(yàn)配置高級(jí)定時(shí)器的通道1,即PA8,用于捕獲信號(hào)發(fā)生器輸出PWM信號(hào),最后通過串口調(diào)試助手打印捕獲到的PWM的頻率和占空比。主要的編程要點(diǎn)如下。
1、高級(jí)定時(shí)器引腳初始化
由于TIM1_CH1是連接在PA8上,這里需要開啟GPIOA時(shí)鐘,并配置引腳為浮空輸入,我們配置的代碼如下:
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、高級(jí)定時(shí)器中斷優(yōu)先級(jí)設(shè)置
之前的課程中讓我們對(duì)中斷優(yōu)先級(jí)已經(jīng)有了深入了解,這里因?yàn)槲覀冎挥幸粋€(gè)捕獲/比較中斷源,所以優(yōu)先級(jí)隨便設(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、高級(jí)定時(shí)器PWM輸入模式配置
我們主要對(duì)時(shí)基和輸入捕獲結(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的捕獲計(jì)數(shù)器設(shè)置為1us計(jì)數(shù)一次,重裝載值為65535,所以可以捕獲的時(shí)間精度為1us,最低可捕獲的頻率為15.3Hz。其次,我們選擇TIM1的通道1(TI1)作為PWM信號(hào)輸入,并選擇TI1FP1為觸發(fā)信號(hào)(輸入的信號(hào)被分為TI1FP1和TI1FP2),因此IC1捕獲PWM信號(hào)周期,IC2捕獲PWM信號(hào)占空比。而且由于PWM輸入模式下,當(dāng)捕獲開始時(shí),需要將CNT復(fù)位,所以我們需要配置定時(shí)器以從模式工作在復(fù)位模式下,最后使能捕獲中斷和高級(jí)定時(shí)器。
4、高級(jí)定時(shí)器中斷服務(wù)函數(shù)配置
在函數(shù)TIM1_CC_IRQHandler中,如果是第一個(gè)上升沿中斷,計(jì)數(shù)器CNT會(huì)被復(fù)位,鎖存到CCR1寄存器的值是0,CCR2寄存器的值也是0,無法計(jì)算頻率和占空比。當(dāng)?shù)诙紊仙氐絹淼臅r(shí)候,CCR1和CCR2捕獲到的才是有效的值。其中CCR1對(duì)應(yīng)的是周期,CCR2對(duì)應(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ù)就是對(duì)上述函數(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、下載驗(yàn)證
我們將編譯好的程序下載至CKS32F107xx開發(fā)板,信號(hào)發(fā)生器和PWM輸入引腳PA8通過杜邦線連接,USB轉(zhuǎn)TTL模塊分別與UART1—PA9和電腦相連,然后打開串口調(diào)試助手,查看打印信息。
-
mcu
+關(guān)注
關(guān)注
146文章
16876瀏覽量
349871 -
寄存器
+關(guān)注
關(guān)注
31文章
5292瀏覽量
119798 -
PWM
+關(guān)注
關(guān)注
114文章
5118瀏覽量
213137 -
定時(shí)器
+關(guān)注
關(guān)注
23文章
3231瀏覽量
114314 -
捕獲模式
+關(guān)注
關(guān)注
0文章
2瀏覽量
799
原文標(biāo)題:MCU微課堂|CKS32F107xx TIM(三)
文章出處:【微信號(hào):中科芯MCU,微信公眾號(hào):中科芯MCU】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論