STM32f103c8t6正交编码器读取问题

第一次写博客,还请大佬们多多指教。下面进入正题。
首先我们先要了解编码器的工作原理。电机在带动码盘转动时,码盘会产生A、B两相脉冲信号,二者相位差90度(正交)。即可以根据信号来的先后判断电机转动的方向(顺、逆)。根据得到的脉冲信号多少及码盘线数(**电机每圈所产生脉冲信号数,可以问商家)**及电机减速比就可以算出电机转了多少圈在结合轮的直径便可以算出车走的距离,若加上定时器便可以计算出电机的转速。
那么该如何获取编码器的值呢?(1)通过定时器输入捕获。(2)IO口外部中断来检测边缘信号。这两个思路在单片机上都行的通。但是STM32单片机具有硬件计数方式。下面就讲下该如何去配置软件。
首先呢就是CH1.CH2(通道1、2)的IO口配置。(必须为每个定时器的CH1、CH2,原因下面会讲)由于编码器的输出模式是开漏输出的所以IO口要配为上拉输入模式
编码器模式配置有三种:
TIM_EncoderMode_TI1,计数器仅在TI1的边沿处计数
TIM_EncoderMode_TI2时,计数器仅在TI2的边沿处计数
TIM_EncoderMode_TI12时,计数器在TI1和TI2边沿处均计数
从上面编码器模式来看就不难理解了为啥一定要配置定时器CH1、CH2IO口为编码器读取IO口了。
模式1、模式2基本是一样的,实际中很少去使用,因为误差太大。模式3就是大家熟知的4倍频原理。STM32f103c8t6正交编码器读取问题_第1张图片这是参考手册里的一张图片。用上它来讲解就应该会清楚很多了。由图可以看出模式1、模式2只是单通道计数,计数方式(向上、向下)则是由另一个通道决定的。
模式3则是全计数方式。STM32f103c8t6正交编码器读取问题_第2张图片
当选择模式1时,TI2为低电平时TI1上升沿时便开始向上计数。(此时可以理解为电机正传)。TI2为高电平时TI1上升沿时便开始向下计数。(此时可以理解为电机反传)。(模式2原理一样)
当选择模式3时,TI1、TI2、的跳变沿(上升、下降)全都被检测,则每个实际来的脉冲信号被检测了4次。(这就是4倍频)因此当我们设置重装在值时应为【编码器线数*4】。
`void Encoder_Init_TIM2(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//使能定时器2的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能PB端口时钟

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1; //端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOA

TIM_DeInit(TIM2);

TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // 预分频器
TIM_TimeBaseStructure.TIM_Period = 3112; //设定计数器自动重装值 4倍频
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//选择时钟分频:不分频
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;////TIM向上计数
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI1, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//编码器模式选择

TIM_ICStructInit(&TIM_ICInitStructure);//滤波器配置
TIM_ICInitStructure.TIM_ICFilter = 1;
TIM_ICInit(TIM2, &TIM_ICInitStructure);

TIM_ClearFlag(TIM2, TIM_FLAG_Update);//清除TIM的更新标志位
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
//Reset counter
TIM_SetCounter(TIM2,0);
TIM_Cmd(TIM2, ENABLE);
}`

int read_encoder_cnt(u8 TIMX)
{	int Encoder_TIM;    
   switch(TIMX)
	 {
	   case 2:  Encoder_TIM= (short)TIM2 -> CNT;  TIM2 -> CNT=0;break;	
		 case 4:  Encoder_TIM= (short)TIM4 -> CNT;  TIM4 -> CNT=0;break;	
		 default: Encoder_TIM=0;
	 }
		return Encoder_TIM;
}

你可能感兴趣的:(STM32f103c8t6正交编码器读取问题)