基于51单片机的循线测距测速及1602显示Word文件下载.docx
《基于51单片机的循线测距测速及1602显示Word文件下载.docx》由会员分享,可在线阅读,更多相关《基于51单片机的循线测距测速及1602显示Word文件下载.docx(15页珍藏版)》请在冰豆网上搜索。
voidDecode(unsignedcharScanCode);
voidWriteDataLCM(unsignedcharWDLCM);
voidWriteCommandLCM(unsignedcharWCLCM,BuysC);
voidfun2(void);
voidfun3(void);
voidfun4(void);
voidfun5(void);
unsignedcharReadDataLCM(void);
unsignedcharReadStatusLCM(void);
unsignedcharcodemcustudio[]={"
…………."
};
unsignedcharcodeemail[]={"
…………"
unsignedcharcodeCls[]={"
……………"
unsignedcharcodeASCII[15]={'
0'
'
1'
2'
3'
4'
5'
6'
7'
8'
9'
.'
-'
M'
staticunsignedcharDisNum=0;
//显示用指针
unsignedinttime=0;
unsignedlongS=0;
bitflag=0;
unsignedchardisbuff[4]={0,0,0,0,};
bitFlg_5ms=0;
unsignedcharCounter_100ms=0;
unsignedcharbuf[5]={0,0,0,0,0};
unsignedintSpeed;
unsignedintspeed_frequency;
//frequency
unsignedintspeed_catch1;
//catch1
unsignedintspeed_catch2;
//catch2
unsignedcharspeed_t2_ovf_count_temp;
//T1overflowcountertempregister
unsignedcharspeed_t2_ovf_count;
//T1overflowcounterregister
unsignedcharspeed_catch_p;
//catchpointer
//写数据
voidWriteDataLCM(unsignedcharWDLCM)
{
ReadStatusLCM();
//检测忙
LCM_Data=WDLCM;
LCM_RS=1;
LCM_RW=0;
LCM_E=0;
//假设晶振速度太高能够在这后加小的延时
//延时
LCM_E=1;
}
//写指令
voidWriteCommandLCM(unsignedcharWCLCM,BuysC)//BuysC为0时忽略忙检测
if(BuysC)ReadStatusLCM();
//依照需要检测忙
LCM_Data=WCLCM;
LCM_RS=0;
//读数据
unsignedcharReadDataLCM(void)
LCM_RW=1;
return(LCM_Data);
//读状态
unsignedcharReadStatusLCM(void)
LCM_Data=0xFF;
while(LCM_Data&
Busy);
//检测忙信号
voidLCMInit(void)//LCM初始化
LCM_Data=0;
WriteCommandLCM(0x38,0);
//三次显示模式设置,不检测忙信号
Delay5Ms();
WriteCommandLCM(0x38,1);
//显示模式设置,开始要求每次检测忙信号
WriteCommandLCM(0x08,1);
//关闭显示
WriteCommandLCM(0x01,1);
//显示清屏
WriteCommandLCM(0x06,1);
//显示光标移动设置
WriteCommandLCM(0x0F,1);
//显示开及光标设置
//按指定位置显示一个字符
voidDisplayOneChar(unsignedcharX,unsignedcharY,unsignedcharDData)
Y&
=0x1;
X&
=0xF;
//限制X不能大于15,Y不能大于1
if(Y)X|=0x40;
//当要显示第二行时地址码+0x40;
X|=0x80;
//算出指令码
WriteCommandLCM(X,1);
//发命令字
WriteDataLCM(DData);
//发数据
//按指定位置显示一串字符
voidDisplayListChar(unsignedcharX,unsignedcharY,unsignedcharcode*DData)
unsignedcharListLength;
ListLength=0;
while(DData[ListLength]>
0x19)//假设抵达字串尾那么退出
{
if(X<
=0xF)//X坐标应小于0xF
{
DisplayOneChar(X,Y,DData[ListLength]);
//显示单个字符
ListLength++;
X++;
}
}
//5ms延时
voidDelay5Ms(void)
unsignedintTempCyc=5552;
while(TempCyc--);
//400ms延时
voidDelay400Ms(void)
unsignedcharTempCycA=5;
unsignedintTempCycB;
while(TempCycA--)
TempCycB=7269;
while(TempCycB--);
};
/********************************************************/
voidConut(void)
{
time=TH0*256+TL0;
TH0=0;
TL0=0;
S=(time*1.7)/100;
//算出来是CM
if((S>
=700)||flag==1)//超出测量范围显示"
-"
{
flag=0;
DisplayOneChar(0,1,ASCII[11]);
DisplayOneChar(1,1,ASCII[10]);
//显示点
DisplayOneChar(2,1,ASCII[11]);
DisplayOneChar(3,1,ASCII[11]);
DisplayOneChar(4,1,ASCII[12]);
//显示M
}
else
disbuff[0]=S%1000/100;
disbuff[1]=S%1000%100/10;
disbuff[2]=S%1000%10%10;
DisplayOneChar(0,1,ASCII[disbuff[0]]);
DisplayOneChar(2,1,ASCII[disbuff[1]]);
DisplayOneChar(3,1,ASCII[disbuff[2]]);
voidzd0()interrupt1//T0中断用来计数器溢出,超过测距范围
flag=1;
//中断溢出标志
voidStartModule()//启动模块
TX=1;
//启动一次模块
_nop_();
TX=0;
//--------------------------------------------
voidfun2(void)
{P10=1;
P11=0;
P12=1;
P13=0;
}//前进
voidfun3(void)
{P10=0;
}//左转
voidfun4(void)
P12=0;
}//右转
voidfun5(void)
}//停止
voidtimer1()interrupt3//T0中断用来计数器溢出,超过测距范围
Flg_5ms=1;
TH1=0xee;
TL1=0;
TF1=0;
if(P14==1&
&
P15==0&
P16==1)fun2();
if((P14==0&
P16==1)||(P14==0&
P15==1&
P16==1))fun3();
if((P14==1&
P16==0)||(P14==1&
P16==0))fun4();
P16==0)||(P17==0))fun5();
//-------------------------------------------
voidTimer2()interrupt5//按时器2捕捉中断,溢出中断
if(TF2)
if(speed_t2_ovf_count_temp<
2)speed_t2_ovf_count_temp++;
else
speed_frequency=0;
speed_catch1=0;
speed_catch2=0;
speed_catch_p=0;
speed_t2_ovf_count_temp=0;
//T2overflowcountertempregister
speed_t2_ovf_count=0;
//T2overflowcounterregister
Speed=0;
TF2=0;
if(EXF2)
switch(speed_catch_p)
case0:
speed_catch1=RCAP2H;
speed_catch1<
<
=8;
speed_catch1+=RCAP2L;
speed_catch_p++;
break;
case1:
speed_catch2=RCAP2H;
speed_catch2<
speed_catch2+=RCAP2L;
speed_t2_ovf_count=speed_t2_ovf_count_temp;
default:
EXF2=0;
/*********************************************************/
voidmain(void)
unsignedcharTempCyc;
unsignedlongtemp;
Delay400Ms();
//启动等待,等LCM讲入工作状态
LCMInit();
//LCM初始化
//延时片刻(可不要)
DisplayListChar(0,0,mcustudio);
DisplayListChar(0,1,email);
ReadDataLCM();
//测试用句无心义
for(TempCyc=0;
TempCyc<
10;
TempCyc++)
DisplayListChar(0,1,Cls);
while
(1)
TMOD=0x11;
//设T0为方式1,GATE=1;
T2CON=0x09;
//捕捉模式
ET0=1;
//许诺T0中断
ET1=1;
ET2=1;
EA=1;
//开启总中断
TR1=1;
//开启计数
TR2=1;
if(Flg_5ms)
Flg_5ms=0;
if(Counter_100ms<
39)
{
Counter_100ms++;
if(Counter_100ms==20)
if(speed_catch_p>
1)
{
temp=(unsignedlong)((65536UL*speed_t2_ovf_count)+speed_catch2-speed_catch1);
//calculateT
Speed=(unsignedint)(9584640UL/temp);
speed_catch_p=0;
}
if(Speed>
9999U)Speed=9999U;
buf[0]=Speed/1000;
buf[1]=(Speed/100)%10;
buf[2]=(Speed/10)%10;
buf[3]=Speed%10;
DisplayOneChar(8,1,ASCII[buf[0]]);
DisplayOneChar(9,1,ASCII[buf[1]]);
DisplayOneChar(10,1,ASCII[buf[2]]);
DisplayOneChar(11,1,ASCII[buf[3]]);
DisplayOneChar(12,1,'
m'
);
DisplayOneChar(13,1,'
DisplayOneChar(14,1,'
/'
DisplayOneChar(15,1,'
s'
}else
Counter_100ms=0;
StartModule();
//DisplayOneChar(0,1,ASCII[0]);
TH0=0;
while(!
RX);
//当RX为零时等待
TR0=1;
while(RX);
//当RX为1计数并等待
TR0=0;
//关闭计数
Conut();
//计算
}
}