最近做一个IRIG-B码对时的项目用到STM32的TIM1输入捕获功能,配置TIM1的输入捕获遇到很多坑,在这里总结下,希望对大家有帮助。
项目中用到的输入引脚为PE13,为TIM1_H3即TIM1的第3通道,这里提醒大家在使用引脚功能时最好查看引脚的重映象表,看是否要开启重映象,功能为捕获高电平脉宽,具体配置如下:
1.首先配置GPIO
/* GPIO引脚配置 */
void R_gpio_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);//开启引脚时钟
GPIO_PinRemapConfig(GPIO_FullRemap_TIM1,ENABLE); //开启TIM1重映象
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; //PE13
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //引脚设置为上拉输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE,&GPIO_InitStructure);
}
2.配置TIM1
/* TIM1输入捕获配置 */
void Time_init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM1_ICInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); //TIM1 时钟使能
TIM_ClearITPendingBit(TIM1, TIM_IT_Update ); //清除TIM1更新中断标志
//定时器 TIM1 初始化
TIM_TimeBaseStructure.TIM_Period = 7199; //设置自动重装载寄存器的周期值,使100ms产生一次中断
TIM_TimeBaseStructure.TIM_Prescaler = 999; //设置预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分频系数
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM 向上计数
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //初始化 TIM1
//TIM1输入捕获参数配置
TIM1_ICInitStructure.TIM_Channel = TIM_Channel_3; //捕获通道IC3
TIM1_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获
TIM1_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //直接映射
TIM1_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //不分频,每个变化沿都捕获
TIM1_ICInitStructure.TIM_ICFilter = 0x00;//不滤波
TIM_ICInit(TIM1, &TIM1_ICInitStructure);
//中断优先级 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn; //TIM1 捕获中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //从优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ 通道使能
NVIC_Init(&NVIC_InitStructure); //初始化 NVIC 寄存器
TIM_ITConfig(TIM1,TIM_IT_Update|TIM_IT_CC3,ENABLE); //使能更新中断和捕获中断
TIM_Cmd(TIM1, ENABLE); //使能定时器
}
配置TIM1的时候有几点要很小心:
1.TIM1在APB2时钟总线上,所以应使用RCC_APB2PeriphClockCmd()函数使能TIM1时钟;
2.TIM1有多种中断,这里选择捕获比较中断,即TIM1_CC_IRQn;
3.引脚为TIM1_CH3,即TIM1的3通道,中断标志位TIM_IT_CC3。
3.中断服务函数配置
/* TIM1 中断服务程序 */
void TIM1_CC_IRQHandler(void)
{
if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET) //检查TIM1更新中断标志
{
overflow++;
}
else if (TIM_GetITStatus(TIM1, TIM_IT_CC3) != RESET) //检查TIM1通道3捕获中断标志
{
if(state == START) //初始状态
{
overflow = 0;
TIM_SetCounter(TIM1,0);
state = WAIT_FALLING;
TIM_OC3PolarityConfig(TIM1,TIM_ICPolarity_Falling); //设置为下降沿捕获
}
else if(state == WAIT_RISING) //捕获上升沿
{
// TIM1CH3_CAPTURE_VAL = TIM_GetCapture3(TIM1);
// value = TIM1CH3_CAPTURE_VAL + (overflow*7200);
overflow = 0;
TIM_SetCounter(TIM1,0);
state = WAIT_FALLING;
TIM_OC3PolarityConfig(TIM1,TIM_ICPolarity_Falling); //设置为下降沿触发
}
else // 捕获下降沿
{
TIM1CH3_CAPTURE_VAL = TIM_GetCapture3(TIM1);
value = TIM1CH3_CAPTURE_VAL + (overflow*7200);
overflow = 0;
TIM_SetCounter(TIM1,0);
state = WAIT_RISING;
TIM_OC3PolarityConfig(TIM1,TIM_ICPolarity_Rising); //设置为上升沿触发
}
}
TIM_ClearITPendingBit(TIM1, TIM_IT_Update|TIM_IT_CC3 ); //清除TIM1更新中断标志和捕获标志
}
这里需要注意几点:
1.TIM1的中断服务函数名要注意,此次用到的是TIM1的捕获比较中断,所以为void TIM1_CC_IRQHandler(void);
2.改变捕获极性的函数要注意,此处为改变通道3捕获极性的函数,所以为TIM_OC3PolarityConfig();
3.通道3获取捕获值函数为TIM_GetCapture3();
4.因为我只需要高电平脉宽,所以只需要在捕获上升沿的时候获取捕获值即可。
经过测试高电平脉宽为10毫秒时捕获值为720,5ms时捕获值为360。
公式为:脉宽=((1 + TIM_Prescaler)/系统时钟频率)*捕获值
上一篇:【STM32】STM32之timer1产生PWM(互补通道)
下一篇:STM32PWM配置详解笔记
推荐阅读最新更新时间:2024-11-13 15:53
设计资源 培训 开发板 精华推荐
- DC1856B-B,用于 LTM4649EY 16V、10A 降压稳压器的演示板
- LTC2636-HMI12 八通道、12 位数模转换器的典型应用
- LTC3622EDE-2 2.5V/5V Vout 应用的典型应用电路,fSW = 1MHz 同步降压稳压器
- 使用 Analog Devices 的 LTC1550LCMS8-2.5 的参考设计
- STEVAL-ISA109V2,基于 STBB2、800mA、3MHz、可调输出、高效双模降压-升压 DC-DC 转换器的演示板
- AD8341-EVAL,基于 AD8341 1.5 至 2.4 GHz 射频矢量调制器的评估板
- 使用 Aimtec 的 AM2S-4812SZ 的参考设计
- 用于更高输出电流的 LT3066IMSE-3.3 并联稳压器的典型应用电路
- STM32F10xxx ADC应用电路使用STM32F10xxx ADC_IN4、ADC_IN10、ADC_IN11和ADC_IN14连接
- ASL5115EVBSLAV: MLC ASL5115SHN评估/开发板