stm小车HAL库 测速 PID调速 蓝牙 OLED使用

//重定向 串口一
int fputc(int ch,FILE *stream)
{
HAL_UART_Transmit(&huart1,( uint8_t *)&ch,1,0xFFFF);
return ch;
}

//typedef struct __FILE FILE; 使用printf时要加上 #include<stdio.h>;
2.串口中断回调函数
uint8_t g_ucUsart3ReceiveData; //保存串口三接收的数据 main.c

HAL_UART_Receive_IT(&huart3,&g_ucUsart3ReceiveData,1); //串口三接收数据 main.c中开启


//在it.c 重新实现串口中断回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if( huart == &huart3)//判断中断源
{
if(g_ucUsart3ReceiveData == 'A') motorPidSetSpeed(1,1);//前运动

HAL_UART_Receive_IT( &huart3, &g_ucUsart3ReceiveData, 1);//继续进行中断接收

}
}


//在usart.c中声明外部变量
extern uint8_t g_ucUsart3ReceiveData; //保存串口三接收的数据

3.pwm

HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);//开启定时器1 通道1 PWM输出
HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_4);//开启定时器1 通道4 PWM输出


__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 40);//修改占空比

 4.电平配置

HAL_GPIO_WritePin(AIN1_GPIO_Port,AIN1_Pin,GPIO_PIN_RESET);//设置AIN1 PB13为 低电平
HAL_GPIO_WritePin(BIN1_GPIO_Port,BIN1_Pin,GPIO_PIN_SET); //设置BIN1 PB3为高电平
HAL_Delay(1000);
//两次会使得电机反向。
HAL_GPIO_WritePin(AIN1_GPIO_Port,AIN1_Pin,GPIO_PIN_SET);//设置AIN1 PB13为 高电平
HAL_GPIO_WritePin(BIN1_GPIO_Port,BIN1_Pin,GPIO_PIN_RESET); //设置BIN1 PB3为低电平

5.电机

//防重定义函数
#ifndef MOTOR_H__
#define MOTOP_H__


#endif




//定义宏方便移植
#define AIN1_RESET HAL_GPIO_WritePin(AIN1_GPIO_Port,AIN1_Pin,GPIO_PIN_RESET)//设
置AIN1 PB13为 低电平
#define AIN1_SET HAL_GPIO_WritePin(AIN1_GPIO_Port,AIN1_Pin,GPIO_PIN_SET)//设置
AIN1 PB13为 高电平
#define BIN1_RESET HAL_GPIO_WritePin(BIN1_GPIO_Port,BIN1_Pin,GPIO_PIN_RESET)
//设置BIN1 PB3为低电平
#define BIN1_SET HAL_GPIO_WritePin(BIN1_GPIO_Port,BIN1_Pin,GPIO_PIN_SET)//设置
AIN1 PB13为 高电平


//电机工作原理
void Motor_Set (int motor1,int motor2)
{
//根据参数正负 设置选择方向
if(motor1 < 0) BIN1_SET;
else BIN1_RESET;
if(motor2 < 0) AIN1_SET;
else AIN1_RESET;
//motor1 设置电机B的转速
if(motor1 < 0)
{
if(motor1 < -99) motor1 = -99;//超过PWM幅值
//负的时候绝对值越小 PWM占空比越大
//现在的motor1 -1 -99
//给寄存器或者函数 99 1
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, (100+motor1));//修改定时器1
通道1 PA8 Pulse改变占空比
}
else{
if(motor1 > 99) motor1 = 99;
//现在是 0 1 99
//我们赋值 0 1 99
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, motor1);//修改定时器1 通道1
PA8 Pulse改变占空比
}
//motor2 设置电机A的转速
if(motor2 < 0)
{
if(motor2 < -99) motor2 = -99;//超过PWM幅值
//负的时候绝对值越小 PWM占空比越大
//现在的motor2 -1 -99
//给寄存器或者函数 99 1
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_4, (100+motor2));//修改定时器1 通
道4 PA11 Pulse改变占空比
}
else{
if(motor2 > 99) motor2 = 99;
//现在是 0 1 99
//我们赋值 0 1 99
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_4, motor2);//修改定时器1 通道4
PA11 Pulse改变占空比
}
}

6.OLED:

OLED的两个引脚

7.为编码器测速开启定时器和定时中断

HAL_TIM_Encoder_Start(&htim2,TIM_CHANNEL_ALL);//开启定时器2 编码器测速
HAL_TIM_Encoder_Start(&htim4,TIM_CHANNEL_ALL);//开启定时器4
HAL_TIM_Base_Start_IT(&htim2); //开启定时器2 中断
HAL_TIM_Base_Start_IT(&htim4); //开启定时器4 中断

HAL_TIM_Base_Start_IT(&htim1); //开启定时器1 中断


