用定时器的编码器模式实现正反转脉冲数,TI1的边沿计数,重载寄存器ARR的值设为359。
当编码器正转时,计数器CNT能从0向上计数增加至359后,然后CNT清0,同时产生更新事件,再向上计数。
但是,当编码器反转,CNT由当前值减为0后,就一直为0,CNT不重置成359。CNT应重置成359向下计数才对呀,
为什么会这样,请教高人!
手上没有编码器,我用STM32的端口模拟输出正交的编码器脉冲信号。
下面是编码器模式配置代码
void TIM5_Mode_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //时基结构
TIM_ICInitTypeDef TIM_ICInitStructure; //脉冲输入结构体
TIM_TimeBaseStructure.TIM_Prescaler=0; //定时器时钟设为72M
//TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //其实不用配置计数方式,硬件会根据编码器的正反转确定向上或向下计数
TIM_TimeBaseStructure.TIM_Period=0X167; //设置重载寄存器的值,ARR=359
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; //频率给滤波器用,频率对外部时钟滤波
TIM_TimeBaseInit(TIM5,&TIM_TimeBaseStructure);
TIM_EncoderInterfaceConfig(TIM5, TIM_EncoderMode_TI1, //调用库函数中的编码器接口模式函数
TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
TIM_ICStructInit(&TIM_ICInitStructure);
TIM_ICInitStructure.TIM_ICFilter = 6; //ICx_FILTER;
TIM_ICInit(TIM5, &TIM_ICInitStructure);
TIM_ClearFlag(TIM5, TIM_FLAG_Update);
TIM_ITConfig(TIM5, TIM_IT_Update, ENABLE);
TIM5->CR1|=0x01; //使能CR1计数器中的CNT位
TIM5->CNT = 0;
TIM_Cmd(TIM5, ENABLE);
}
下面是STM32端口模拟输出正交编码器信号
void Encoder_PulseOut(uint16_t n) //模拟编码器正转信号,A相超前B相90°,PB1输出A相脉冲,PB2输出B相脉冲
{
for(;n>0;n--)
{
GPIO_SetBits(GPIOB,GPIO_Pin_1);
delay(0x7FF);
GPIO_SetBits(GPIOB,GPIO_Pin_2);
delay(0x7FF);
GPIO_ResetBits(GPIOB,GPIO_Pin_1);
delay(0x7FF);
GPIO_ResetBits(GPIOB,GPIO_Pin_2);
delay(0x7FF);
}
}
void Encoder_PulseOut_REV(uint16_t n) //模拟编码器反转信号,A相滞后B相90°
{
for(;n>0;n--)
{
GPIO_SetBits(GPIOB,GPIO_Pin_2);
delay(0x7FF);
GPIO_SetBits(GPIOB,GPIO_Pin_1);
delay(0x7FF);
GPIO_ResetBits(GPIOB,GPIO_Pin_2);
delay(0x7FF);
GPIO_ResetBits(GPIOB,GPIO_Pin_1);
delay(0x7FF);
}
}
下面是主函数
int main(void)
{
Encoder_PulseOut(3600); //编码器正转,输出正交编码器脉冲3600
Delay(0x1FF); //编码器暂停一会儿
Encoder_PulseOut_REV(3650); //编码器反转,输出脉冲3650个
n_Counter = TIM_GetCounter(TIM5)/2; //IC1相对于IC2每个脉冲内有两次上升沿
if((TIM5->CR1&0x0010)==0x0010) //通过串口读出编码器正反转
printf("\r\n编码器反转\r\n");
else printf("\r\n编码器正转\r\n");
while(1);
}
设ARR=359,编码器先正转3600个脉冲,再反转3650个脉冲,CNT中的值应为310才对,但是串口读出来的CNT=0,而且一直停在0了,为什么?
这个问题困扰我很久,一直没解决,太痛苦了!参考了各种例程,都是这么配置的,为什么就不能对,请高人指导!
|