今天主要是用TIM3進行PWM的輸入模式,進行對矩形波的脈沖信號寬度以及其周期進行測量,先來看一幅圖。
圖1 TIM內部邏輯圖
我們先來看看datasheet上是怎么說的:
該模式是輸入捕獲模式的一個特例,除下列區別外,操作與輸入捕獲模式相同:
● 兩個ICx信號被映射至同一個TIx輸入。
● 這2個ICx信號為邊沿有效,但是極性相反。
● 其中一個TIxFP信號被作為觸發輸入信號,而從模式控制器被配置成復位模式。
例如,你需要測量輸入到TI1上的PWM信號的長度(TIMx_CCR1寄存器)和占空比(TIMx_CCR2
寄存器),具體步驟如下(取決于CK_INT的頻率和預分頻器的值)
● 選擇TIMx_CCR1的有效輸入:置TIMx_CCMR1寄存器的CC1S=01(選擇TI1)。
● 選擇TI1FP1的有效極性(用來捕獲數據到TIMx_CCR1中和清除計數器):置CC1P=0(上升沿
有效)。
● 選擇TIMx_CCR2的有效輸入:置TIMx_CCMR1寄存器的CC2S=10(選擇TI1)。
● 選擇TI1FP2的有效極性(捕獲數據到TIMx_CCR2):置CC2P=1(下降沿有效)。
● 選擇有效的觸發輸入信號:置TIMx_SMCR寄存器中的TS=101(選擇TI1FP1)。
● 配置從模式控制器為復位模式:置TIMx_SMCR中的SMS=100。
● 使能捕獲:置TIMx_CCER寄存器中CC1E=1且CC2E=1。
我們從圖1上可以看出只有TI1FP1和TI2FP2連到了從模式控制器,所以PWM輸入模式只能使用TIMx_CH1 /TIMx_CH2信號。
圖2 IC1,IC2捕獲信號圖
TI1為輸入PWM波信號波形,TIMx_CNT為計數器計數值,當第一個下降沿信號到來,IC2會先進行捕獲,然后到下一個上升沿到來,IC1進行捕獲!在捕獲的同時,IC1和IC2會吧CNT的值映射到對應的CCR1、CCR2的寄存器里面,這個值就是我們需要的計數值!
那么我們所需測量的周期就是IC1捕獲的值,脈沖寬度即為IC2測量的值了!
可是,這里有個bug,不注意的人,很容易犯錯!我們的CCRx寄存器是一個16bit的寄存器計數范圍為0~0xffff,即0~65535,可是當測量的矩形波周期太長,脈沖寬度太寬,二我們的計數又太快,很容易出現CCRx溢出現象,所以,我們在測量低頻信號時,一定要對TIM的時鐘進行分頻,這樣我們的計數就不會那么快了,也不會產生溢出現象,當我們計數計完了,再把分頻所導致的結果進行倍頻就OK了。
還有個地方,可能你只按照我上面說的進行做,你會發現他總是跟實際的頻率,或者周期差那么一點點!其實這是有來由的!下面看看圖3:
圖3 注意點
根據圖3,我們可以看出他在開始計數的過程中會差那么三個時鐘,所以我們要在數值上進行補齊!也就這么多!下面附上代碼:
void inpwm_init(void)
{
TIM_ICInitTypeDef TIM_ICInitStructure;
/* TIM3 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
/* GPIOA clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/* NVIC configuration */
NVIC_Configuration();
/* Configure the GPIO ports */
GPIO_Configuration();
/* TIM3 configuration: PWM Input mode ------------------------
The external signal is connected to TIM3 CH2 pin (PA.07),
The Rising edge is used as active edge,
The TIM3 CCR2 is used to compute the frequency value
The TIM3 CCR1 is used to compute the duty cycle value
------------------------------------------------------------ */
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(TIM3, &TIM_ICInitStructure);
/* Select the TIM3 Input Trigger: TI2FP2 */
TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1);
/* Select the slave Mode: Reset Mode */
TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);
/* Enable the Master/Slave Mode */
TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);
/* TIM enable counter */
TIM_Cmd(TIM3, ENABLE);
/* Enable the CC2 Interrupt Request */
TIM_ITConfig(TIM3, TIM_IT_CC2|TIM_IT_CC1, ENABLE);
}
void TIM3_IRQHandler(void)
{
if(TIM_GetFlagStatus(TIM3,TIM_FLAG_CC1) == SET)
{
DutyCycle = TIM_GetCapture1(TIM3)+3;
Frequency = 72000000 / DutyCycle;
TIM_ClearFlag(TIM3,TIM_FLAG_CC1);
}
if(TIM_GetFlagStatus(TIM3,TIM_FLAG_CC2) == SET)
{
IC2Value = TIM_GetCapture2(TIM3)+4;
TIM_ClearFlag(TIM3,TIM_FLAG_CC2);
}
}
圖4 實際波形
圖5 測量結果
上一篇:【菜鳥入門】stm32的第一個程序--LED
下一篇:【STM庫應用】stm32 之 IIC應用
推薦閱讀
史海拾趣