两轮自平衡小车资料(L298N 模块原理图及使用说明+c源码)

     本文详细介绍了基于STM32微控制器的两轮自平衡小车的设计与实现过程。内容包括小车的硬件选型、电路设计、软件编程以及PID控制算法的应用。通过陀螺仪和加速度计获取小车的姿态信息,利用PID控制算法调整电机输出,实现小车的自主平衡。此外,还探讨了如何通过遥控实现小车的平稳前进和后退,以及利用灰度传感器实现循迹和避障功能。

驱动步进电机如下:

硬件接线图
系统原理图如下:
IN1-IN4
逻辑输入端,其中 IN1 IN2 控制电机 M1 IN3 IN4 控制电机 M2 。例如
IN1 输入
高电平 1,IN2 输入低电平 0 ,对应电机 M1 正转; IN1 输入低电平 0,IN2
输入高电平 1 , 对应电机 M1 反转,调速就是改变高电平的占空比。(如何改变
占空比请学会百度)
PWMA
PWMB
L298N 使能端(高电平有效,常态下用跳线帽接于 VCC ),可通过这两个端
口实现 PWM 调速(使用 PWM 调速时取下跳线帽),具体参考 L298N 芯片手册。
如何控制直流电机正反转 ?
如逻辑输入部分接单片机 P0 口的 P0.0-P0.3. 那么想让电机正转只要给 1010, 反转给 0101
可:
Void main()
{
While(1)
{
P0=0xaa;
Delay(1000);
P0=0x55;
Delay(1000);
}
}

主程序:


#define PI (3.14159265)
// 度数表示的角速度*1000
#define MDPS (70)
// 弧度表示的角速度
#define RADPS ((float)MDPS*PI/180000)
// 每个查询周期改变的角度
#define RADPT (RADPS/(-100))


// 平衡的角度范围;+-60度(由于角度计算采用一阶展开,实际值约为46度)
#define ANGLE_RANGE_MAX (60*PI/180)
#define ANGLE_RANGE_MIN (-60*PI/180)

// 全局变量
pid_s sPID;					// PID控制参数结构体
float radian_filted=0;		// 滤波后的弧度
accelerometer_s acc;		// 加速度结构体,包含3维变量
gyroscope_s gyr;			// 角速度结构体,包含3维变量
int speed=0, distance=0;	// 小车移动的速度,距离
int tick_flag = 0;			// 定时中断标志
int pwm_speed = 0;			// 电机pwm控制的偏置值,两个电机的大小、正负相同,使小车以一定的速度前进
int pwm_turn = 0;			// 电机pwm控制的差异值,两个电机的大小相同,正负相反,使小车左、右转向
float angle_balance = 0;	// 小车的平衡角度。由于小车重心的偏移,小车的平衡角度不一定是radian_filted为零的时候


// 定时器周期中断,10ms
void sys_tick_proc(void)
{
	static unsigned int i = 0;

	tick_flag++;

	i++;
	if(i>=100) i=0;

	if(i==0)	   	// 绿灯的闪烁周期为1秒
	{
		LED1_OFF();
	}
	else if(i==50)
	{
		LED1_ON();
	}
}

void control_proc(void)
{
	int i = ir_key_proc(); // 将红外接收到的按键值,转换为小车控制的相应按键值。

	switch(i)
	{
		case KEY_TURN_LEFT:
			if(pwm_turn<500) pwm_turn += 50;
			break;
		case KEY_TURN_RIGHT:
			if(pwm_turn>-500) pwm_turn -= 50;
			break;
		case KEY_TURN_STOP:
			pwm_turn = 0;
			distance = 0;
			pwm_speed = 0;
			break;
		case KEY_SPEED_UP:
			if(pwm_speed<500) pwm_speed+=100;
			break;
		case KEY_SPEED_DOWN:
			if(pwm_speed>-500) pwm_speed-=100;
			break;
		case KEY_SPEED_0:
			pwm_speed = 0;
			break;
		case KEY_SPEED_F1:
			pwm_speed = 150;
			break;
		case KEY_SPEED_F2:
			pwm_speed = 300;
			break;
		case KEY_SPEED_F3:
			pwm_speed = 450;
			break;
		case KEY_SPEED_F4:
			pwm_speed = 600;
			break;
		case KEY_SPEED_F5:
			pwm_speed = 750;
			break;
		case KEY_SPEED_F6:
			pwm_speed = 900;
			break;
		case KEY_SPEED_B1:
			pwm_speed = -150;
		case KEY_SPEED_B2:
			pwm_speed = -300;
		case KEY_SPEED_B3:
			pwm_speed = -450;
			break;
		default:
			break;
	}

	pwm_turn *= 0.9;	// pwm_turn的值以0.9的比例衰减,使小车在接收到一个转向信号后只转动一定的时间后停止转动。


	speed = speed*0.7 +0.3*(encoder_read());	// 定周期(10ms)读取编码器数值得到实时速度,再对速度进行平滑滤波
 	if(speed!=0)
	{
		printf("speed: %d, dst: %d, pwm: %d \r\n", speed,distance,(int)(speed*6+distance*0.1));
	}



	encoder_write(0);							// 编码器值重新设为0

	distance += speed;							// 对速度进行积分,得到移动距离

	if(distance>6000) distance = 6000;			// 减少小车悬空、空转对控制的影响
	else if(distance<-6000) distance = -6000;

}

void balance_proc(void)
{
	static unsigned int err_cnt=0;

//	float tFloat;
	int pwm_balance;
//	static float angle;
//	float angle_t;
	float radian, radian_pt;  	// 当前弧度及弧度的微分(角速度,角度值用弧度表示)

	adxl345_read(&acc);			// 读取当前加速度。由于传感器按照的位置原因,传感器的值在函数内部经过处理,变为小车的虚拟坐标系。
	l3g4200d_read(&gyr);		// 读取当前角速度。同样经过坐标系变换。


// 此段程序用于传感器出错时停止小车
	err_cnt = err_cnt*115>>7;	// err_cnt以0.9的比例系数衰减(115>>7的值约为0.9,避免浮点数,提高速度)
	if(acc.flag != 0x0F || gyr.flag != 0x0F)   // 读取的角度、角速度值有误。可能是电磁干扰、iic线太长等导致出错。
	{

资源下载:

两轮自平衡小车资料(L298N 模块原理图及使用说明+c源码)

最近更新

  1. TCP协议是安全的吗?

    2024-06-10 08:04:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-10 08:04:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-10 08:04:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-10 08:04:02       18 阅读

热门阅读

  1. FastJson

    FastJson

    2024-06-10 08:04:02      10 阅读
  2. Prompt实现简单英语单词教学

    2024-06-10 08:04:02       7 阅读
  3. 2024.6.9 六

    2024-06-10 08:04:02       7 阅读
  4. 单词记忆(第二周)

    2024-06-10 08:04:02       10 阅读
  5. 【设计模式】结构型设计模式之 享元模式

    2024-06-10 08:04:02       9 阅读
  6. 免费热榜API——哔哩哔哩

    2024-06-10 08:04:02       12 阅读