首页 » 互联网 » 基于STM32 的带AB相编码器的直流电机底层驱动调试(上)-底层_编码器_速度

基于STM32 的带AB相编码器的直流电机底层驱动调试(上)-底层_编码器_速度

萌界大人物 2024-08-29 04:40:51 0

扫一扫用手机浏览

文章目录 [+]

毕业一年后才正式从事STM32干系的开拓,现在的能力也不过入门级别.只想把当前学到的一些东西和大家分享,自己也能巩固下一下,希望能帮到某些须要的朋友.

学习STM32,创造它的定时器是一个难点,至今还有很多地方捉摸不透,当然,如果只是利用普通定时功能就不多说了.掌握直流电机,PWM调速是必备,可是做小车速率一定要做到闭环掌握,以是得有编码器.查阅手册,STM32的定时器还支持AB相正交编码器功能,实在令人高兴,无需再用定时器的输入补获功能来打算速率了.

基于STM32 的带AB相编码器的直流电机底层驱动调试(上)-底层_编码器_速度 基于STM32 的带AB相编码器的直流电机底层驱动调试(上)-底层_编码器_速度 互联网

作为AGV小车,最最少的功能得是循迹吧!低真个便是学校用的光电循迹,白底黑线跑道.轻微高等点的是巡磁轨道,磁感应传感器加磁条的方案,相比拟较稳定,只是本钱要高许多,更高真个该当便是SLAM激光导航模块+惯性导航构建舆图来循迹,这种要繁芜很多,目前也只是理解一些事理,而前两种已经实践过.就目前履历而谈,第一种适宜学习(当初贴轨道可是花了我大把韶光和体力),第二种适宜低级运用,第三种就适宜高等运用处所了. (以前飞思卡尔的摄像头,光电,电磁循迹方案彷佛只是用于竞赛,没把稳到有什么实际运用) 唉!废话说的有点多.......

基于STM32 的带AB相编码器的直流电机底层驱动调试(上)-底层_编码器_速度 基于STM32 的带AB相编码器的直流电机底层驱动调试(上)-底层_编码器_速度 互联网
(图片来自网络侵删)

电机选型:JGB37-545B带AB相编码器直流减速电机

驱动芯片:LMD18200T

MCU:STM32F103VET6

电机PWM接口利用定时器4的通道1和2,编码器接口利用定时器1和定时器2的正交编码器接口.电机初始化函数如下:

void Motor_Init(void)

{

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

TIM_OCInitTypeDef TIM_OCInitStructure;

TIM_ICInitTypeDef TIM_ICInitStructure;

GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO, ENABLE) ;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4 , ENABLE);

GPIO_PinRemapConfig(GPIO_Remap_TIM4, ENABLE);

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz ;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10; //方向掌握引脚

GPIO_Init(GPIOD, &GPIO_InitStructure);

GPIO_ResetBits(GPIOD,GPIO_Pin_9|GPIO_Pin_10);

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 ; //PWM输出引脚

GPIO_Init(GPIOD, &GPIO_InitStructure);

TIM_DeInit(TIM4);

TIM_TimeBaseStructure.TIM_Period = 100-1;

TIM_TimeBaseStructure.TIM_Prescaler = 72-1; //周期10K

TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数模式

TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);

TIM_ARRPreloadConfig(TIM4, ENABLE);

TIM_OCStructInit(&TIM_OCInitStructure);

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

TIM_OCInitStructure.TIM_Pulse = 0;

TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

TIM_OC1Init(TIM4, &TIM_OCInitStructure);

TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);

TIM_OC2Init(TIM4, &TIM_OCInitStructure);

TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable); //定时器4的2路比较输出功能使能

TIM_Cmd(TIM4, ENABLE);

// 编码器 1 //

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);

GPIO_PinRemapConfig(GPIO_FullRemap_TIM1, ENABLE); //利用IO重映射功能

GPIO_StructInit(&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_11 ;

GPIO_Init(GPIOE, &GPIO_InitStructure);

TIM_DeInit(TIM1);

TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);

TIM_TimeBaseStructure.TIM_Period = 0xFFFF;

TIM_TimeBaseStructure.TIM_Prescaler = 0;

TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

