备注:博文仅仅是记录个人笔记,加深理解
说起定时器,我们可能都认为都是简单的定时功能.但说句实在话,想把定时器学的透彻还是需要发些时间的.
stm32f4的定时器的标准库都有3300多行,可见其实也是很复杂的.
输入捕获功能相对比较简单,一般用来计算频率.它的过程是这样的,
- 当定时器通道捕获到预先配置的边沿,则会把当前计数器的值,锁存到对应通道的CCR寄存器中,此时锁存的值记为value1.
- 当再次捕获到对应的边沿,此时锁存到CCR寄存器中的值记为value2.
当计数器没有发生溢出时,(value2-value1)即为外部波形一个周期中计数器增加或减少的计数器值. 如果计数器发生过溢出,则实际的value2 为 (计数器溢出次数 * 定时器时钟) - value1 + value2. 如果定时器的时钟为clk,那么 clk/(value2-value1) 即为外部信号频率.
如下图T2-T1就是一个周期的时间.

代码分析:
定时器时钟为60K. 从原理上这个可以用来测量编码器的脉冲数量,进而计算出瞬时速度
#define TIM1_CLK 60000
int inputCaptureMain(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
uint16_t PrescalerValue = 0;
/* 这里是定时器gpio的初始化*/
TIM_Config();
/*base config*/
/* Compute the prescaler value */
/* 默认APB2时钟是84M,所以这里定时器TIM1时钟为6M*/
PrescalerValue = (uint16_t) (SystemCoreClock / TIM1_CLK) - 1;
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = 60000; //定时器为1s发生溢出
TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
/*下面能看到定时器的捕获边沿为上升沿*/
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_ICInit(TIM1, &TIM_ICInitStructure);
/* Enable the CC1 Interrupt Request */
TIM_ITConfig(TIM1, TIM_IT_CC1, ENABLE);
TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
/* TIM enable counter */
TIM_Cmd(TIM1, ENABLE);
}
/*记录计数器溢出次数*/
void TIM1_UP_IRQ(void)
{
if(TIM_GetITStatus(TIM1, TIM_IT_Update) == SET)
{
overFlowCount++;
TIM_ClearFlag(TIM1, TIM_FLAG_Update);
}
}
void TIM1_CC_IRQ(void)
{
if(TIM_GetITStatus(TIM1, TIM_IT_CC1) == SET)
{
/* Clear TIM1 Capture compare interrupt pending bit */
TIM_ClearITPendingBit(TIM1, TIM_IT_CC1);
TIM_ClearFlag(TIM1, TIM_IT_CC1);
if(uhCaptureNumber == 0)
{
/* 捕获第一次的计数器的值 */
uhIC3ReadValue1 = TIM_GetCapture1(TIM1);
uhCaptureNumber = 1;
overFlowCount = 0;
}
else if(uhCaptureNumber == 1)
{
/* 捕获第二次计数器的值 */
uhIC3ReadValue2 = TIM_GetCapture1(TIM1);
if (overFlowCount > 0)
{
uhIC3ReadValue2 = (overFlowCount*TIM1_CLK) - uhIC3ReadValue1 + uhIC3ReadValue2;
}
/* 计算value2和value1的差值,即过去了多长时间*/
if (uhIC3ReadValue2 > uhIC3ReadValue1)
{
uwCapture = (uhIC3ReadValue2 - uhIC3ReadValue1);
}
else if (uhIC3ReadValue2 < uhIC3ReadValue1)
{
uwCapture = ((0xFFFF - uhIC3ReadValue1) + uhIC3ReadValue2);
}
else
{
uwCapture = 0;
}
/* 计算外部时钟的周期*/
uwTIM1Freq = (uint32_t) TIM1_CLK / uwCapture;
uhCaptureNumber = 0;
printf("freq:%d,val2:%d,val1:%d\n", uwTIM1Freq, uhIC3ReadValue2, uhIC3ReadValue1);
}
}
}
1万+

被折叠的 条评论
为什么被折叠?



