循迹小车51单片机参考程序

#include
#include //头文件/

#define uchar unsigned char
#define uint unsigned int

uchar t=0; // 定时器中断计数器 //
uchar PWM_TL=0 ; //定义左电机的占空比控制变量//
unsigned char PWM_TR=0 ; //定义右电机的占空比控制变量//
uchar code dis1[] = {"0123456789"};
uchar code dis2[] = {"2011.04.28 "};
uchar code dis3[] = {"time:"};
uchar code dis4[] = {"date:"};

bit flag=0; //标志位,用来判断轮子是否一圈转完,进行占空比控制//

#define temp P2

/*******************************************************
控制口定义
//*******************************************************/


sbit DIN1=P1^0; // 左轮电机端口 1 //
sbit DIN2=P1^1; // 左轮电机端口 2 //
sbit DIN3=P1^2; // 右轮电机端口 1 //
sbit DIN4=P1^3; // 右轮电机端口 2 //

sbit PWML=P1^6; //左轮电机的PWM控制//
sbit PWMR=P1^5; //右轮电机的PWM控制//

sbit LCD_RS = P2^0;
sbit LCD_RW = P2^1;
sbit LCD_EN = P2^2;




/************************************************************
定时器0服务程序、用来产生两路的PWM波
//************************************************************/

