一、功能简介
本项目使用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设计,视频分享,技术交流。