#include<stc8a8k.h>
#include<oled.h>
#include<delay.h>
#include "hpwm.h"
//左电机
sbit LPWM=P2^0;
sbit LA2=P0^4;
sbit LA1=P0^5;
//右电机
sbit RPWM=P2^1;
sbit RA2=P0^6;
sbit RA1=P0^7;
//接传感器
sbit L1S=P1^2;
sbit MS=P1^1;
sbit R1S=P1^0;
// sbit L1S=P1^0;
// sbit L0S=P1^1;
// sbit R0S=P1^2;
// sbit R1S=P1^3;
//定义黑白线的信号,根据实际模块定义,1是高电平,0是低电平
unsigned char blackline=1;
unsigned char whiteline=0;
//*************************************
sbit key=P3^4;//接按键
sbit beep=P0^3;//接蜂鸣器
sbit led=P0^0;//接LED报警灯
unsigned char keyflag=0;
unsigned char crossnum=0;
unsigned char startflag=0;
unsigned char LV=0,MV=0,RV=0,preLV=0,preMV=0,preRV=0;
//循迹函数声明,先声明后定义,不然main都不知道有这个函数,在main函数后面定义具体程序代码
void trackline0();
//这个是定义,不声明,后面main函数可以直接用,
//小车前进,根据速度两个轮子速度差,进行前进,转弯等
//vleft:0-1之间,是比例
//vright
void qianjin(float vleft,float vright)
{
HPWM_Set(0,8000,vleft);
LA2=1;
LA1=0;
HPWM_Set(1,8000,vright);
RA2=1;
RA1=0;
}
void back(float vleft,float vright)
{
HPWM_Set(0,8000,vleft);
LA2=0;
LA1=1;
HPWM_Set(1,8000,vright);
RA2=1;
RA1=0;
}
//小车停止
void stop()
{
LA2=0;
LA1=0;
RA2=0;
RA1=0;
}
//*******************************************主函数
void main()
{
L1S=1;
MS=1;
R1S=1;
OLED_Init();
HPWM_Init();
OLED_ShowString(0,0,"Please press start...");
delay_tms(100);
while(1)
{
//*****************************
//检测按键是不是按下,开始启动
if(key==0)
{
delay_tms(10);//延时去抖动
if(key==0)
{
startflag=1;
OLED_ShowString(0,0,"I am running...");
//开机先动一下
qianjin(0.35,0.35);//
delay_tms(1000);//延时
stop();
delay_tms(2000);//延时
}
}
//**********************如果开始标记等于1,说明按下启动键,这时候小车才开始跑
if(startflag==1)
{
//开始循迹,请看这部分代码,太长了,单独拉出来写,方便看主程序逻辑
trackline0();
}
}
}
//trackline0();
void trackline0()
{
if(L1S==0)LV=0;
else LV=1;
if(MS==0)MV=0;
else MV=1;
if(R1S==0)RV=0;
else RV=1;
if(LV==blackline && MV==whiteline && RV==whiteline)//1 00
{
qianjin(0.25,0.45);//左转弯
}
else if(LV==whiteline && MV==blackline && RV==whiteline)//0 1 0
{
qianjin(0.3,0.3);//直走
}
else if(LV==whiteline && MV==whiteline&& RV==blackline)// 00 1
{
qianjin(0.45,0.25);//右转弯
}
else if(LV==blackline && MV==blackline && RV==whiteline)//110 判断是左转90度
{
stop();
delay_tms(2000);
// qianjin(0.25,0.25);//直走
// delay_tms(20);
qianjin(0.05,0.55);//左转弯
//back(0.35,0.35);
while(1)
{
delay_tms(20);
if(R1S==blackline)break;
}
}
else if(LV==whiteline && MV==blackline && RV==blackline)//011 判断是右转90度
{
stop();
delay_tms(2000);
qianjin(0.45,0.05);//直走
delay_tms(30);
// back(0.35,0.35);
while(1)
{ delay_tms(20);
if(L1S==blackline)break;
}
}
else if(LV==blackline && MV==blackline && RV==blackline)//111 判断是终点,调头
{
stop();
delay_tms(2000);
qianjin(0.35,0.35);
delay_tms(500);
back(0.35,0.35);
delay_tms(500);
while(1)//如果中间的传感器碰到黑线,就跳出循环
{ delay_tms(20);
if(MS==blackline)
break;
}
}
else if(LV==whiteline && MV==whiteline && RV==whiteline)//000找不到直线,如如果前面是直走,就转360度,如果是之前右边,就左转,之前左偏,就右转
{
if(preLV==whiteline && preMV==blackline && preRV==whiteline)//0 1 0,就调头,右转,
{
qianjin(0.4,0.15);//右转弯
delay_tms(500);
while(1)//如果中间的传感器碰到黑线,就跳出循环
{
if(R1S==1)
break;
}
}
if(preLV==blackline && preRV==whiteline)//1 0,之前是左偏,那么就右转
{
qianjin(0.4,0.1);//
}
if(preLV==whiteline && preRV==blackline)//01,之前是右偏,那么就左转
{
qianjin(0.1,0.4);//
}
if(preLV==blackline && preMV==blackline && preRV==blackline)//111,之前三叉路口,就右转
{
qianjin(0.4,0.1);//
}
return;
}
preLV=LV;
preMV=MV;
preRV=RV;
}
2020-11-14
最新推荐文章于 2022-11-20 15:26:36 发布
这是一个使用STC8A8K单片机控制的循迹机器人程序,通过OLED显示、HPWM设置电机速度、延迟函数及传感器检测来实现路径跟踪。程序中定义了按键、蜂鸣器、LED灯和电机控制引脚,并根据传感器读取的黑白线状态调整小车行驶方向,包括直行、转弯和调头。同时,程序还包含了防止小车偏离赛道的错误处理机制。
摘要由CSDN通过智能技术生成