新手入门
- 积分
- 16
- 金钱
- 16
- 注册时间
- 2021-5-25
- 在线时间
- 10 小时
|
20金钱
现象1:只能检测一个方向的脉冲,反向不计数现象2:引脚设置为浮空模式时,在不连接编码器的情况下,甚至是只接杜邦线的情况下,编码器会自动计数
现象3:引脚设置为上拉输入模式时,编码器接电后,在不转动的情况下依然会自动计数
现象4:定时器2在上拉输入模式下计数缓慢,跟不上转动速度,定时器3在上拉输入模式下,会自动计数。
现象5:编码器引脚在接电后,以万用电表检测脉冲引脚有±0.08v的电压跳变
现象6:编码器方向读取不准,时常出现:00010010001011010或11110111010111001,推测这是计数问题的原因之一
硬件信息:
以上用的编码器实则为拉线传感器,其内核还是增量式编码器(AB相);
传感器已送回商家检测过,对方以示波器检测,表明传感器准确无误;
单片机为STM32F103ZE核心板;也用NANO板尝试过,现象一致;
注:目前仅用多个定时器对单个拉线传感器脉冲数进行测量,并未同时测量3个编码器;
以下为代码部分:
void BianMQ_GPIO_Init()
{
// 结构体
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_ICStructInit(&TIM_ICInitStructure); //清空结构体
TIM_TimeBaseStructInit(&TIM_TimeBaseInitStructure); //清空结构体
// 使能引脚及定时器
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能PA/B端口时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //使能定时器2、3、4端口时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_TIM4,ENABLE); //TIM4引脚复用
GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2,ENABLE); //TIM2引脚复用模式1
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
// GPIO_PinRemapConfig(GPIO_FullRemap_TIM3,ENABLE);
// 引脚配置
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_6|GPIO_Pin_7; //对应定时器3的通道1、2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13; //对应定时器4的通道1、2
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //对应定时器2的通道1、2
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_Init(GPIOB, &GPIO_InitStructure);
// 定时器配置
TIM_DeInit(TIM2); //初始化
TIM_DeInit(TIM3);
TIM_DeInit(TIM4);
TIM_TimeBaseInitStructure.TIM_Period=(2000-1)*4; //设定计数器自动重装值
TIM_TimeBaseInitStructure.TIM_Prescaler=0; //预分频系数
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; //选择时钟分频:不分频
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);
TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);
//编码器配置
TIM_EncoderInterfaceConfig(TIM2,TIM_EncoderMode_TI12,TIM_ICPolarity_BothEdge,TIM_ICPolarity_BothEdge); //TIM_ICPolarity_Rising、TIM_ICPolarity_BothEdge,都尝试过,现象一致
TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12,TIM_ICPolarity_BothEdge,TIM_ICPolarity_BothEdge);
TIM_EncoderInterfaceConfig(TIM4,TIM_EncoderMode_TI12,TIM_ICPolarity_BothEdge,TIM_ICPolarity_BothEdge);
TIM_ICStructInit(&TIM_ICInitStructure); //清空结构体
TIM_ICInitStructure.TIM_ICFilter =10; //配置滤波器
TIM_ICInit(TIM2,&TIM_ICInitStructure);
TIM_ICInit(TIM3,&TIM_ICInitStructure);
TIM_ICInit(TIM4,&TIM_ICInitStructure);
//溢出中断设置
NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel=TIM4_IRQn;
NVIC_Init(&NVIC_InitStructure);
TIM_ClearITPendingBit(TIM2, TIM_IT_Update );
TIM_ClearITPendingBit(TIM3, TIM_IT_Update );
TIM_ClearITPendingBit(TIM4, TIM_IT_Update );
TIM_ClearFlag(TIM2,TIM_FLAG_Update); //清楚TIM的更新标志位
TIM_ClearFlag(TIM3,TIM_FLAG_Update);
TIM_ClearFlag(TIM4,TIM_FLAG_Update);
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);
//计数值清0
TIM_SetCounter(TIM2,0);
TIM_SetCounter(TIM3,0);
TIM_SetCounter(TIM4,0);
TIM_Cmd(TIM2,ENABLE);
TIM_Cmd(TIM3,ENABLE);
TIM_Cmd(TIM4,ENABLE);
}
/************************************************
函数名称 : ENCODER_Read
功 能 : 读取编码器数据
参 数 : Dir --- 方向
Cnt --- 计数
返 回 值 : 无
*************************************************/
/*
void ENCODER_Read(int *Dir, int *Cnt)
{
Dir[0]= TIM2->CR1>>4 & 0x01; //判断方向
Cnt[0]= TIM_GetCounter(TIM2); //读取计数值
}
*/
int circle_count[3]={0,0,0}; //圈数
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)
{
if((((TIM2->CR1)>>4) & 0x01)==0) //判断方向:DIR==0
circle_count[0]++;
else if((((TIM2->CR1)>>4) & 0x01)==1) //判断方向:DIR==1
circle_count[0]--;
}
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET)
{
if((((TIM3->CR1)>>4) & 0x01)==0)
circle_count[1]++;
else if((((TIM3->CR1)>>4) & 0x01)==1)
circle_count[1]--;
}
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
}
void TIM4_IRQHandler(void)
{
if(TIM_GetITStatus(TIM4,TIM_IT_Update)==SET)
{
if((((TIM4->CR1)>>4) & 0x01)==0)
circle_count[2]++;
else if((((TIM4->CR1)>>4) & 0x01)==1)
circle_count[2]--;
}
TIM_ClearITPendingBit(TIM4,TIM_IT_Update);
}
还请各位大佬帮忙看看,已经尝试两周了,还没人指导,真找不着原因。拜谢!
|
|