【Proteus仿真】【STM32单片机】双轮平衡车设计

发布时间:2024年01月15日


一、功能简介

本项目使用Proteus8仿真STM32单片机控制器,使用OLED液晶显示模块、陀螺仪传感器、L298N电机驱动、PCF8691 ADC模块、按键、HCSR04超声波等。

主要功能:
系统运行后,OLED显示超声波检测的距离和陀螺仪检测的俯仰角。S1开关切换自动和手动控制模式,当S1闭合时处于手动模式,可通过K1-K4键控制小车前进/后退/左转/右转方向,当运行中俯仰角为正数越大,小车速度越快,反之越慢。
当S1断开时处于自动模式,当超声波未检测到障碍物时,小车根据俯仰角值前进或后退,速度随俯仰角变大而加快。当俯仰角为负值,则小车反方向加速使其平衡。
当超声波检测到障碍物时,小车先后退后左转避障。
系统运行中,小车状态可显示在OLED上。


二、软件设计

/*
作者:嗨小易(QQ技术交流群:570487280)

*/


//系统数据显示
void sys_data_show(void)
{
	u8 buf[5];
	int temp=0;

	while(1)
	{
		//超声波距离显示
		buf[0]=sys_ctrl.dis/100+0x30;
		buf[1]=sys_ctrl.dis%100/10+0x30;
		buf[2]=sys_ctrl.dis%100%10+0x30;		
		buf[3]='\0';
		OLED_ShowString(6*8,2,buf,16);
		//俯仰角显示
		if(sys_ctrl.pitch>=0)
		{
			temp=sys_ctrl.pitch;
			buf[0]='+';	
		}
		else
		{
			temp=-sys_ctrl.pitch;
			buf[0]='-';		
		}
		buf[1]=temp/100+0x30;
		buf[2]=temp%100/10+0x30;
		buf[3]=temp%100%10+0x30;		
		buf[4]='\0';
		OLED_ShowString(6*8,4,buf,16);

		switch(sys_ctrl.dir)
		{
			case 0:OLED_ShowString(0,6,"Stop ",16);break;
			case 1:OLED_ShowString(0,6,"Forwd",16);break;
			case 2:OLED_ShowString(0,6,"Left ",16);break;
			case 3:OLED_ShowString(0,6,"Back ",16);break;
			case 4:OLED_ShowString(0,6,"Right",16);break;	
		}

		break;	
	}		
}

//系统数据设置
void sys_data_set(void)
{
	u8 key=0;
	static u8 md=0;

	//自动/手动模式选择
	if(MODE_SW==0)
	{
		sys_ctrl.mode=1;//手动
		if(md==0)
			OLED_ShowString(11*8,6,"Manul",16);
		md=1;
		sys_ctrl.dir=0;
		sys_ctrl.speed=0;
	}
	else 
	{
		sys_ctrl.mode=0;//自动
		if(md==1)
			OLED_ShowString(11*8,6,"Auto ",16);
		md=0;
		sys_ctrl.dir=0;
		sys_ctrl.speed=50;	
	}
	
	//手动模式下,可通过按键控制
	if(sys_ctrl.mode==1)
	{ 	
		key=KEY_Scan(1);
		switch(key)
		{
			case KEY1_PRESS://前进
				sys_ctrl.dir=1;
				sys_ctrl.speed=50;
				break;
			case KEY2_PRESS://左转
				sys_ctrl.dir=2;
				sys_ctrl.speed=50;
				break;
			case KEY3_PRESS://后退
				sys_ctrl.dir=3;
				sys_ctrl.speed=50;
				break;
			case KEY4_PRESS://右转
				sys_ctrl.dir=4;
				sys_ctrl.speed=50;
				break;
			default ://停止
				sys_ctrl.dir=0;
				sys_ctrl.speed=0;
				break;
		}			
	}	
}

//系统功能控制
void sys_fun_ctrl(void)
{
	//手动模式下,可通过按键控制
	if(sys_ctrl.mode==1)
	{
		switch(sys_ctrl.dir)
		{
			case 0://停止
				car_stop();
				break;
			case 1://前进
				car_forward();
				break;
			case 2://左转
				car_left();
				break;
			case 3://后退
				car_back();
				break;
			case 4://右转
				car_right();
				break;	
		}
		pwm_set_duty(sys_ctrl.speed+sys_ctrl.pitch);	
	}
	//自动模式下小车控制
	else
	{
		//还未遇到障碍物
		if(sys_ctrl.dis>DISTANCE_MIN)
		{
			//小车前进
			if(sys_ctrl.pitch>=0)
			{
				sys_ctrl.dir=1;
				car_forward();	
			}
			//小车后退
			else
			{
				sys_ctrl.dir=3;
				car_back();//后退	
			}	
		}
		//遇到障碍物,避开障碍物
		else
		{	
			car_stop();//停止
			OLED_ShowString(0,6,"Stop ",16);
			delay_ms(1000);
			car_back();//后退
			OLED_ShowString(0,6,"Back ",16);
			delay_ms(1000);
			sys_data_get();//系统数据获取
			car_left();//左转
			OLED_ShowString(0,6,"Left ",16);
			delay_ms(1000);
			sys_data_get();//系统数据获取
			car_stop();//停止
			OLED_ShowString(0,6,"Stop ",16);
		}
		pwm_set_duty(sys_ctrl.speed+abs(sys_ctrl.pitch));	
	}				
}



三、实验现象

B站演示视频:https://space.bilibili.com/444388619
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

联系作者

视频地址:https://space.bilibili.com/444388619/video
专注于51单片机、STM32、国产32、DSP、Proteus、arduino、ESP32、物联网软件开发,PCB设计,视频分享,技术交流。

文章来源:https://blog.csdn.net/Hello_Muyi/article/details/135603962
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。