|
今天早上开始做项目中的测速部分,采用3144E开关型霍尔传感器数字输出,只要单片机采集模块输出的脉冲个数,从而即可计算出速度。折腾了一下下,现在写下思路。
首先总结下STM32外部脉冲ETR引脚:
TIMER1-----PA12
TIMER2-----PA0
TIMER3-----PD2
TIMER4-----PE0
其他大家有需要再查数据手册的引脚图即可。
这边使用使用定时器TIM1的ETR输入引脚PA12作为采集脉冲输入引脚,定时器TIM1是16位可自动装载初始值的高级计数器,使能GPIO和TIM1时钟后,把GPIO口配置成浮空输入模式,自动重装初始值和分频系数大家可以根据实际情况自己设置,这边开启更新中断TIM_IT_Update,查了数据手册后发现中断向量号是TIM1_UP_IRQn,并不是TIM1_IRQn。
初始化代码
void TIM1_Counter_Init(u32 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructuer;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE); ///使能TIM1时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStructuer.GPIO_Pin=GPIO_Pin_12;
GPIO_InitStructuer.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_InitStructuer.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructuer);
//timer1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;//子优先级2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
TIM_TimeBaseInitStructure.TIM_Period = arr;//自动重装载值
TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //定时器分频
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;//向上计数模式
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStructure);//初始化TIM1
TIM_ETRClockMode2Config(TIM1, TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted, 5);//5次采样滤波 外部时钟模式2
TIM_ClearITPendingBit(TIM1,TIM_IT_Update); //清除中断标志位,避免第一次自动进入中断一次
TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE);
TIM_SetCounter(TIM1,0);//设置计数初值
TIM_Cmd(TIM1,ENABLE); //使能定时器1
}
//定时器1中断服务函数
u8 overflow_cnt=0;//溢出次数
void TIM1_UP_IRQHandler(void)
{
if(TIM_GetITStatus(TIM1,TIM_IT_Update)==SET) //溢出中断
{
overflow_cnt++;
printf("\r\n*********测速计数溢出***********\r\n");
}
TIM_ClearITPendingBit(TIM1,TIM_IT_Update); //清除中断标志位
}
一开始,中断服务函数名称写错成TIM1_IRQHandler,导致没有进入中断,看了下启动文件中的中断函数名发现定时器1有好几个中断函数,于是便看了下数据手册的说明,才发现是错了,改正后,程序正常。
主函数那边printf("CNT:%d\r\n",TIM_GetCounter(TIM1));获取计数值,打开串口调试助手,再用小磁钢在模块旁边甩动,一开始小磁钢的方向放错了,导致计数值一直没增加,改用按键输入脉冲调试了一会想到会不会是因为磁场方向问题,换了下小磁钢的方向,计数值就增加了,哎。

因为用了delay函数延时显示避免刷屏,所以有点跳数了,不过数值还是正确的。
|
|