void timer0() interrupt 1 // 定时器T0中断服务程序 //
{
// 定时器中断PWM计数 //
if(tPWML=1;
else
PWML=0; // 产生左电机的PWM信号 //

if(tPWMR=1;
else
PWMR=0; // 产生右电机的PWM信号 //

t++ ;
if(t>=100)
t=0; // 1个PWM信号由100次循环产生 //
}
/*************************************************************
循迹程序
*************************************************************/
void xunji(void)
{
switch(temp)
{
case 0x10:
{flag=0;DIN1=0;DIN2=1;DIN3=1;DIN4=0;PWM_TL=60;PWM_TR=40;break;} //0001 0000状态//
case 0x08:
{flag=0;DIN1=1;DIN2=0;DIN3=0;DIN4=1;PWM_TL=40;PWM_TR=60;break;} //0000 1000状态//
case 0x20:
{flag=0;DIN1=0;DIN2=1;DIN3=1;DIN4=0;PWM_TL=70;PWM_TR=40;break;} //0010 0000状态//
case 0x04:
{flag=0;DIN1=1;DIN2=0;DIN3=0;DIN4=1;PWM_TL=40;PWM_TR=70;break;} //0000 0100状态//
case 0x40:
{flag=0;DIN1=0;DIN2=1;DIN3=1;DIN4=0;PWM_TL=80;PWM_

TR=30;break;} //0100 0000状态//
case 0x02:
{flag=0;DIN1=1;DIN2=0;DIN3=0;DIN4=1;PWM_TL=30;PWM_TR=80;break;} //0000 0010状态//
case 0x80:
{flag=0;DIN1=0;DIN2=1;DIN3=1;DIN4=0;PWM_TL=85;PWM_TR=35;break;} //1000 0000状态//
case 0x01:
{flag=0;DIN1=1;DIN2=0;DIN3=0;DIN4=1;PWM_TL=35;PWM_TR=85;break;} //0000 0001状态//
case 0x00:
{flag=0;DIN1=1;DIN2=0;DIN3=1;DIN4=0;PWM_TL=80;PWM_TR=80;break;} //0000 0000状态//
case 0xff:
{flag=0;DIN1=0;DIN2=0;DIN3=0;DIN4=0;PWM_TL=0;PWM_TR=0;break;} //1111 1111状态//
case 0x30:
{flag=0;DIN1=0;DIN2=1;DIN3=1;DIN4=0;PWM_TL=70;PWM_TR=50;break;} //0011 0000状态//
case 0x0c:
{flag=0;DIN1=1;DIN2=0;DIN3=0;DIN4=1;PWM_TL=50;PWM_TR=70;break;} //0000 1100状态//
case 0x60:
{flag=0;DIN1=0;DIN2=1;DIN3=1;DIN4=0;PWM_TL=70;PWM_TR=45;break;} //0110 0000状态//
case 0x06:
{flag=0;DIN1=1;DIN2=0;DIN3=0;DIN4=1;PWM_TL=45;PWM_TR=70;break;} //0000 0110状态//
case 0xc0:
{flag=0;DIN1=0;DIN2=1;DIN3=1;DIN4=0;PWM_TL=75;PWM_TR=40;break;} //1100 0000状态//
case 0x03:
{flag=0;DIN1=1;DIN2=0;DIN3=0;DIN4=1;PWM_TL=40;PWM_TR=75;break;} //0000 0011状态//
default:
break;
}
}



void Init(void)
{
TMOD=0x02; //设定定时器T0工作在模式2 //
TH0=0xB6; //装入定时器的初值 //
TL0=0xB6;
EA=1; // 开总中断 //
ET0=1; // 定时器0中断允许 //
TR0=1; // 启动定时器0 //
}



/*1602部分子函数*/
void delay(int ms)
{
int i;
while(ms--)
{
for(i = 0; i< 250; i++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}




bit lcd_busy()
{
bit result;
LCD_RS = 0;
LCD_RW = 1;
LCD_EN = 1;
_nop_();
_nop_();
_nop_();
_nop_();
result = (bit)(P0&0x80);
LCD_EN = 0;
return result;
}





void lcd_wcmd(uchar cmd)
{
while(lcd_busy());
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
_nop_();
_nop_();
P0 = cmd;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EN = 1;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EN = 0;
}







void lcd_wdat(uchar dat)


{
while(lcd_busy());
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
P0 = dat;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EN = 1;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EN = 0;
}







void lcd_pos(uchar pos)
{
lcd_wcmd(pos|0x80); //数据指针=80+地址变量
}





void lcd_init()
{
delay(15); //等待LCD电源稳定
lcd_wcmd(0x38); //16*2显示,5*7点阵,8位数据
delay(5);
lcd_wcmd(0x38);
delay(5);
lcd_wcmd(0x38);
delay(5);

lcd_wcmd(0x0c); //显示开,关光标
delay(5);
lcd_wcmd(0x06); //移动光标


delay(5);
lcd_wcmd(0x01); //清除LCD的显示内容
delay(5);
}







void lcd_clr()
{
lcd_wcmd(0x01); //清除LCD的显示内容
delay(5);
}










/**************************************************************
主函数
**************************************************************/
void main(void) //主函数//
{

uchar i,min,sec,n;
min=0;sec=0;n=0x3A;

Init();
lcd_init();
lcd_pos(0x00);
i=0;
for(i=0;i<5;i++)
lcd_wdat(dis3[i]);
lcd_pos(0x40);
i=0;
for(i=0;i<5;i++)
lcd_wdat(dis4[i]);
lcd_pos(0x46);
i=0;
for(i=0;i<16;i++)
lcd_wdat(dis2[i]);
while(1)
{
if(temp==0xff)
{
PWM_TL=80; //设置PWM占空比的初值都为80%//
PWM_TR=80;
// 启动定时器0 // //调用系统初始化函数//
DIN1=1;
DIN2=0;
DIN3=1;
DIN4=0; //电机控制端初始化为两电机都正转//
};
if(temp!=0xff)
{
P2=0xff; //从P2口读入前方传感器的状态,并调用循迹处理程序//
xunji();
}; //当传感器检测到的情况始终没有全1时循环检测或是while(1)//

delay(10);
lcd_pos(0x08);
lcd_wdat(dis1[min/10]);
lcd_wdat(dis1[min%10]);
lcd_wdat(n);
lcd_wdat(dis1[sec/10]);
lcd_wdat(dis1[sec%10]);
delay(112);
sec++;
if(sec==60)
{
min++;
sec=0;
}

}
}




相关文档
最新文档