#include "LCD_realtime.h" //液晶显示头文件
#define WHEELCIRCLE 118 //轮周长
#define PWMCYCLE 10 //PWM周期设定为10*5ms
sbit MODESWITCH = P1^2; //直行与寻迹的模式选择按钮
sbit START = P1^3; //开始按钮
sbit MIDDLE = P1^4; //中间传感器输入
sbit LEFT=P3^2 //左边传感器输入
sbit RIGHT=P3^3 //右边传感器检输入
sbit IN1 = P2^3; //电机驱动输入1
sbit IN2 = P2^4; //电机驱动输入2
sbit IN3 = P2^5; //电机驱动输入3
sbit IN4 = P2^6; //电机驱动输入4
//显示函数需要在前面声明,由于作为定时器中断时的函数所调用,其出现在显示函数定义之前
void LCDdisplay();
unsigned int PWMHigh = 0; //控制占空比
unsigned int TimeCount = 0; //控制刷新定时
unsigned int Flag = 0; //计高电平时间标志
unsigned int Time = 0; //记录行进时间
unsigned int Velocity = 0; //记录实时速度
unsigned int WheelCount = 0; //记录轮子转数
unsigned int Distance = 0; //记录行进路程
unsigned char DnT[] = { ' ','0','0','0', '.', '0', '0', 'm',' ',' ','0','0','.','0','s'}; //显示路程时间
unsigned char speed[] = {' ',' ','V', ':',' ', '0', '.', '0', '0','0',' ', 'm', '/', 's', '\0'}; //显示速度
/*方波产生*/
void MakePWM(void)
{
Flag++;
if (Flag<=PWMHigh)
{
ENA=1;
delay1ms(5);
}
else if(Flag<=PWMCYCLE)
{
ENA=0;
delay1ms(5);
}
else if(Flag>PWMCYCLE)
{
Flag=0;
}
}
/*前进*/
void forward()
{
if(LEFT==1&&MIDDLE==0&&RIGHT==1)
{ IN1=1;
IN2=0;
IN3=1;
IN4=0;
}
}
/*左转*/
void turnleft()
{
if(LEFT==0&&MIDDLE==0&&RIGHT==1)
{ IN1=0;
IN2=0;
IN3=1;
IN4=0;
}
}
/*Y右转*/
void turnright()
{
if(LEFT==1&&MIDDLE==0&&RIGHT==0)
{ IN1=0;
IN2=0;
IN3=1;
IN4=0;
}
}
/*左转*/
void turnleft()
{// MIDDLE=1; //接受MIDDLE传感器信号输入
FORWARD=1;
BACKWARD=0;
PWMHigh=3; //转弯时改用3档较低速度
LEFT=1;
RIGHT=0;
while(MIDDLE==1)
{
MakePWM();
}
LEFT=0; //中断完成前恢复数据
RIGHT=0;
FORWARD=1;
BACKWARD=0;
PWMHigh = 4;
}
{
if()
}
/*右转*/
void turnright()
{// MIDDLE=1;
FORWARD=1;
BACKWARD=0;
PWMHigh=3;
LEFT=0;
RIGHT=1;
while(MIDDLE==1)
{
MakePWM();
}
LEFT=0;
RIGHT=0;
FORWARD=1;
BACKWARD=0;
PWMHigh = 4;
}
void int0left(void) interrupt 0
{// delay1ms(10); //延时防抖动
// if(P3^2==0)
turnleft();
}
void int1right(void) interrupt 2
{// delay1ms(10); //延时防抖动
// if(P3^3==0)
turnright();
}
/*主程序的初始化*/
void MAINInit(void)
{
IT0 = 1;
IT1 = 1;
ET0 = 1;
ET1 = 1;
TH0 = 0;
TL0 = 0;
TMOD=0x16;
FORWARD = 0;
BACKWARD = 0;
LEFT = 0;
RIGHT = 0;
EA = 1;
}
/*模式1的直行速控函数*/
void go_straight()
{
TL1 = 0xb0;
TH1 = 0x3c;
TL0 = 0;
TH0 = 0;
TR0 = 1;
TR1 = 1;
speedup();
speedeven(); //占空比为8/10,维持时间为3000ms
speeddown();
}
/*T0中断*/
void T0jishu(void) interrupt 1
{
// delay1ms(10); //延时防抖动
// if(P3^4==0) //T0仍为低电平则判别为下降沿
TH0 = 0; //用于计算轮子转动的圈数,刷新时间间隔内被定时服务读取一次TH和TL的数据,并重新启动
TL0 = 0;
TR0 = 1;
}
/*统计信息并更新显示数据函数*/
void refreshLCD()
{
Time = Time + 10; //时间加1S
TimeCount = 0; //重置TimeCount,每数2次即经过0.1s
Distance = Distance + WHEELCIRCLE*WheelCount; //s = s + vt ,单位mm
Velocity = WHEELCIRCLE*WheelCount*1; //v = &s/&t , 单位mm/s (/1相当于*1)
LCDdisplay(); //信息更新并显示函数
}
/*T1中断*/
void T1dingshi(void) interrupt 3
{
TL1 = 0xb0; //0x3cb0=(65536-50000),即中断时间定为50ms
TH1 = 0x3c;
TF1 = 0; //中断后立刻恢复标志位重复计时
TR1 = 1;
TimeCount++; //记录重复次数
if (TimeCount == 20) //取刷新时间间隔为1s
{
WheelCount = TL0; //记录0.2s内计数器记录的轮子转数(这里假设转速不超过255转每1秒)
//重新启动计数器
TH0 = 0;
TL0 = 0;
TR0 = 1;
refreshLCD(); //刷新数据函数
}
}
/*实时数据显示函数*/
void LCDdisplay()
{
//将整形的值转换为字符数组,以方便显示;加48是转换AIISIC字符方式
DnT[1] = (Distance/100000)%10 + 48;
DnT[2] = (Distance/10000)%10 + 48;
DnT[3] = (Distance/1000)%10 + 48;
DnT[5] = (Distance/100)%10 + 48;
DnT[6] = (Distance/10)%10 + 48; //精确到厘米
DnT[10]= (Time/100)%10 + 48;
DnT[11]= (Time/10)%10 + 48;
DnT[13]= Time%10 + 48; //精确到0.1s
speed[5] = (Velocity/1000)%10 + 48;
speed[7] = (Velocity/100)%10 + 48;
speed[8] = (Velocity/10)%10 + 48;
speed[9] = Velocity%10 + 48; //精确到mm/s
DisplayListChar(0,0,DnT); //实时显示各运行参数(以0.5s间隔更新)
DisplayListChar(0,1,speed);
delay1ms(10);
}
/*主函数*/
void main()
{
unsigned char m; //控制模式2寻迹时间的循环标记
MAINInit(); //初始化主程序 (已包括定时器、计数器的初始化)
// LCDInit(); //初始化液晶显示
while(1)
{
if(MODESWITCH)
{
LEFT=0;
RIGHT=0;
ENA=0;
FORWARD=1;
BACKWARD=0;
LCDMODE1ready();
EX0=0;
EX1=0;
if(START)
{
delay1ms(200);
go_straight(); //函数中已包含定时器计数器的初始赋值
// TR1=0; //只将定时器置零,秒表停下
// LCDMODE1finish();
while(1);
}
}
else
{
LCDMODE2xunji();
EX0=1;
EX1=1;
if(START)
{
ENA=0;
FORWARD=1;
BACKWARD=0;
TL1=0xb0;
TH1=0x3c;
TL0 = 0;
TH0 = 0;
TR0=1;
TR1=1;
for(m=0;m<=9;m++)
{
PWMHigh=4;
speedeven(); //占空比3/10,维持比较长一段时间
}
// TR1=0; //只将定时器置零,秒表停下
while(1);
}
}
}
}