TIM_EncoderInterfaceConfig(TIM1, TIM_EncoderMode_TI1, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising); //利用编码器模式1,只能反响出速率 ,如果须要反响出方向,可以利用TIM_EncoderMode_TI12,双向计数模式

TIM_ICStructInit(&TIM_ICInitStructure);

TIM_ICInitStructure.TIM_Channel = TIM_Channel_1 ;

TIM_ICInitStructure.TIM_ICFilter = 15; //

TIM_ICInit(TIM1, &TIM_ICInitStructure);

TIM_ICInitStructure.TIM_Channel = TIM_Channel_2 ;

TIM_ICInitStructure.TIM_ICFilter = 15;//选择输入比较滤波器

TIM_ICInit(TIM1, &TIM_ICInitStructure);

TIM_ClearFlag(TIM1, TIM_FLAG_Update);//清TIM更新标志

TIM_SetCounter(TIM1,0);

TIM_Cmd(TIM1, ENABLE);

// 编码器2 //

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

GPIO_StructInit(&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 ;

GPIO_Init(GPIOA, &GPIO_InitStructure);

TIM_DeInit(TIM2);

TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);

TIM_TimeBaseStructure.TIM_Period = 0xFFFF;

TIM_TimeBaseStructure.TIM_Prescaler = 0;

TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI1, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);

//TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI12, TIM_ICPolarity_BothEdge , TIM_ICPolarity_BothEdge);

TIM_ICStructInit(&TIM_ICInitStructure);

TIM_ICInitStructure.TIM_Channel = TIM_Channel_1 ;

TIM_ICInitStructure.TIM_ICFilter = 15;

TIM_ICInit(TIM2, &TIM_ICInitStructure);

TIM_ICInitStructure.TIM_Channel = TIM_Channel_2 ;

TIM_ICInit(TIM2, &TIM_ICInitStructure);

TIM_ClearFlag(TIM2, TIM_FLAG_Update);

TIM_SetCounter(TIM2,0);

TIM_Cmd(TIM2, ENABLE);

}

设置速率宏定义,这里只是设定占空比,如需设置详细速率(如cm/s)须要重新封装

#define MOTOR_SET_SPEED_R(spd)TIM_SetCompare1(TIM4,spd)

#define MOTOR_SET_SPEED_L(spd)TIM_SetCompare2(TIM4,spd)

实际运用时须要知道一些固定参数,如轮子直径,电机减速比,从而将输出的脉冲(占空比)对应到详细的速率值.

复位编码器值:

#define MOTOR_RESET_ENCODER_R()TIM_SetCounter(TIM1,0)

#define MOTOR_RESET_ENCODER_L()TIM_SetCounter(TIM2,0)

读编码器值:

#define MOTOR_READ_ENCODER_R()-TIM_GetCounter(TIM1)

#define MOTOR_READ_ENCODER_L()TIM_GetCounter(TIM2)

就写到这里吧,写的不是很清楚.底层驱动网上例程很多,很随意马虎调试.运用中更看重方法,思路无非便是调节占空比掌握速率,读编码器单位韶光输入脉冲数得到速率,然后加上PID调节使速率稳定.关于PID方面的个人理解下次再来分享!

标签:

相关文章

基带技术,通信领域的基石与未来

随着信息技术的飞速发展,通信技术已经成为现代社会不可或缺的一部分。在通信技术的众多领域中,基带技术扮演着至关重要的角色。本文将围绕...

互联网 2025-01-07 阅读0 评论0

壁纸代码雨,数字之美与编程魅力

在这个数字时代,人们越来越离不开计算机,而计算机的诞生与发展离不开编程。编程作为计算机的灵魂,已经成为现代社会不可或缺的一部分。而...

互联网 2025-01-07 阅读0 评论0

多通道技术,未来科技发展的新引擎

在科技飞速发展的今天,多通道技术已经成为推动科技创新的重要力量。所谓多通道技术,指的是利用多个通道同时传输和处理信息的技术。这一技...

互联网 2025-01-07 阅读0 评论0

多端同步协议,构建高效协同工作的桥梁

在当今信息爆炸的时代,多端同步协议成为连接不同设备、实现数据共享的关键技术。多端同步协议通过高效、稳定的数据传输,助力各行业实现协...

互联网 2025-01-07 阅读0 评论0