正交编码器:
每个高级定时器与通用定时器都具有一个编码器接口,如果用了编码器接口就用不了该定时器了。
输入引脚为输入捕获的通道1和通道2(CH1和CH2),CH3和CH4不能接编码器。
正反转对应另一相的状态是相反的。
工作原理:
出现边沿信号,计数器自增或自减,当出现某个边沿时,判断另一项的电平。
输入捕获滤波器以及边沿检测也有使用,但是后面的是否交叉,预分频器和CCR寄存器与编码器接口无关。
656535 的16位无符号数转化为16位有符号数后,65535对应的为-1,即反转。
在TI1和TI2都计数,精度更高。
正交编码器抗噪声:
引脚反向----->改变计数方向。
接线方法:
PA6和PA7对应CH1和CH2,不能其他。
代码部分:
1. RCC开启时钟 开启GPIO和定时器的时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
2. 配置GPIO,将PA6和PA7配置为输入模式
GPIO_InitTypeDef GPIOInitstructure;
GPIOInitstructure.GPIO_Mode= GPIO_Mode_IPU;
GPIOInitstructure.GPIO_Pin= GPIO_Pin_6 | GPIO_Pin_7;
GPIOInitstructure.GPIO_Speed= GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIOInitstructure);
3. 配置时基单元,预分频PSC,自动重装ARR,计数器CNT
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Period= 65536 - 1;
TIM_TimeBaseInitStructure.TIM_Prescaler= 1 - 1;
TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);
4. 配置两个通道的输入捕获单元,滤波器和极性选择
TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_ICStructInit(&TIM_ICInitStructure);
TIM_ICInitStructure.TIM_Channel= TIM_Channel_1;
TIM_ICInitStructure.TIM_ICFilter= 0xF;
TIM_ICInitStructure.TIM_ICPolarity= TIM_ICPolarity_Rising;//此处的上升沿表示极性不反相
TIM_ICInit(TIM3,&TIM_ICInitStructure);
TIM_ICInitStructure.TIM_Channel= TIM_Channel_2;
TIM_ICInitStructure.TIM_ICFilter= 0xF;
TIM_ICInitStructure.TIM_ICPolarity= TIM_ICPolarity_Rising;//此处的上升沿表示极性不反相
TIM_ICInit(TIM3,&TIM_ICInitStructure);
5. 配置编码器接口模式
TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising);//TIM_ICPolarity_Rising为不反相
6. 启动定时器
TIM_Cmd(TIM3,ENABLE);
注意:
不需要定时器内部时钟配置:(编码器接口为一个带方向控制的外部时钟,内部时钟失去作用)
TIM_InternalClockConfig(TIM3);
不需要配置计数器模式:(计数方向由编码器决定)
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
自动重装值给65535,方便-1的换算
TIM_TimeBaseInitStructure.TIM_Period= 65536 - 1;
预分频系数不分频:
TIM_TimeBaseInitStructure.TIM_Prescaler= 1 - 1;
结构体的配置不完整:给结构体赋一个初始值防止不确定值出现问题
TIM_ICStructInit(&TIM_ICInitStructure);
结构体变量的配置,在调用完ICInit之后,被写入到硬件寄存器中,再次配置不需要使用另一个结构体变量
编码器函数:(编码器测量位置)
uint16_t Encoder_Get(void)
{
return TIM_GetCounter(TIM3);
}
类型强制转换:
int16_t Encoder_Get(void)
{
return TIM_GetCounter(TIM3);
}
编码器测速:
在固定的闸门时间,测出CNT的值,并将其清0
int16_t Encoder_Get(void)
{
uint16_t Temp;
Temp = TIM_GetCounter(TIM3);
TIM_SetCounter(TIM3,0);
return Temp;
}
电机飞速旋转时,闸门时间短一点:
while(1)
{
OLED_ShowSignedNum(2,5,Encoder_Get(),5);
Delay_ms(1000);
}
将其放到定时器里,防止主函数堵塞