# include "reg51.h"
# include "pwm.h"
uchar flag,i,receive;
uchar code table1[]="GO";
uchar code table2[]="Back";
uchar code table3[]="Left";
uchar code table4[]="Right";
uchar code table0[]="Stop";
uchar code table5[]="2016111130";
uchar code table6[]="Welcome to Lanya";
sbit RS=P2^2;
sbit RW=P2^3;
sbit E=P2^4;
void delay_50us(uint us)
{
uint i,k;
for (i=us;i>0;i--)
for (k=100;k>0;k--);
}
void write_data(uint dat) //定义写数据函数
{
RS=1;
RW=0;
E=0;
P0=dat; //送入数据
delay_50us(10);
E=1;
delay_50us(10);
E=0; //到此数据送入完毕
}
void write_com(uchar com) //定义写指令函数
{
RS=0;
RW=0;
E=0;
P0=com; //送入指令
delay_50us(10);
E=1;
delay_50us(10);
E=0; //到此指令送入完毕
}
void lcd1602inti(void) //函数声明
{
delay_50us(100); //延时15ms
write_com(0x38); //不检测忙信号
delay_50us(100); //延时5ms
write_com(0x38); //不检测忙信号
delay_50us(100); //延时5ms
write_com(0x38); //不检测忙信号
write_com(0x38); //显示模式设置
write_com(0x08); //显示关闭
write_com(0x01); //显示清屏
write_com(0x06); //显示光标移动设置
write_com(0x0c); //显示开及光标设置
}
void display()
{
uchar i;
lcd1602inti();
write_com(0x83);
for(i=0;i<10;i++)
{
write_data(table5[i]); //table1[]="2016111130";
}
write_com(0xC0);
for(i=0;i<16;i++)
{
write_data(table6[i]); //table2[]="Welcome to Lanya";
}
}
void Usartinit() //初始化
{
TMOD=0x21; //设置定时器1的工作方式2 0010 0000 GATE C/T 8位初值自动重装8位定时器
//GATE C/T M1 M0 GATE C/T M1 M0 C/T位为1为计数模式 C/T位为0为定时模式
PCON=0x80; //波特率加倍 电源管理寄存器
TH1=0xf3; //给定时器重装初值
TL1=0xf3; //这里的波特率必须加倍 不加倍的话 通讯不成功 本人目前还不知道原因
//由于开发板使用的晶振频率是12M,非标准频率,在设置波特率时很容易产生误差,而导致串口通信出现乱码或者失败
//目前来说,选择波特率4800,SMOD=1波特率加倍的方式,误差率仅为0.16%,为12M晶振中最小的误差
TH0=0XEC; //5ms定时
TL0=0X78;
TR0=1;
ET0=1;
TR1=1; //开定时器1
SM0=0; //选择串口工作方式1,常用
SM1=1;
REN=1; //开串口接收 此时接收器一所选择的波特率16倍速率采样RXD移交的电平 开始接收信息
ES=1; //串行中断总开关
EA=1; //开总中断
}
void main()
{
lcd1602inti();
Usartinit(); //调用初始化函数进行初始化
display();
while(1)
{
if(flag==1)//不断的检测标志位是否被置1 被置1说明已经执行了中断服务程序,即已经接数据,否则一直检测flag的状态
{
switch(receive)
{
case 1: run();
ES=0; //接下来要发送数据 先要使ES=0关闭串口中断 等数据发送完后再打开串口中断
for(i=0;i<2;i++)
{
SBUF=table1[i];
while(!TI); //等待是否发送完成 因为发送完成后TUI会有硬件置1
TI=0; //清除发送完成标志位 手动清0
}
ES=1;
flag=0;
break;
case 2: backrun();
ES=0;
for(i=0;i<4;i++)
{
SBUF=table2[i];
while(!TI);
TI=0;
}
ES=1;
flag=0;
break;
case 3: leftrun();
ES=0;
for(i=0;i<4;i++)
{
SBUF=table3[i];
while(!TI);
TI=0;
}
ES=1;
flag=0;
break;
case 4: rightrun();
ES=0;
for(i=0;i<5;i++)
{
SBUF=table4[i];
while(!TI);
TI=0;
}
ES=1;
flag=0;
break;
case 0: stoprun();
ES=0;
for(i=0;i<4;i++)
{
SBUF=table0[i];
while(!TI);
TI=0;
}
ES=1;
flag=0;
}
}
}
}
void Usart() interrupt 4 //一旦有数据接入,串行口中断触发
{
receive=SBUF-48; //当REN为1时 开始接收数据 将接收到的值赋予receive 这里的是ACSII 所以要减去48
RI=0; //当RI=0 将接收数据存入SBUF寄存器中 清除接收中断标志位 有内部硬件置1,项CPU发出中断请求 在中断服务程序中,必须用软件将其清零, 取消此中断申请
flag=1; //将标志位置1 这个是方便在主程序中查询判断是否已经接收到数据
}
……………………
…………限于本文篇幅 余下代码请从51黑下载附件…………