电机编码器(Encoder)

宏定义

定时器的自动重装载值,不可大于65535 因为F103的定时器是16位的。
#define ENCODER_TIM_PERIOD (u16)(65535)

计算转速需要的参数
#define PI 3.14159265 //PI圆周率
#define Control_Frequency 200.0 //编码器读取频率
#define Diameter_67 67.0 //轮子直径67mm
#define EncoderMultiples 4.0 //编码器倍频数
#define Encoder_precision 11.0 //编码器精度 11线
#define Reduction_Ratio 30.0 //减速比30
#define Perimeter 210.4867 //周长,单位mm

Control_Frequency=200 意味着Read_Encoder()的取值周期为5ms



左右轮的ID
typedef enum {
MOTOR_ID_ML = 0,
MOTOR_ID_MR,
MAX_MOTOR
} Motor_ID;

方法

如果要使用电机Motor, 请确保初始化电机的函数要在初始化编码器定时器的函数之前调用!!

Encoder_Init_TIM3(void)

初始化TIM3定时器

设置项目 设置值
预分频器 0
自动重装值 ENCODER_TIM_PERIOD(具体值需查看代码)
时钟分频 不分频 (TIM_CKD_DIV1)
计数模式 向上计数 (TIM_CounterMode_Up)
输入捕获滤波 10
GPIO引脚 GPIO_Pin_6 和 GPIO_Pin_7
GPIO模式 浮空输入 (GPIO_Mode_IN_FLOATING)
定时器3时钟使能 使能定时器3的时钟
PA端口时钟使能 使能PA端口时钟
编码器模式 编码器模式3 (TIM_EncoderMode_TI12)
输入捕获极性 上升沿触发 (TIM_ICPolarity_Rising)
TIM更新标志位清除 清除TIM的更新标志位
TIM更新中断使能 使能TIM更新中断

Encoder_Init_TIM4(void)

初始化TIM4定时器

设置项目 设置值
定时器结构体 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure
输入捕获结构体 TIM_ICInitTypeDef TIM_ICInitStructure
GPIO初始化结构体 GPIO_InitTypeDef GPIO_InitStructure
定时器4时钟使能 使能定时器4的时钟 (RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE))
PB端口时钟使能 使能PB端口时钟 (RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE))
GPIO引脚配置 GPIO_Pin_6 | GPIO_Pin_7
GPIO模式 浮空输入 (GPIO_Mode_IN_FLOATING)
GPIO初始化 根据设定参数初始化GPIOB (GPIO_Init(GPIOB, &GPIO_InitStructure))
定时器基础配置初始化 TIM_TimeBaseStructInit(&TIM_TimeBaseStructure)
预分频器 0x0
计数器自动重装值 ENCODER_TIM_PERIOD
时钟分频 不分频 (TIM_CKD_DIV1)
计数模式 向上计数 (TIM_CounterMode_Up)
定时器初始化 TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure)
编码器接口配置 使用编码器模式3 (TIM_EncoderInterfaceConfig(TIM4, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising))
输入捕获结构体初始化 TIM_ICStructInit(&TIM_ICInitStructure)
输入捕获滤波 10
输入捕获初始化 TIM_ICInit(TIM4, &TIM_ICInitStructure)
TIM更新标志位清除 清除TIM的更新标志位 (TIM_ClearFlag(TIM4, TIM_FLAG_Update))
TIM更新中断使能 使能TIM更新中断 (TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE))

Read_Encoder(Motor_ID MYTIMX)

单位时间读取编码器计数

Read_Encoder() 读取到的是从上一次调用Read_Encoder()到这一次调用Read_Encoder()这段时间内编码器的计数

为了计算转速, 需要以固定的时间间隔调用Read_Encoder()

参数类型注释
MYTIMXMotor_ID选择一个电机读取
Motor_ID可选参数 MOTOR_ID_ML/MOTOR_ID_MR
返回值类型
编码器计数int

Get_Velocity_From_Encoder(int encoder_left, int encoder_right);

返回左右轮的转速, 单位为mm/s

此函数默认是以5ms作为测速周期, 对应着宏定义中的 Control_Frequency=200 (T=1/f)

参数类型注释
encoder_leftint左电机编码器值
encoder_rightint右电机编码器值
返回值类型
velocitiesfloat*
返回值为一个速度数组
velocities[0]是左电机速度
velocities[1]是右电机速度, 单位为mm/s

TIM3_IRQHandler(void);

定时器3中断处理函数

TIM4_IRQHandler(void);

定时器4中断处理函数

使用示例


//  导入部分代码省略 
int main() {
    Encoder_Init_TIM3();
    Encoder_Init_TIM4();
    int left_count = 0;
    int right_count = 0;
    while(1) {
        //  取5ms作为测速周期, 对应着宏定义中的 Control_Frequency=200 (T=1/f)
        delay_ms(5);
        left_count += Read_Encoder(MOTOR_ID_ML);
        right_count += Read_Encoder(MOTOR_ID_MR);
        printf("L: %d, R: %d\n", left_count, right_count);
    }
    return 0;
}