|
附上程序
#include "reg52.h"
#include "intrins.h"
typedef unsigned char BYTE;
typedef unsigned int WORD;
#define FOSC 12000000L //系统频率
#define BAUD 115200 //串口波特率
#define uint unsigned int
#define uchar unsigned char
#define Busy 0x80 //用于检测LCM状态字中的Busy标识
//////液晶屏数据口///////
sbit LCM_RS =P2^0;//定义液晶屏信号引脚
sbit LCM_RW =P2^1;
sbit LCM_E =P2^2;
#define LCM_Data P0//液晶数端口
unsigned char code uctech[] = {"0123456789ABCDEF:"};
sfr AUXR = 0x8e; //辅助寄存器
#define T1MS (65536-FOSC/8000) //1000MS模式
sbit ONA =P2^3;//电机1A
sbit ONB =P2^4;//电机1B
sbit ONC =P2^6;//电机2A
sbit OND =P2^7;//电机2B
sbit Echo1 =P3^2;//超声波数据
sbit Trig1 =P2^5;//超声波启动
void delay(unsigned int z)//延时
{
unsigned int x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
//1ms延时
void Delay5Ms(void)
{
delay(5);
}
void WriteDataLCM(unsigned char WDLCM)
{
//ReadStatusLCM(); //检测忙
LCM_RS = 1;
LCM_Data = WDLCM;
Delay5Ms();
LCM_RW = 0;
LCM_E = 1; //若晶振速度太高可以在这后加小的延时
Delay5Ms();
LCM_E = 0; //延时
}
//写指令
void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测
{
//if (BuysC) ReadStatusLCM(); //根据需要检测忙
LCM_RS = 0;
LCM_Data = WCLCM;
Delay5Ms();
LCM_RW = 0;
LCM_E = 1;
Delay5Ms();
LCM_E = 0;
}
#if 0
//读数据
unsigned char ReadDataLCM(void)
{
LCM_RS = 1;
LCM_RW = 1;
LCM_E = 0;
LCM_E = 0;
LCM_E = 1;
return(LCM_Data);
}
//读状态
unsigned char ReadStatusLCM(void)
{
LCM_Data = ~0xFF;
LCM_RS = 0;
LCM_RW = 1;
LCM_E = 0;
LCM_E = 0;
LCM_E = 1;
while (LCM_Data & Busy); //检测忙信号
return(LCM_Data);
}
#endif
void LCMInit(uchar i) //LCM初始化
{
LCM_Data = 0;
WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
Delay5Ms();
WriteCommandLCM(0x38,0);
Delay5Ms();
WriteCommandLCM(0x38,0);
Delay5Ms();
WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
WriteCommandLCM(0x08,1); //关闭显示
WriteCommandLCM(0x01,1); //显示清屏
WriteCommandLCM(0x06,1); // 显示光标移动设置
WriteCommandLCM(i,1); // 显示开及光标设置
}
void LCMInitc(uchar i)
{
WriteCommandLCM(0x06,0); //光标归位
WriteCommandLCM(i,0); //关光标,闪烁
}
//按指定位置显示一个字符
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData,uchar i)
{
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
X |= 0x80; // 算出指令码
WriteCommandLCM(X,0); //这里不检测忙信号,发送地址码
LCMInitc(i);
Delay5Ms();
LCMInitc(0x0c);
WriteDataLCM(DData);
}
//按指定位置显示一串字符
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
{
unsigned char ListLength;
ListLength = 0;
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
while (DData[ListLength]>0x20) //若到达字串尾则退出
{
if (X <= 0xF) //X坐标应小于0xF
{
DisplayOneChar(X, Y,DData[ListLength],0x0c); //显示单个字符
ListLength++;
X++;
}
}
}
void tim0init()
{
//AUXR |= 0x80; //定时器0为1T模式
TMOD = 0x00; //设置定时器为模式0(16位自动重装载)
TL0 = 0x66; //初始化计时值
TH0 = 0xfc;
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
TMOD|=0x11; //设T1为方式1,GATE=1;
EA=1; //开启总中断
TH1=0;
TL1=0;
ET1=1; //允许T1中断
TR1=0;
EA = 1;
}
WORD U16FLAG;
unsigned int time_c,Dista1;
unsigned char timeH,timeL;
bit succeed_flag;
/********************************************************/
void StartModule()
{
// unsigned int distance;
#if 1
Trig1=1; //启动模块
delay(1);
Trig1=0;
U16FLAG=58477;
while((!Echo1)&&U16FLAG++);
TR1=1; //开启计数
U16FLAG=58477;
while((Echo1)&&U16FLAG++);
TR1=0;
time_c=TH1*256+TL1;
TH1=0;
TL1=0;
Dista1=(time_c*1.7)/100;//算出来是CM
delay(50);
#endif
}
void timer1() interrupt 3 using 1
{
TH0=0;
TL0=0; //中断溢出标志
}
uint tim0[20];
//定时器中断
void tm0_isr() interrupt 1 using 1
{
tim0[0]++;
if(Dista1>110)//加速正转
{
tim0[3]=(Dista1-80);
tim0[2]=65536-FOSC/(tim0[3]*200);
TL0=tim0[2];
TH0=tim0[2]>>8;
switch(tim0[0])
{
case 1: ONA=0;ONB=1;ONC=1;OND=1;break;
case 2: ONA=1;ONB=0;ONC=1;OND=1;break;
case 3: ONA=1;ONB=1;ONC=0;OND=1;break;
case 4: ONA=1;ONB=1;ONC=1;OND=0;tim0[0]=0; break;
}
}
if(Dista1>80&&Dista1<140)//匀速正转
{
tim0[2]=65536-FOSC/3000;
TL0=tim0[2];
TH0=tim0[2]>>8;
switch(tim0[0])
{
case 1: ONA=0;ONB=1;ONC=1;OND=1;break;
case 2: ONA=1;ONB=0;ONC=1;OND=1;break;
case 3: ONA=1;ONB=1;ONC=0;OND=1;break;
case 4: ONA=1;ONB=1;ONC=1;OND=0;tim0[0]=0; break;
}
}
else if(Dista1<=20)//加速反转
{
tim0[3]=(50-Dista1) ;
tim0[2]=65536-FOSC/(tim0[3]*200);
TL0=tim0[2];
TH0=tim0[2]>>8;
switch(tim0[0])
{
case 1: ONA=1;ONB=1;ONC=0;OND=1;break;
case 2: ONA=1;ONB=0;ONC=1;OND=1;break;
case 3: ONA=0;ONB=1;ONC=1;OND=1;break;
case 4: ONA=1;ONB=1;ONC=1;OND=0;tim0[0]=0;break;
}
}
else if(Dista1<=50)//匀速反转
{
tim0[2]=65536-FOSC/3000;
TL0=tim0[2];
TH0=tim0[2]>>8;
switch(tim0[0])
{
case 1: ONA=1;ONB=1;ONC=0;OND=1;break;
case 2: ONA=1;ONB=0;ONC=1;OND=1;break;
case 3: ONA=0;ONB=1;ONC=1;OND=1;break;
case 4: ONA=1;ONB=1;ONC=1;OND=0;tim0[0]=0;break;
}
}
else if(Dista1>50&&Dista1<80)//不转
{
ONA=1;ONB=1;ONC=1;OND=1;
tim0[0]=0;
}
else if(Dista1>140)// 匀速转
{
tim0[2]=65536-FOSC/6000;
TL0=tim0[2];
TH0=tim0[2]>>8;
switch(tim0[0])
{
case 1: ONA=0;ONB=1;ONC=1;OND=1;break;
case 2: ONA=1;ONB=0;ONC=1;OND=1;break;
case 3: ONA=1;ONB=1;ONC=0;OND=1;break;
case 4: ONA=1;ONB=1;ONC=1;OND=0;tim0[0]=0;break;
}
}
}
void main()
{
tim0init();
LCMInit(0x0c); //LCM初始化
Delay5Ms(); //延时片刻(可不要
DisplayListChar(8, 1,"C");//在指定,列显示字符串
DisplayListChar(9, 1,"M");//在指定,列显示字符串
while(1)
{
StartModule();
DisplayOneChar(4,1,uctech[Dista1/1000%10],0x0c);//显示个位
DisplayOneChar(5,1,uctech[Dista1/100%10],0x0c);//显示个位
DisplayOneChar(6,1,uctech[Dista1/10%10],0x0c);//显示个位
DisplayOneChar(7,1,uctech[Dista1%10],0x0c);//显示个位
}
}
|
|