//放在stm32f1xx_it.c中的定义变量
short Encode1Count = 0;//
short Encode2Count = 0;
float Motor1Speed = 0.00;
float Motor2Speed = 0.00;
uint16_t TimerCount=0;

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
        if(htim == &htim1)//htim1 500HZ 2ms 中断一次
        {
            TimerCount++;
            if(TimerCount %5 == 0)//每10ms执行一次
                {
                    Encode1Count = (short)__HAL_TIM_GET_COUNTER(&htim4);
                    Encode2Count = (short)__HAL_TIM_GET_COUNTER(&htim2);
                    __HAL_TIM_SET_COUNTER(&htim4,0);
                    __HAL_TIM_SET_COUNTER(&htim2,0);
                    Motor1Speed = (float)Encode1Count*100/9.6/11/4;
                    Motor2Speed = (float)Encode2Count*100/9.6/11/4;
                    TimerCount=0;
                 }
         }
}

8.重定向fputc

int fputc(int ch,FILE *stream)
{
HAL_UART_Transmit(&huart1,( uint8_t *)&ch,1,0xFFFF);
return ch;
}

9.蓝牙控制速度

extern uint8_t g_ucUsart3ReceiveData; //保存串口三接收的数据
int InitSpeed = 50;

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart == &huart3)
	{
		if(g_ucUsart3ReceiveData == 'U')
		{
			InitSpeed += 5;
			if(InitSpeed >= 100) InitSpeed=100;
			MotorGo(InitSpeed);
		}
		if(g_ucUsart3ReceiveData == 'D')
		{
			InitSpeed -= 5;
			if(InitSpeed <= 0) InitSpeed=0;
			MotorGo(InitSpeed);
		}
		HAL_UART_Receive_IT( &huart3, &g_ucUsart3ReceiveData, 1);//继续进行中断接收
	}
	
}

10.pid调参:

//.h文件中的
#ifndef __PID_H
#define __PID_H
//声明一个结构体类型
typedef struct
{
	float target_val;//目标值
	float actual_val;//实际值
	float err;//当前偏差
	float err_last;//上次偏差
	float err_sum;//误差累计值
	float Kp,Ki,Kd;//比例,积分,微分系数
} tPid;
//声明函数
float P_realize(tPid * pid,float actual_val);
void PID_init(void);
float PI_realize(tPid * pid,float actual_val);
float PID_realize(tPid * pid,float actual_val);
#endif

//.c文件中的
#include "pid.h"
//定义一个结构体类型变量
tPid pidMotor1Speed;
//给结构体类型变量赋初值
void PID_init()
{
	pidMotor1Speed.actual_val=0.0;
	pidMotor1Speed.target_val=5;
	pidMotor1Speed.err=0.0;
	pidMotor1Speed.err_last=0.0;
	pidMotor1Speed.err_sum=0.0;
	pidMotor1Speed.Kp=10;
	pidMotor1Speed.Ki=5;
	pidMotor1Speed.Kd=0;
}


// PID控制函数
float PID_realize(tPid * pid,float actual_val)
{
	pid->actual_val = actual_val;//传递真实值
	pid->err = pid->target_val - pid->actual_val;当前误差=目标值-真实值
	pid->err_sum += pid->err;//误差累计值 = 当前误差累计和
	//使用PID控制 输出 = Kp*当前误差 + Ki*误差累计值 + Kd*(当前误差-上次误差)
	pid->actual_val = pid->Kp*pid->err + pid->Ki*pid->err_sum + pid->Kd*(pid->err - pid->err_last);
	//保存上次误差: 这次误差赋值给上次误差
	pid->err_last = pid->err;
	return pid->actual_val;
}


//中断函数中的
if(TimeCount %10 ==0)//每20ms一次
		{
			MotorGo(PID_realize(&pidMotor1Speed,MotorSpeed));
			TimeCount=0;
		}
extern tPid pidMotor1Speed;//声明结构体变量
PID_init();//.c文件中初始化

stm32 hal库是一种功能强大的软件库,可用于开发基于stm32微控制器的应用程序。PID增量式调速是一种用于运动控制的算法,可以实现精确的速度控制。 PID是指比例、积分和微分控制器,它可以根据当前的反馈误差来调整输出信号,以使系统保持稳定。在PID增量式调速算法中,通过测量当前速度和设定速度之间的差异(误差),计算出控制量的增量,然后应用于电机驱动器,以调整电机的速度。 在stm32 hal库中,我们可以通过以下步骤实现PID增量式调速: 1. 配置PWM输出引脚:首先,我们需要配置PWM输出引脚,以便将控制量传递给电机驱动器。使用stm32 hal库的GPIO模块可以轻松配置和控制引脚。 2. 初始化TIM定时器:然后,我们需要初始化TIM定时器,以便生成PWM波形。stm32 hal库提供了方便的函数和结构体,可用于配置和控制定时器。 3. 设置PID参数:接下来,我们需要设置PID控制器的参数。这包括比例常数Kp、积分常数Ki和微分常数Kd。我们可以使用指定的函数来设置这些参数。 4. 实时控制:根据当前的反馈误差和PID参数,使用增量式调度器计算出控制量的增量,并将其应用于电机驱动器。通过周期性地读取反馈信号并更新控制量,我们可以实现精确的速度控制。 总的来说,借助stm32 hal库的丰富功能和灵活的控制能力,可以相对容易地实现PID增量式调速算法。这种算法可以广泛应用于各种需要精确速度控制的应用领域,如机器人、无人机和工业自动化等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值