中级会员
- 积分
- 315
- 金钱
- 315
- 注册时间
- 2016-3-29
- 在线时间
- 46 小时
|
发表于 2017-11-30 09:41:31
|
显示全部楼层
本人想通过stm32f103zet6进行光栅尺测速,具体实施方案是将一块连接板一端连接光栅尺读数头,另一端连接一根移动杆。想通过程序来检测移动杆移动的速度并显示在板子的LCD屏幕上。
具体思路是设置两个定时器,其中Time4在编码器模式,用于检测位移。另外一个Time2每隔10ms中断一次,中断服务函数中用TIM_GetCounter取中断时刻的TIM4->CNT值减去10ms前的CNT值。得到位移差,再用位移差除以10ms求得平均速度。程序如下,但是串口打印出来的数据总是不是速度。帮忙看一下,谢谢!
extern u16 deep,speed,deep1;
static u16 lastCount,currCount;
void TIM4_Init(u16 deep)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
/*- 正交编码器输入引脚 PB->6 PB->7 -*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/*- TIM4编码器模式配置 -*/
TIM_DeInit(TIM4);
TIM_TimeBaseStructure.TIM_Period = deep;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision =TIM_CKD_DIV1 ;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
TIM_EncoderInterfaceConfig(TIM4, TIM_EncoderMode_TI12, TIM_ICPolarity_BothEdge ,TIM_ICPolarity_BothEdge); //配置编码器模式触发源和极性
TIM_ICStructInit(&TIM_ICInitStructure); //配置滤波器
TIM_ICInitStructure.TIM_ICFilter = 6;
TIM_ICInit(TIM4, &TIM_ICInitStructure);
TIM_ClearFlag(TIM4, TIM_FLAG_Update);//TIM4
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);//
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; //TIM4中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占优先级0级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级3级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器
TIM4->CNT = 0;
TIM_Cmd(TIM4, ENABLE); //启动TIM4定时器
}
extern u8 curr_flag;
void TIM4_IRQHandler(void) //TIM3中断
{
if (TIM_GetITStatus(TIM4,TIM_IT_Update) != RESET) //检查TIM3更新中断发生与否
{
TIM_ClearITPendingBit(TIM4,TIM_IT_Update ); //清除TIMx更新中断标志
TIM_ClearFlag(TIM4, TIM_FLAG_Update);//清除TIM7待处理标志位
curr_flag=0;
TIM3->CCR1 = 0000;
TIM3->CCR2 = 1000;
}
}
void TIM2_Int_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //时钟使能
//定时器TIM3初始化
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断
//中断优先级NVIC设置
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn ; //TIM3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级3级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器
TIM2->CNT=0;
TIM_Cmd(TIM2, ENABLE); //使能TIMx
}
//定时器2中断服务程序
void TIM2_IRQHandler(void) //TIM3中断
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) //检查TIM2更新中断发生与否
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update ); //清除TIMx更新中断标志
currCount=TIM_GetCounter(TIM4);
speed=(currCount-lastCount)*0.1;
lastCount=currCount;
printf("speed=%d,deep1=%d\n",speed,deep1);
}
}
|
|