📄 perfect111.c
字号:
#include <intrins.h>
#include <AT89X52.h>
/********************************************************************************\
** 宏定义区 **
\********************************************************************************/
/*------------------------------- LCD模块 ------------------------------------*/
#define LCD_RW P2_6 //读写控制端
#define LCD_RS P2_7 //数据命令选择端
#define LCD_E P2_5 //执行使能端
#define LCD_Data P1 //P1口
#define Write 0x00 //低电平写入
#define Read 0x01 //高电平读出
#define Data 0x01 //高电平选择数据
#define Cmd 0x00 //低电平选择命令
#define Enable 0x00 //跃变到低电平时执行命令
#define Disable 0x01
#define True 0x01
#define False 0x00
#define LCD_Init 0x38 //初始化模式
#define LCD_DispCtr 0x0C //开显示及光标设置
#define LCD_CloseCtr 0x08 //关显示
#define LCD_CLS 0x01 //清屏幕
#define LCD_EnterSet 0x06 //显示光标
#define Busy P1_7 //忙信号
/*-------------------------- 测速/测距/测时模块 -------------------------------*/
#define CircleLength 0.132 //小车转一轮的长度为0.132m
/*-------------------------------- 控速模块 -----------------------------------*/
#define P03 P0_3 //后电机
#define P04 P0_4 //后电机
#define P01 P0_1 //前电机
#define P02 P0_2 //前电机
#define P31 P0_5 //控制液晶背光
//#define P33 P3_3
/*------------------------------ 菜单选择模块 ---------------------------------*/
#define Line 0x00 //0代表直线模式
#define Curve 0x01 //1代表S型模式
#define Normal 0x00 //0 代表正常速度
#define Low 0x01 //1 代表低速
#define High 0x02 //2 代表高速
/*********************************************************************************\
** 全局函数区 **
\*********************************************************************************/
/*------------------------------- LCD模块 -------------------------------------*/
void LCDInit(void); //LCD初始化
void SetWriteCmd(void); //设置写命令模式
void SetReadCmd(void); //设置读命令模式
void SetWriteData(void); //设置写数据模式
void WriteCmd(char cmd); //写命令
void WriteData(char ddata); //写数据
void ExecuteCmd(void); //执行命令
void SetXY(char x,char y); //定位显示地址
void DisplaySingleChar(char x,char y,char cchar); //显示单个字符
void DisplayString(char x,char y,char *str); //显示一段字符串
void Delay(unsigned int time); //延时主程序
void DelayUs(unsigned int time); //延时子程序
bit IsBusy(void); //判断忙标志函数
void DisplayTime(void); //显示时间
void DisplayAVGSpeed(void); //显示平均速度
void DisplayDistance(void); //显示路程
/*-------------------------- 测速/测距/测时模块 -------------------------------*/
void INTInit(void); //中断初始化
void SpeedINT(void); //测速中断
/*-------------------------------- 控速模块 -----------------------------------*/
void CtrSpeedINT(void); //控速中断
void Time0INT(void);
void Time1INT(void); //控速单位时间中断
void Clock0_Init(void); //时钟0中断初始化
void Clock1_Init(void); //时钟1中断初始化
/********************************************************************************\
** 全局变量区 **
\********************************************************************************/
float SpeedCount = 0; //测速计数脉冲
float Speed = 0.0;
float Distance = 0.0;
char Time1INTCount=0; //T1中断时间计时
float PassTime=0.00; //小车行走的时间
short IsT0INT=1;
bit IsT1INT; //判断T1是否已经响应中断
short IsT0INT2=1;
char Thx[6]={0xf0,0xf0,0xc5,0xf0,0xe8,0xff}; //4ms,4ms,15ms,5ms,6ms
char Tlx[6]={0x60,0x60,0x68,0x60,0x90,0xff};
char Thx0=0xd8; //10ms
char Tlx0=0xf0;
char Thx1=0xb1; //20ms
char Tlx1=0xe0;
short Round=0;
short Back=0;
short Back0=0;
bit Backid;
bit Stop=0;
char Area0=0;
char Area1=0; //区域变量
char LowSpeedArea1StartTime;
char LowSpeedArea1EndTime;
char HighSpeedAreaEndTime;
char LowSpeedArea2EndTime;
char LowSpeedArea1PassTime=0; //第一个低速区通过时间
char HighSpeedAreaPassTime=0; //高速区通过时间
char LowSpeedArea2PassTime=0; //第二个低速区通过时间
char ReadyToGo=4; //倒计时
char flag;
bit Roundid=0;
char Nocurve=0;
bit Running;
bit StartSelectModeAndSpeed; //模式和速度是否选择完毕标志
bit IsSelectingMode; //模式选择标志
bit IsSelectingSpeed; //速度选择标志
bit ModeSelected; //已经被选择的模式标志
char SelectedMode=10; //模式选择是否完毕标志
bit Next; //Next键标志
bit SpeedSelected; //已经被选中的速度方案标志
char SelectedSpeed; //速度选择是否完毕标志
bit ChoosingDisplay;
bit SelectedShow;
bit SelectedReturn;
bit Selected;
bit ReturnSelection;
bit AVGSpeedShow;
bit TotalDistanceShow;
bit ReturnMain;
bit LowSpeedArea1Show;
char NextTimes=0;
bit AutoDisplay;
bit GoToChoosingDisplay;
char AutoMode=0;
char PassLineID=0;
char PassLine=0;
float PrepareDistance;
float FirstDistance;
float SecondDistance;
float FirstAreaRate;
float SecondAreaRate;
float ThirdAreaRate;
bit RateID=0;
float SurveyDistance;
unsigned int T024Change=62536; //3ms
unsigned int T03Change=57536; //8ms
/********************************************************************************\
** 全局函数实现区 **
\********************************************************************************/
/*-------------------------------- 主函数 ------------------------------------*/
void main()
{
/*----------------------- 单片机复位初始化 ---------------------------------*/
P01=0; //电机不动
P02=0;
P03=0;
P04=0;
P31=1; //背光开
/*------------------------ 显示欢迎信息 -----------------------------------*/
Delay(40); //延时等待LCD启动
LCDInit(); //初始化LCD
DisplayString(0x0,0," Starting... ");
DisplayString(0x0,1,"Designed By 3202");
Delay(300);
WriteCmd(LCD_CLS);
/*------------------------ 启动按钮功能 ----------------------------------*/
EA=1; //开总中断
EX0=1; //开INT0中断
IT0=1; //INTO边沿触发
EX1=1; //开INT1中断
IT1=1; //INT1边沿触发
/*------------------------------ 模式选择 ---------------------------------*\
说明:有三种模式可以选择
(1) Line 模式 ----直线模式。这种模式可以满足基本要求,即根据要求变速走完
全程,但对于低速区、高速区必须在规定的时间内走完这一要
求并不一定能够精确满足,存在误差,因为在这种模式下,速
度是程序预定的,在实际情况下,可能会由于电池驱动力不足
或是场地长度限制等问题而导致误差。
(2) Curve 模式----S型曲线模式。这种模式可以满足扩展要求,即根据铁片寻迹,
沿着铁片线路走出S型曲线。在这种模式下,我们的小车能够
自动寻找正确的方向而开始走S型曲线,即如果开始时走错方
向了,小车会自动倒退重新开始沿着正确的方向走S型曲线。
(3) AutoMode模式--自动模式。这种模式是对Line模式的改良。在这种模式下,小
车能够先走完全程一次,记录每一段区域的距离,然后自动倒
退回起跑线,再根据记录下来的信息以及对于低速区、高速区
的通过时间要求,在第二次行走过程中根据信息而计算出的结
果自动调整速度,以尽力满足对低速区、高速区通过时间的要
求。这种模式我们也把它叫做自适应速度调整模式。
\*---------------------------------------------------------------------------*/
StartSelectModeAndSpeed=True; //开始模式和速度选择
DisplayString(0x0,0," Choose The Mode"); //显示模式选择提示信息
DisplayString(0x0,1," you want. ");
Delay(250);
WriteCmd(LCD_CLS);
IsSelectingMode=True; //启动模式选择
Next=False; //防止复位时中断对按钮的影响
ModeSelected=False;
while(1)
{
Next=False;
WriteCmd(LCD_CLS);
DisplayString(0x0,0," Line Mode ");
DisplayString(0x0,1,"Next Yes");
Delay(120); //检测按键抖动并消除
if (Next==True)
Next=False;
while (1) //不断检测中断,直到按确定键或是NEXT键
{
if (Next==True) //如果按Next键则直接跳出
break;
if (ModeSelected==True) //如果按确定键则设置模式为Line并跳出
{
SelectedMode=Line;
break;
} //如果什么键都没有按下,那么一直显示等待
}
if (ModeSelected==True) //按下了确定键,退出模式选择
{
IsSelectingMode=False;
break;
}
if (Next==True) //按下了Next键,显示下一个菜单项
{
Next=False;
WriteCmd(LCD_CLS);
DisplayString(0x0,0," Curve Mode ");
DisplayString(0x0,1,"Next Yes");
Delay(120); //检测按键抖动并消除
if (Next==True)
Next=False;
while(1) //不断检测中断,直到按确定键或是Next键
{
if (Next==True) //如果再一次按下Next键,则跳出
break;
if (ModeSelected==True) //如果按下确定键,则设置模式为Curve,并跳出
{
SelectedMode=Curve;
break;
}
}
}
if (ModeSelected==True) //按下了确定键,退出模式选择
{
IsSelectingMode=False;
break;
}
if (Next==True) //再一次按下了Next键,则循环模式选择
{
Next=False;
WriteCmd(LCD_CLS);
DisplayString(0x0,0," AutoMode ");
DisplayString(0x0,1,"Next Yes");
Delay(120); //检测按键抖动并消除
if (Next==True)
Next=False;
while(1)
{
if (Next==True)
break;
if (ModeSelected==True)
{
AutoMode=1;
break;
}
}
}
if (ModeSelected==True)
{
IsSelectingMode=False;
break;
}
if (Next==True)
{
Next=False;
continue;
}
}
Delay(50);
WriteCmd(LCD_CLS);
Next=False; //防止上面中断对按钮的影响
SpeedSelected=False;
/*------------------------------ 速度选择 ---------------------------------*\
说明:只有选择了Line模式才会启动速度选择,有三种速度可以选择。
(1) Normal ---- 正常速度,即中等速度。
(2) Low ---- 低速
(3) High ---- 高速
\*---------------------------------------------------------------------------*/
if (SelectedMode==Line && AutoMode==0)
{
DisplayString(0x0,0," Now Choose a ");
DisplayString(0x0,1," kind of Speed ");
Delay(250);
WriteCmd(LCD_CLS);
Next=False;
IsSelectingSpeed=True; //启动速度选择
while(1)
{
Next=False;
WriteCmd(LCD_CLS);
DisplayString(0x0,0," Normal Speed ");
DisplayString(0x0,1,"Next Yes");
Delay(120);
if (Next==True)
Next=False; //检测按键抖动并消除
while(1)
{
if (Next==True) //如果按Next键则直接跳出
break;
if (SpeedSelected==True) //如果按确定键则设置速度为Normal并跳出
{
Thx[0]=0xec;Tlx[0]=0x78; //5ms
Thx[1]=0xf0;Tlx[1]=0x60; //4ms
Thx[2]=0x8a;Tlx[2]=0xd0; //30ms
Thx[3]=0xf0;Tlx[3]=0x60; //4ms
Thx[4]=0xec;Tlx[4]=0x78; //5ms
SelectedSpeed=Normal;
break;
} //如果什么键都没有按下,那么一直显示等待
}
if (SpeedSelected==True) //按下了确定键,退出速度选择
{
IsSelectingSpeed=False;
break;
}
if (Next==True)
{
Next=False;
WriteCmd(LCD_CLS);
DisplayString(0x0,0," Low Speed ");
DisplayString(0x0,1,"Next Yes");
Delay(120); //检测按键抖动并消除
if (Next==True)
Next=False;
while(1)
{
if (Next==True) //如果再一次按下Next键,则跳出
break;
if (SpeedSelected==True) //如果按下确定键,则设置速度为Low,并跳出
{
SelectedSpeed=Low; //这里没有速度设置,因为默认速度就是Low
break;
}
}
}
if (SpeedSelected==True) //按下了确定键,退出速度选择
{
IsSelectingSpeed=False;
break;
}
if (Next==True)
{
Next=False;
WriteCmd(LCD_CLS);
DisplayString(0x0,0," High Speed ");
DisplayString(0x0,1,"Next Yes");
Delay(120); //检测按键抖动并消除
if (Next==True)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -