单片机源程序如下:
#include <reg52.h>
#include <lcd.h>//液晶显示配置文件
#include <stdio.h>
sbit mot_clock = P0^1;
sbit mot_dir =P0^0;
sbit clock = P0^3;
sbit dir =P0^2;
sbit kaiguan =P1^1;
sbit zuozhuan =P1^0;
sbit youzhuan =P1^2;
sbit zuok =P1^3;//左转开始信号
sbit zuos =P1^4;//左转停止信号
sbit youk =P1^5;//右转开始信号
sbit yous =P1^6;//右转停止信号
sbit zheng =P3^4;
sbit Tr=P3^0;
sbit Ec=P3^1;
sbit tui=P0^7;
typedef unsigned char uchar;
typedef unsigned int uint;
unsigned int RunSpeed=50; //速度
bit dir_flag;
uint d=0;
unsigned char a[2]=0;
unsigned int s,j,s1;
float csbc=0.03315;
void delay_ms(unsigned int Delay) //1ms延时程序
{
unsigned int i;
for(;Delay>0;Delay--)
for(i=0;i<124;i++);
}
void Delay10us()
{
uchar i;
i=10;
while(--i);
}
void Delay(unsigned int z)//毫秒级延时
{
unsigned int x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}
//定时器0中断程序:正转
/*void t_0(void) interrupt 1
{
Ec=0;
}*/
void zhengzhuan()
{
dir_flag=1;
mot_clock=0;
mot_dir=0;
clock=0;
dir=0;
delay_ms(100);
mot_clock=1;
mot_dir=1;
clock=1;
dir=1;
}
//定时器1中断:反转
void t_1() interrupt 3
{
dir_flag=0;
mot_clock=0;
mot_dir=0;
clock=0;
dir=0;
delay_ms(100);
mot_clock=1;
mot_dir=1;
clock=1;
dir=1;
}
//中断0:加速程序
void SpeedUp() interrupt 0
{
if(RunSpeed>=12)
RunSpeed=RunSpeed-2;
}
//中断1:减速程序
void SpeedDowm() interrupt 2
{
if(RunSpeed<=100)
RunSpeed=RunSpeed+2;
}
void qiting()
{
if(kaiguan==0)
{
zuozhuan=0;
youzhuan=0;
}
if(kaiguan==1)
{
zuozhuan=1;
youzhuan=1;
}
}
void Read_value()
{
Tr=0; //启动一次模块
Delay10us();
Tr=1;
ET0=1; //启动计数器T0,用以计时
TR0=1;
EA=1;
j=50; //延时
while(j--)
{
}
Ec=1;
j=0;
while(Ec) //判断接收回路是否收到超声波的回波
{
j++;
if(j>=2500) //如果达到一定时间没有收到回波,则将csbint置零,退出接收回波处理程序
Ec=0;
}
TR0=0;
s1=TH0*256+TL0; //读取时间数据
TH0=0;
TL0=0;
s1=s1*csbc-4;
s1/=2;
a[0]=s1/10+'0';
a[1]=s1%10+'0';
if((s1>30)&&(tui!=0))
{
WriteCmd(LCD_CLS);
while((s1>30)&&(tui!=0))
{
zuozhuan=0;
youzhuan=0;
DisplayString(0x4,1,"stop");
//LCD_Write_String(0,1,a);
DisplayString(0x0,0,"youzhangaiwu");
}
WriteCmd(LCD_CLS);
}
if(tui==0)
{
zuozhuan=1;
youzhuan=1;
}
}
void main()
{
LCDInit();
/*定时器设置*/
TMOD|=0x61; //定时器0,1都为计数方式;方式2;
EA=1; //开中断
TH0=0; //定时器0初值FFH;
TL0=0;
ET0=1;
TR0=0;
TH1=0xff; //定时器1初值FFH;
TL1=0xff;
ET1=1;
TR1=1;
IT0=1; //脉冲方式
EX0=1; //开外部中断0:加速
IT1=1; //脉冲方式
EX1=1; //开外部中断1:减速
mot_clock=1;
dir_flag =1;
mot_dir=1;
clock=1;
dir=1;
while(1)
{
DisplayString(0x0,0,"forward");
delay_ms(RunSpeed);
mot_clock=~mot_clock;
clock=~clock;
Read_value();
LCD_Write_String(0,1,a);
DisplayString(0x2,1,"cm");
qiting();
if(zheng==0)
{
zhengzhuan();
}
if(dir_flag==1)//正转
{
mot_clock=~mot_clock;
clock=~clock;
//delay_ms(RunSpeed);
if(zuok==0)
{
WriteCmd(LCD_CLS);
zuozhuan=0;
clock=1;
dir=1;
while(zuos!=0)
{
delay_ms(RunSpeed);
clock=~clock;
DisplayString(0x0,0,"Turn Left small");
}
WriteCmd(LCD_CLS);
}
if(youk==0)
{
WriteCmd(LCD_CLS);
youzhuan=0;
clock=1;
dir=1;
while(yous!=0)
{
delay_ms(RunSpeed);
mot_clock=~mot_clock;
DisplayString(0x0,0,"Turn Right small");
}
WriteCmd(LCD_CLS);
}
}
if(dir_flag==0)//反转
{
if(zheng==0)
{
zhengzhuan();
}
mot_dir=~mot_dir;
dir=~dir;
if(zuok==0)
{
WriteCmd(LCD_CLS);
zuozhuan=0;
mot_clock=1;
mot_dir=1;
while(zuos!=0)
{
mot_clock=~mot_clock;
clock=~clock;
delay_ms(RunSpeed);
dir=~dir;
DisplayString(0x0,0,"back Turn Left ");
}
WriteCmd(LCD_CLS);
mot_clock=~mot_clock;
}
if(youk==0)
{
WriteCmd(LCD_CLS);
youzhuan=0;
mot_clock=1;
mot_dir=1;
while(yous!=0)
{
mot_clock=~mot_clock;
clock=~clock;
delay_ms(RunSpeed);
mot_dir=~mot_dir;
DisplayString(0x0,0,"back Turn Right ");
}
WriteCmd(LCD_CLS);
}
}
}
}
LCD1602:
/********************************************************************************\
** 宏定义区 **
\********************************************************************************/
/*------------------------------- LCD模块 ------------------------------------*/
sbit LCD_RW =P3^6; //读写控制端
sbit LCD_RS =P1^7; //数据命令选择端
sbit LCD_E =P3^7; //执行使能端
#define Busy 0x80 //忙信号
#define LCD_Data P2
#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 //显示光标
/*------------------------------- 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 delay500ms(void) ;
void write_com(unsigned char com);
void write_data(unsigned char date);
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s);
bit IsBusy(void); //判断忙标志函数
//void DisplayTime(void); //显示时间
//void DisplayAVGSpeed(void); //显示平均速度
//void DisplayDistance(void); //显示路程
/****************************************************************************************\
** LCD驱动模块 **
\****************************************************************************************/
/*--------------------------------- LCD初始化函数--------------------------------------*/
void LCDInit(void)
{
//三次显示模式设置
LCD_Data=0;
LCD_E=Disable;
Delay(5);
WriteCmd(LCD_Init);
Delay(5);
WriteCmd(LCD_Init);
Delay(5);
WriteCmd(LCD_Init);
WriteCmd(LCD_Init); //初始化
WriteCmd(LCD_CloseCtr); //关显示
WriteCmd(LCD_CLS); //清屏幕
WriteCmd(LCD_EnterSet); //光标移动设置
WriteCmd(LCD_DispCtr); //显示开以及光标设置
}
/*--------------------------------- LCD模式设置函数--------------------------------------*\
SetWriteCmd() 设置LCD为写命令模式
SetReadCmd() 设置LCD为读命令模式
SetWriteData() 设置LCD为写数据模式
\*----------------------------------------------------------------------------------------*/
void SetWriteCmd(void)
{
LCD_RW=Write;
LCD_RS=Cmd;
}
void SetReadCmd(void)
{
LCD_RW=Read;
LCD_RS=Cmd;
}
void SetWriteData(void)
{
LCD_RW=Write;
LCD_RS=Data;
}
/*--------------------------------- LCD功能执行函数--------------------------------------*\
WriteCmd() 写命令
WriteData() 写数据
ExecuteCmd() 执行命令
SetXY() 显示定位
DisplaySingleChar() 显示单个字符
DisplayString() 显示一串字符
IsBusy() 忙标志检测
\*----------------------------------------------------------------------------------------*/
void WriteCmd(char cmd)
{
while(IsBusy());
LCD_Data=cmd;
SetWriteCmd();
ExecuteCmd();
}
void WriteData(char ddata)
{
while(IsBusy());
LCD_Data=ddata;
SetWriteData();
ExecuteCmd();
}
void ExecuteCmd(void)
{
LCD_E=Enable;
LCD_E=Disable;
}
void SetXY(char x,char y)
{
if (y)
x|=0x40;
x|=0x80;
Delay(5);
WriteCmd(x);
}
void DisplaySingleChar(char x,char y,char cchar)
{
SetXY(x,y);
WriteData(cchar);
}
void DisplayString(char x,char y,char *str)
{
while(*str)
{
Delay(5);
DisplaySingleChar(x++,y,*str);
str++;
}
}
bit IsBusy(void)
{
LCD_Data=0xFF;
SetReadCmd();
ExecuteCmd();
return (bit)(P2 & 0x80);
}
void write_com(unsigned char com) //写命令
{
LCD_RS=0;
LCD_RW=0;
LCD_Data=com;
Delay(5);
LCD_E=1;
Delay(5);
LCD_E=0;
}
void write_data(unsigned char date) //写一个字符
{
LCD_RS=1;
LCD_RW=0;
LCD_Data=date;
Delay(5);
LCD_E=1;
Delay(5);
LCD_E=0;
}
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
{
if (y == 0)
{
write_com(0x80 + x);
}
else
{
write_com(0xC0 + x);
}
while (*s)
{
write_data( *s);
s ++;
}
}
|