一、准备工作:
有关CUBEMX的初始化配置,参见我的另一篇blog:【STM32+HAL】CUBEMX初始化配置
有关LCD的初始化配置,参见我的另一篇blog:【STM32+HAL】LCD显示及触摸初始化配置
二、所用工具:
1、芯片: STM32F407ZGT6
2、STM32CubeMx软件
3、显示屏:正点原子4.3寸TFT LCD MCU电阻屏 480*800
4、驱动器:L298N
5、电机:MG310电机(GMR编码器)
三、实现功能:
实现对直流减速电机的PID控制及转速显示
四、HAL配置步骤:
1、定时器配置
2、编码器配置
编码器用于读取电机转速,原理详见下附链接
3、PWM配置
4、中断配置
至此,HAL库配置完成
五、硬件连接:
根据芯片原理图,
L298N:PA7(PWM输出IO口)接L298N的IN1,IN2接地,12V供电接输入电压源正极,电压源负极接单片机GND,GND接单片机GND,输出A接电机正负极
编码器:PA6,PC7(编码器IO口)分别接编码器A、B相
六、KEIL填写代码:
1、初始化
HAL_TIM_Encoder_Start(&htim3, TIM_CHANNEL_ALL);//开启编码器
HAL_TIM_Base_Start_IT(&htim3);//开启编码器中断
HAL_TIM_Base_Start_IT(&htim2);//开启定时器中断
HAL_TIM_PWM_Start(&htim14,TIM_CHANNEL_1);//开启PWM波
HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);//串口接收初始化
LCD_Init();
POINT_COLOR=RED; //LCD显示初始化
LCD_Clear(WHITE);
tp_dev.init(); //LCD触摸初始化
2、PWM波生成模块
void Generate(void)
{
if(flag_pwm){ //PWM开关
if(Bias<-3||Bias>3)//偏差过小时不开启改变
Cnt+=Bias;
Cnt=(Cnt>9992)?9992:Cnt;//防溢出
TIM14->CCR1=Cnt;
}
}
3、读取电机速度模块
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
UNUSED(htim);
if(htim->Instance==TIM2){
Encode = (short)(__HAL_TIM_GET_COUNTER(&htim3));
__HAL_TIM_SET_COUNTER(&htim3,0);
Bias=PID(Encode,SetSpeed);
}
}
4、PID偏差计算模块
int PID(int current,int target) //PID速度控制
{
static int LastError; //Error[-1]
static int PrevError; //Error[-2]
int iError,Outpid; //当前误差
target=target/0.15; //将速度值转换为编码值
iError=target-current; //增量计算
Outpid=(Proportion * iError) //E[k]项
-(Integral * LastError) //E[k-1]项
+(Derivative * PrevError); //E[k-2]项
PrevError=LastError; //存储误差,用于下次计算
LastError=iError;
return Outpid;
}
七、原理讲解
STM32Cube HAL库——霍尔编码器测速(电机转速测量)
HAL库版STM32双轮自平衡车(一) ———代码思路和PID基础精讲
八、源码提供
九、更多细节
1、编码器检测电机正反转:
dir = __HAL_TIM_IS_TIM_COUNTING_DOWN(&htim3);
2、L298N正反转:
需配置两路PWM输入IN1,IN2
void PWM_Select(int x)
{
if(x==0) PWMA=0,PWMB=0;
else if(x==1) PWMA=Moto,PWMB=0;
else if(x==2) PWMA=0,PWMB=Moto;
}