51超声波测距离LCD1602显示程序
51单片机驱动LCD1602程序设计(C语言)
字符液晶绝大多数是基于 HD44780 液晶芯片的,控制原理是完全相同的,因此 HD44780 写 的控制程序可以很方便地应用于市面上大部分的字符型液晶。字符型 LCD 通常有 14 条引脚线或 16 条引脚线的 LCD,多出来的 2 条线是背光电源线 VCC(15 脚)和地线 GND(16 脚),其控制原理 与 14 脚的 LCD 完全一样,定义如下表所示:
for(i=0;i<count;i++) {
if (0 == y) x |= 0x80; //当要显示第一行时地址码+0x80; else x |= 0xC0; //在第二行显示是地址码+0xC0; Write_com(x); //发送地址码 Write_dat(*p); //发送要显示的字符编码 x++; p++; }
01110
○■■■○
10001
■○○○■
10001
■○○○■
10001
■○○○■
11111
■■■■■
10001
■○○○■
10001
■○○○■
上图左边的数据就是字模数据,右边就是将左边数据用“○”代表 0,用“■”代表 1。看出是个“A”
字了吗?在文本文件中“A”字的代码是 41H,PC 收到 41H 的代码后就去字模文件中将代表 A 字的
字符型 LCD 的引脚定义
HD44780 内置了 DDRAM、CGROM 和 CGRAM。DDRAM 就是显示数据 RAM,用来寄存 待显示的字符代码。共 80 个字节,其地址和屏幕的对应关系如下表:
也就是说想要在 LCD1602 屏幕的第一行第一列显示一个"A"字,就要向 DDRAM 的 00H 地址写 入“A”字的代码就行了。但具体的写入是要按 LCD 模块的指令格式来进行的。在 1602 中我们用前 16 个就行了。第二行也一样用前 16 个地址。对应如下:
51单片机超声波测距离(带温度补偿)
超声波模块原理图:发射接收原理图PCB:51单片机原理图:软件部分C语言程序:/*=========================================================== =========调试要求:1.MCU:A T89S52芯片或AT89C522.晶振:12MHz调试注意:本程序带温度补偿,采用DS18B20测量温度1.LCD1602液晶屏有显示后,才接入超声波模块。
2.注意超声波模块电源的极性。
不清楚请参好淘宝的电路图3.没有选用频率为12MHz晶振,用了别的频率晶振,单片机定时器的测量值与发出的40KHz频率脉冲不对。
4.使用者经常误发出20KHZ脉冲当40KHZ脉冲。
(40KHz频率脉冲,周期25us,占空比为50% = 12.5us)5.如果是用开发板调超声波模块,请检查开发板上的电路是否与超声波模块的控制脚复用了, 若复用了,请通过跳线分开发板上的电路。
6如果使用的是万用板,请确定单片机的复位电路和晶振电路是否正常,同时单片机的31脚(EA)记得接高电平。
============================================================= =======*/#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int//===============================LCD1602接口定义=====================/*-----------------------------------------------------|DB0-----P2.0 | DB4-----P2.4 | RW-------P0.1 ||DB1-----P2.1 | DB5-----P2.5 | RS-------P0.2 ||DB2-----P2.2 | DB6-----P2.6 | E--------P0.0 ||DB3-----P2.3 | DB7-----P2.7 | 注意,P0.0到P0.2需要接上拉电阻---------------------------------------------------============================================================= */#define LCM_Data P2 //数据接口#define Busy 0x80 //用于检测LCM状态字中的Busy标识sbit LCM_RW = P0^1; //读写控制输入端,LCD1602的第五脚sbit LCM_RS = P0^2; //寄存器选择输入端,LCD1602的第四脚sbit LCM_E = P0^0; //使能信号输入端,LCD1602的第6脚//===============================超声波模块定义========================sbit RemPin =P3^2;// 接收端(这个不能修改,因为是外部中断(INT0)的引脚) sbit TxPin =P3^1;// 发射端//******************************************************************** ***//ds18b20数字温度传感器控制引脚定义sbit dq_ds18b20=P3^3;//定义控制DS18B20//******************************************************************** ***//LCD显示模块的函数声明void WriteDataLCM (uchar WDLCM);//LCD模块写数据void WriteCommandLCM (uchar WCLCM,BuysC); //LCD模块写指令uchar ReadDataLCM (void);//LCD模块读数据uchar ReadStatusLCM (void);//读LCD模块的忙标void DisplayOneChar (uchar X,uchar Y,uchar ASCII);//在第X+1行的第Y+1位置显示一个字符void DisplayListChar (uchar X,uchar Y,uchar delayms,uchar code *DData); void DisplayCursorPos (uchar X, uchar Y);void LCMInit (void);void DisplayIntData (uchar X, uchar Y,int ZhengShu,uchar Digit,uchar XiaoShu);void DisplayCharData (uchar X, uchar Y,uchar ZiFu);//******************************************************************** **//延时函数声明void delay25us_40KHz(unsigned char us);void DelayUs(uint us);void DelayMs(uint Ms);void delay_3us();//3US的延时程序void delay_8us(unsigned int t);//8US延时基准程序void delay_50us(unsigned int t);//延时50*T微妙函数的声明//******************************************************************** ***//DS18B20测温函数定义void w_1byte_ds18b20(uchar value);//向DS18B20写一个字节uchar r_1byte_ds18b20(void);//从DS18B20读取一个字节的数据void rest_ds18b20(void);//DS18B20复位程序void readtemp_ds18b20(void);//读取温度void display_temp(void);//温度显示程序//******************************************************************** ***//参数定义uint length = 0; // 测距的长度0.00Muchar flag = 0; // 测距的标志有信号接收=1uchar templ,temph;uint speed;//根据温度计算出来的声音速度uchar t_b,t_s,t_g,t_x;//从左到右分别存储温度百位,十位,个位,小数位uchar flag1;//温度正负性暂存,1为正数,0为负数const unsigned char tabl3[]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x0 8,0x09,0x09};/*=========================================================== ================主程序============================================================= ================*/void main(void){uchar i;LCMInit(); //1602初始化EX0 = 1; //允许总中断中断,使能INT0 外部中断ET0 = 1;TMOD=0x11; //设定T0为16位时器,设定T1为16位时器DisplayOneChar( 0,14,'m');DisplayListChar(0,0,0, "Distanc: "); //显示字符串while(1){readtemp_ds18b20();display_temp();//显示温度for(i=0;i<20;i++){DisplayIntData(0, 13,length,5,3);//显示测量距离TH0=0x00;TL0=0x00;TR0=1; //启动定时器0EA = 1; //允许所有中断delay25us_40KHz(15); //发出脉冲信号DelayMs(200);}}}//******************************************************************** ***********//温度显示函数void display_temp(){if(flag1==1)//温度为正数时的显示程序{DisplayOneChar( 1,2,'+');}else{DisplayOneChar( 1,2,'-');}//显示温度信息DisplayOneChar( 1,0,'T');DisplayOneChar( 1,1,':');DisplayOneChar( 1,3,t_s+0x30);DisplayOneChar( 1,4,t_g+0x30);DisplayOneChar( 1,5,'.');DisplayOneChar( 1,6,t_x+0x30);//显示速度信息DisplayOneChar( 1,8,'S');DisplayOneChar( 1,9,':');DisplayOneChar( 1,10,speed/100%10+0x30);DisplayOneChar( 1,11,speed/10%10+0x30);DisplayOneChar( 1,12,speed%10+0x30);DisplayOneChar( 1,13,'M');DisplayOneChar( 1,14,'/');DisplayOneChar( 1,15,'S');}//****************************************************//读取温度void readtemp_ds18b20(void){uchar temp32;rest_ds18b20();w_1byte_ds18b20(0xcc); //跳过读序列号的操作w_1byte_ds18b20(0x44); //启动温度转换delay_8us(2);rest_ds18b20();w_1byte_ds18b20(0xcc); //跳过读序列号的操作w_1byte_ds18b20(0xbe); //读取温度寄存器等(共可读9个寄存器)前两个就是温度templ=r_1byte_ds18b20();temph=r_1byte_ds18b20();if((temph&0xf0))//判断温度的正负性{flag1=0;temph=-temph;templ=-templ;t_x=tabl3[templ & 0x0f];//计算温度的小数temp32=temph & 0x0f;temp32<<=4;templ>>=4;temp32=temp32 | templ;t_b=temp32/100%10;//计算温度的百位数据t_s=temp32/10%10;//计算温度的十位数据t_g=temp32%10;//计算温度的个位数据speed=331.4-0.607*(temp32 | templ);}else//为正数{t_x=tabl3[templ & 0x0f];//计算温度的小数temp32=temph & 0x0f;temp32<<=4;templ>>=4;temp32=temp32 | templ;t_b=temp32/100%10;//计算温度的百位数据t_s=temp32/10%10;//计算温度的十位数据t_g=temp32%10;//计算温度的个位数据flag1=1;speed=311.4+0.607*(temp32 | templ);}}/*=========================================================== =========功能:在1602显示一个整数数据说明:显示一个整数数据-9999->32625. 从右至左显示数据5位:============================================================= =========*/void DisplayIntData(uchar X, uchar Y,int ZhengShu,uchar Digit,uchar XiaoShu) {uchar i=0,k=0, BCD[5]={0};if(Digit>5) Digit=5;if(ZhengShu<0){k=1;//负数示志位ZhengShu=-ZhengShu;}BCD[4] =ZhengShu / 10000; //求出万位数据ZhengShu = ZhengShu % 10000;BCD[3] =ZhengShu / 1000; //求出千位数据ZhengShu = ZhengShu % 1000;BCD[2] =ZhengShu / 100; //求出百位数据ZhengShu = ZhengShu % 100;BCD[1] =ZhengShu / 10; //求出十位数据BCD[0] =ZhengShu % 10; //求出个位数据for(i=0;i<Digit;i++)//输出显示的数值{if((i==XiaoShu)&&(0!=XiaoShu)){DisplayOneChar(X,Y-i,'.');//输出小数点Y= Y-1;}DisplayOneChar(X,Y-i,BCD[i]+0x30); //显示一个字符}if(k==1)DisplayOneChar(X,Y-1,'-');//输出负符}//****************************************************************//读一个字节uchar r_1byte_ds18b20(void){uchar i=0;uchar value= 0;for (i=0;i<8;i++){value>>=1;dq_ds18b20=0;// DQ_L;delay_3us();dq_ds18b20=1; //DQ_H;delay_8us(2);if(dq_ds18b20==1) value|=0x80;delay_8us(6); //延时40us}dq_ds18b20=1;return value;}//******************************************************************** ***********//子程序功能:向DS18B20写一字节的数据void w_1byte_ds18b20(uchar value){uchar i=0;for(i=0;i<8;i++){dq_ds18b20=1;delay_3us();dq_ds18b20=0;delay_8us(2);if (value& 0x01) dq_ds18b20=1; //DQ = 1delay_50us(1); //延时50us 以上delay_8us(2);value>>=1;}dq_ds18b20=1; //DQ = 1}//;**************************************************//ds18b20复位子程序void rest_ds18b20(void){rest:delay_3us(); //稍做延时delay_3us();dq_ds18b20=1;delay_3us();dq_ds18b20=0;// DQ_L;delay_50us(11);//480us<T<960usdq_ds18b20=1;//拉高总线delay_8us(5);if(dq_ds18b20==1){return;}delay_50us(2); //延时90usif(dq_ds18b20==1){return;}else{goto rest;}}//==============================超声波模块测试子程序================================================/*=========================================================== =========注意:是用12MHz晶振设定延时时间:x*25us 与产生40KHZ的脉冲============================================================= =======*/void delay25us_40KHz(unsigned char us){while(us--){TxPin = 0;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();TxPin = 1;_nop_();_nop_();_nop_();_nop_();}TxPin = 1;}/*=========================================================== ==================中断程序的入口(注意:接收与发射的电平是相反的)============================================================= ==================*/void init0int() interrupt 0{uint timer_us = 0;TR0=0; //关闭定时器0timer_us =TH0*256+TL0;if(timer_us>190)timer_us=timer_us-180; //修正测距的距离if(timer_us<=735){timer_us=timer_us-96;//二次修正}if(timer_us>5059){timer_us+=29;}if(timer_us>5470){timer_us+=29;}if(timer_us>6410){timer_us+=29;}if(timer_us>7410){timer_us+=29;}if(timer_us>8410){timer_us+=29;}if(timer_us>9410){timer_us+=29;}if(timer_us>10410){timer_us+=29;}length = ((unsigned long)(speed)*timer_us)/2000;//计算长度,是扩大100倍flag = 0;EA = 0; //禁止所有中断}/*=========================================================== =========功能:在1602显示一个字符数据说明:显示一个字符数据0~256. 从左至右显示数据3位============================================================= =========*/void DisplayCharData(uchar X, uchar Y,uchar ZiFu){uchar i=0;uchar V alueBCD[3];V alueBCD[0] = ZiFu / 100; //求出百位数据ZiFu = ZiFu % 100;V alueBCD[1] = ZiFu / 10; //求出十位数据V alueBCD[2] = ZiFu % 10; //求出个位数据for(i=0;i<3;i++)//输出显示的数值{DisplayOneChar(X,Y+i,V alueBCD[i]+0x30); //显示一个字符}}/*=========================================================== ================超出测量时间============================================================= ================*/void timer0int (void) interrupt 1{TR0=0; //关闭定时器0length = 0; //超出测量时间显示示0flag = 1; //EA = 0; //禁止所有中断}/*=========================================================== ===========LCM初始化============================================================= =========*/void LCMInit(void){LCM_Data = 0;WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号DelayMs(5);WriteCommandLCM(0x38,0);DelayMs(5);WriteCommandLCM(0x38,0);DelayMs(5);WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号WriteCommandLCM(0x08,1); //关闭显示WriteCommandLCM(0x01,1); //显示清屏WriteCommandLCM(0x06,1); // 显示光标移动设置WriteCommandLCM(0x0C,1); // 显示开及光标设置DelayMs(100);}/*=========================================================== =========显示光标的位置============================================================= =======*/void DisplayCursorPos( unsigned char X, unsigned char Y){X &= 0x1;Y &= 0xF; //限制Y不能大于15,X不能大于1if (X) Y |= 0x40; //当要显示第二行时地址码+0x40;Y |= 0x80; // 算出指令码WriteCommandLCM(Y, 1); //这里不检测忙信号,发送地址码}/*=========================================================== =========按指定位置显示一串字符:第X 行,第y列注意:字符串不能长于16个字符============================================================= =========*/void DisplayListChar(uchar X,uchar Y,uchar delayms, uchar code *DData){unsigned char ListLength;ListLength = 0;X &= 0x1;Y &= 0xF; //限制X不能大于15,Y不能大于1while (DData[ListLength]!='\0') //若到达字串尾则退出{if (Y <= 0xF) //X坐标应小于0xF{DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符ListLength++;Y++;DelayMs(delayms);//延时显示字符串}elsebreak;//跳出循环体}}/*=========================================================== =========设定延时时间:x*1us============================================================= =======*/void DelayUs(uint us){while(us--);}/*=========================================================== =========设定延时时间:x*1ms============================================================= =======*/void DelayMs(uint Ms){uint i,TempCyc;for(i=0;i<Ms;i++){TempCyc = 250;while(TempCyc--);}}//==============================LCD1602显示子程序================================================/*=========================================================== ==========写数据函数: E =高脉冲RS=1 RW=0============================================================= =========*/void WriteDataLCM(unsigned char WDLCM){ReadStatusLCM(); //检测忙LCM_Data = WDLCM;LCM_RS = 1;LCM_RW = 0;LCM_E = 0; //若晶振速度太高可以在这后加小的延时LCM_E = 0; //延时LCM_E = 1;}/*=========================================================== =========写指令函数: E=高脉冲RS=0 RW=0============================================================= =========*/void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测{if (BuysC) ReadStatusLCM(); //根据需要检测忙LCM_Data = WCLCM;LCM_RS = 0;LCM_RW = 0;LCM_E = 0;LCM_E = 0;LCM_E = 1;}/*=========================================================== =========//读数据============================================================= =========*/unsigned char ReadDataLCM(void){LCM_RS = 1;LCM_RW = 1;LCM_E = 0;LCM_E = 0;LCM_E = 1;return(LCM_Data);}/*=========================================================== =========正常读写操作之前必须检测LCD控制器状态:E=1 RS=0 RW=1;DB7: 0 LCD控制器空闲,1 LCD控制器忙。
基于51单片机的红外遥控+液晶LCD1602显示程序源代码
基于51单片机的红外遥控+液晶LCD1602显示程序源代码/*******************红外遥控+液晶LCD1602测试程序源代码******************** 单片机型号:STC15W4K56S4,内部晶振:22.1184M。
功能:红外遥控+液晶LCD1602显示功能测试。
操作说明:按下红外遥控器上的“CH-”键,液晶LCD1602上显示“CH-”。
按下红外遥控器上的“CH”键,液晶LCD1602上显示“CH”。
按下红外遥控器上的“CH+”键,液晶LCD1602上显示“CH+”。
按下红外遥控器上的“|<<”键,液晶LCD1602上显示“|<<”。
按下红外遥控器上的“>>|”键,液晶LCD1602上显示“>>|”。
按下红外遥控器上的“>||”键,液晶LCD1602上显示“>||”。
按下红外遥控器上的“-”键,液晶LCD1602上显示“-”。
按下红外遥控器上的“+”键,液晶LCD1602上显示“+”。
按下红外遥控器上的“EQ”键,液晶LCD1602上显示“EQ”。
按下红外遥控器上的“0”键,液晶LCD1602上显示“0”。
按下红外遥控器上的“100+”键,液晶LCD1602上显示“100+”。
按下红外遥控器上的“200+”键,液晶LCD1602上显示“200+”。
按下红外遥控器上的“1”键,液晶LCD1602上显示“1”。
按下红外遥控器上的“2”键,液晶LCD1602上显示“2”。
按下红外遥控器上的“3”键,液晶LCD1602上显示“3”。
按下红外遥控器上的“4”键,液晶LCD1602上显示“4”。
按下红外遥控器上的“5”键,液晶LCD1602上显示“5”。
按下红外遥控器上的“6”键,液晶LCD1602上显示“6”。
按下红外遥控器上的“7”键,液晶LCD1602上显示“7”。
按下红外遥控器上的“8”键,液晶LCD1602上显示“8”。
超声波测距 lcd1602显示
};
}
/********************************************************/
void Conut(void)
{
time=TH0*256+TL0;
TH0=0;
TL0=0;
S=(time*1.7)/100; //算出来是CM
{
WDLCM = ((WDLCM&0x01)<<7)|((WDLCM&0x02)<<5)|((WDLCM&0x04)<<3)|((WDLCM&0x08)<<1)|((WDLCM&0x10)>>1)|((WDLCM&0x20)>>3)|((WDLCM&0x40)>>5)|((WDLCM&0x80)>>7);
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
TX=0;
}
/********************************************************/
void delayms(unsigned int ms)
{
while (DData[ListLength]>0x19) //若到达字串尾则退出
{
if (X <= 0xF) //X坐标应小于0xF
{
DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
ListLength++;
51单片机超声波测距程序
wela=1; P0=0xfe; wela=0; delay(1); }
文档
标准实用文案
/* 被调用子函数 */ void diaoyong()
{ uint i; EA=0; echo=1;
高 trig=1; delay20us(); trig=0; while(echo==0);
{
time=timeh*256+timel;// 计算测定距离,并显示
distance=time*0.1720;
display(distance);
}
if(0,同
时灯闪烁
{
distance=0;
test=!test;
}
}
/* 主函数 */
文档
标准实用文案
// 测试灯
uint timeh,timel,distance; uint ge,shi,bai,xiaoshu,flag,time;
/* 共阴极数码管不带小数点代码表 */
文档
标准实用文案
uchar code list[]={ 0x3f , 0x06 , 0x5b , 0x4f , 0x66 , 0x6d ,0x7d , 0x07 , 0x7f , 0x6f , 0x77 , 0x7c , 0x39 , 0x5e , 0x79 , 0x71 };
void main() {
initime0(); test=0; trig=0; EA=1; while(1) {
diaoyong(); display(distance); } }
文档
标准实用文案
// 超声波测距,测距范围 2cm-400cm; #include<reg52.h> #include<intrins.h>
超声波测距1602显示
//add 为显示字符的位置,x 为显示的字符
{ // //
Write_com(0x01); delay(5); WriteAddress(0x00);
delay(5); Write_com(0x80+0x40+add); WriteData(0x30+x); }
LCD1602()//1602 初显示 { LcdInt(); //调用 LCD 初始化函数 delay(10); Write_com(0x01); //清屏 delay(5); WriteAddress(0x00); //设置显示位置为第一行第一个字,这条语句可以不用写, 因为默认是从第一行第一个字显示
limi=s3/1000; //厘米 s4=s3%1000; haomi=s4/100;//毫米
if(s1>400000) { Write_com(0x80+0x40+3); WriteData('e'); delay(5); WriteData('r'); delay(5); WriteData('r'); delay(5); WriteData('o'); delay(5); WriteData('r'); delay(5); }
/***************************************************** 以上为 1602 模块语句 ***************************************************/
display(unsigned char add,unsigned char x)
/***************************************************** 函数功能:延时 1ms ***************************************************/
基于51单片机的US-100(超声波模块)1602显示程序
/*****************************************************************************/Name: LCD1602+US-100+STC89C52HC-SR04 超声波测距模块串口程序晶振: 11.0592MDesigned by : 庶野琴风Date:2016/08/11QQ:397739038接线:模块TRIG接 P3.1 ECH0 接 P3.0RS(CS)接P2.0;RW(SID)接P2.1;E(SCLK)接P2.2;BF接P0.7;/*****************************************************************************/#include<reg52.h>#include<intrins.h>#define nops {_nop_();_nop_();_nop_();_nop_();}/******************************引脚及变量的定义****************************/ sbit RS = P2^0; // 寄存器选择位sbit RW = P2^1; // 读取选择位sbit E = P2^2;// 使能信号位sbit BF = P0^7; // 忙碌信号位unsigned char code Tab[] = {"0123456789"};unsigned char code string[] = {"range:2cm--4.5m"};char part,ge,shi,bai;char idata GLengthLoh[2];// 接收缓冲区bit success_flag;// 定义测试成功标志位/*********************************************************//********* /********* /*********函数名称: delay1ms(void)函数功能:延时 1 毫秒函数参数: void******************/******************/******************//*********************************************************/void delay1ms(void)// 误差-0.651041666667us{char a,b;for(b=102;b>0;b--)for(a=3;a>0;a--);}/*********************************************************//*********函数名称: delaynms(char n)******************//*********函数功能:延时n 个 1 毫秒******************//*********函数参数: n******************/ /*********************************************************/void delaynms(char n){char a;for(a = 0;a > n;a--)delay1ms();}/*********************************************************//*********函数名称: BusyTest(void)******************//*********函数功能:判断液晶模块忙碌状态******************//*********函数参数:返回值:result******************//*********************************************************/unsigned char BusyTest(){bit result;RS=0;RW=1;//RS为低电平,RW 为高电平时,可以读状态E=1; nops; result = BF; E=0;// 使能为高电平时可读取信息// 延时 40us,给硬件反应时间// 将忙碌标志位电平赋给result // 使能 1 到 0:执行指令return result;}/*********************************************************//*********函数名称: WriteInstruction(char dictate)*******//*********函数功能:将模式设置指令或显示地址写入液晶模块**/ /*********函数参数: dictate******************//*********************************************************/void WriteInstruction(char dictate){while(BusyTest() == 1);// 如果忙碌标志位忙碌则等待RS=0;RW=0;//RS/RW 位同时为低电平时可写入指令E=0;//使能0到 1:写入指令nops;P0 = dictate;// 将数据送入 P0 口,写入数据或地址nops;E=1;//使能0到 1:写入指令nops;E=0;//使能1到 0:执行指令}/*********************************************************//*********函数名称: WriteAddress(char x)*******//*********函数功能:指定字符显示的实际地址***********//*********函数参数: x******************//*********************************************************/void WriteAddress(char x){WriteInstruction(x|0x80);// 80H+地址码}/*********************************************************//*********函数名称: WriteData(char y)*******//*********函数功能:将数据(字符的标准ASCII码 )写入液晶模块 *//*********函数参数: y******************//*********************************************************/void WriteData(char y){while(BusyTest() == 1);// 如果忙碌标志位忙碌则等待RS=1;RW = 0;//RS 为高电平, RW 为低电平时,可以写入数据E=0;P0 = y;nops;E=1;nops;E=0;}/*********************************************************//*********函数名称: LCDInit(void)*******//*********函数功能:液晶模块初始化****************//*********函数参数: void******************//*********************************************************/void LCDInit(void){delaynms(15);// 延时 15 毫秒,首次写入液晶指令应给反应时间WriteInstruction(0x38);// 显示模式设置:16× 2 显示, 5× 7 点阵, 8 位数据接口delaynms(5);//延时 5秒,反应时间WriteInstruction(0x38);delaynms(5);//延时 5秒,反应时间WriteInstruction(0x38);delaynms(5);// 连续三次,确保初始化成功WriteInstruction(0x0c);// 显示模式设置:显示开,无光标,光标不闪烁delaynms(5);WriteInstruction(0x06);// 显示模式设置:显示光标右移,屏幕不移动delaynms(5);WriteInstruction(0x01);// 清屏delaynms(5);}/*********************************************************//********* /*********函数名称: UART_Send(char dat)函数功能:串口发送函数*******/****************//*********函数参数: dat******************/ /*********************************************************/void UART_Send(char dat){TI=0; SBUF = dat;//清发送标志//如果 TI为 0等待while (!TI);// 等待发送数据}/*********************************************************//*********函数名称: UART_Init()***************//*********函数功能:串口初始化函数****************//*********函数参数:无******************//*********************************************************/void UART_Init(){TH1 = 0xFD;TL1 = 0xFD;TMOD = 0x21;// 设置定时器 1 为模式 2;定时器 0 为模式 1 TH0 =(65536-2500)/256;// 约 2.50MS 定时器初值TL0 =(65536-2500)%256;// 约 2.50MS 定时器初值ET0 = 1;TR0 = 1;// 启动定时器TR1 = 1;// 启动定时器SM0SM1SM0 = 0;// 串口通信模式设置00 = 0SM1 = 1;//0 1 = 1//10 = 2//1 1 = 3 REN = 1;// 串口允许接收数据ES = 1;// 开串中断EA=1;}/*********************************************************//*********函数名称: UART_ISR(void)***************//*********函数功能:串口中断函数****************//*********函数参数: void******************//*********************************************************/void UART_ISR(void) interrupt 4{char temp,k;ES=0;if(RI){// 关中断RI=0;temp = SBUF;// 清接收标志GLengthLoh[k] = temp;k++;if(k == 2) //k= 数据长度k = 0;}ES=1;// 开中断}/*********************************************************//********* /********* /*********函数名称: timer0()函数功能:定时器函数函数参数: void***************/****************/******************//*********************************************************/timer0() interrupt 1//定时器0 中断是 1 号{TH0 =(65536-2500)/256; // 约TL0 =(65536-2500)%256; // 约2.50MS 定时器初值2.50MS 定时器初值TH0 = 0xef;TL0 = 0x94;// 写入定时器0 初始值}/*********************************************************//*********函数名称: conversion(int8 temp_data)*******//*********函数功能:数据转换****************//*********函数参数: temp_data******************//*********************************************************/void conversion(int temp_data){char part_data,ge_data,shi_data,bai_data;bai_data = temp_data / 1000;shi_data = (temp_data % 1000) / 100;ge_data = (temp_data % 100) / 10;part_data = temp_data % 10;EA=0;bai = bai_data;shi = shi_data;ge = ge_data;part = part_data;EA=1;}/*********************************************************//*********函数名称: main(void)*******/ /*********函数功能:主函数****************/ /*********函数参数: void******************/ /*********************************************************/void main(void){int k;long PreLength;LCDInit();// 调用液晶初始化函数delaynms(10);UART_Init();PreLength = 0;k = 0;while(1){WriteAddress(0x01);while(string[k] != '\0'){WriteData(string[k]);k++;}UART_Send(0X55);PreLength = GLengthLoh[0] * 256 + GLengthLoh[1] - 5;conversion(PreLength);WriteAddress(0x41); WriteData('J');// 从第 2 行第 6 列开始显示// 将特定的字符常量写入LCDWriteData('U');WriteData('L');WriteData('I');WriteData(':');if(PreLength <= 4500 && PreLength >= 20){WriteData(Tab[bai]);// 将百位数字的字符常量写入LCD WriteData(Tab[shi]);// 将十位数字的字符常量写入LCD WriteData(Tab[ge]);// 将个位数字的字符常量写入LCD WriteData('.');WriteData(Tab[part]);}else{WriteData('-');WriteData('-');WriteData('-');WriteData('-');WriteData('-');}WriteData(' ');WriteData('c');WriteData('m');} }。
基于51单片机超声波测距报警系统课程设计
基于51单片机超声波测距报警系统课程设计一、引言超声波测距技术是一种常见的非接触式测距技术,具有测距范围广、精度高等优点。
在日常生活中,超声波测距技术被广泛应用于车辆倒车雷达、智能家居中的人体感应等领域。
本文将介绍基于51单片机的超声波测距报警系统的课程设计。
二、设计思路本课程设计主要分为硬件设计和软件设计两部分。
硬件部分主要包括超声波模块、LCD显示屏、蜂鸣器等模块的连接和电路设计;软件部分主要包括51单片机程序设计及LCD显示程序编写。
三、硬件设计1. 超声波模块连接超声波模块是实现测距功能的核心部件。
在本课程设计中,我们采用HC-SR04型号的超声波模块。
该模块需要连接到51单片机上,具体连接方式如下:- 将VCC引脚连接到51单片机上的5V电源;- 将GND引脚连接到51单片机上的GND;- 将Trig引脚连接到P2.0口;- 将Echo引脚连接到P2.1口。
2. LCD显示屏连接LCD显示屏用于显示测距结果和报警信息。
在本课程设计中,我们采用1602型号的LCD显示屏。
该模块需要连接到51单片机上,具体连接方式如下:- 将VSS引脚连接到51单片机上的GND;- 将VDD引脚连接到51单片机上的5V电源;- 将VO引脚连接到一个10K电位器,再将电位器两端分别接到GND 和5V电源;- 将RS引脚连接到P1.0口;- 将RW引脚连接到P1.1口;- 将EN引脚连接到P1.2口;- 将D4-D7引脚分别连接到P0口的高四位。
3. 蜂鸣器连接蜂鸣器用于报警。
在本课程设计中,我们采用被动式蜂鸣器。
该模块需要连接到51单片机上,具体连接方式如下:- 将正极引脚(一般为长针)连接到51单片机上的P3.7口;- 将负极引脚(一般为短针)连接到51单片机上的GND。
四、软件设计1. 51单片机程序设计在本课程设计中,我们采用Keil C51作为编程工具,使用C语言编写程序。
主要程序流程如下:- 定义超声波模块的Trig和Echo引脚;- 定义LCD显示屏的RS、RW、EN和D4-D7引脚;- 定义蜂鸣器的引脚;- 定义变量存储测距结果和报警状态;- 初始化LCD显示屏、超声波模块等模块;- 循环执行以下操作:- 发送超声波信号并计算回波时间,从而得到距离值;- 根据距离值判断是否需要报警,并控制蜂鸣器发出报警声音;- 将测距结果和报警状态显示在LCD显示屏上。
51单片机LCD1602液晶显示的接法
51单片机综合学习之1602字符型液晶显示篇在日常生活中,我们对液晶显示器并不陌生。
液晶显示模块已作为很多电子产品的通过器件,如在计算器、万用表、电子表及很多家用电子产品中都可以看到,显示的主要是数字、专用符号和图形。
在单片机的人机交流界面中,一般的输出方式有以下几种:发光管、LED数码管、液晶显示器。
发光管和LED数码管比较常用,软硬件都比较简单,在前面章节已经介绍过,在此不作介绍,本章重点介绍字符型液晶显示器的应用。
在单片机系统中应用晶液显示器作为输出器件有以下几个优点:显示质量高由于液晶显示器每一个点在收到信号后就一直保持那种色彩和亮度,恒定发光,而不像阴极射线管显示器(CRT)那样需要不断刷新新亮点。
因此,液晶显示器画质高且不会闪烁。
数字式接口液晶显示器都是数字式的,和单片机系统的接口更加简单可靠,操作更加方便。
体积小、重量轻液晶显示器通过显示屏上的电极控制液晶分子状态来达到显示的目的,在重量上比相同显示面积的传统显示器要轻得多。
功耗低相对而言,液晶显示器的功耗主要消耗在其内部的电极和驱动IC上,因而耗电量比其它显示器要少得多。
10.8.1 液晶显示简介①液晶显示原理液晶显示的原理是利用液晶的物理特性,通过电压对其显示区域进行控制,有电就有显示,这样即可以显示出图形。
液晶显示器具有厚度薄、适用于大规模集成电路直接驱动、易于实现全彩色显示的特点,目前已经被广泛应用在便携式电脑、数字摄像机、PDA移动通信工具等众多领域。
②液晶显示器的分类液晶显示的分类方法有很多种,通常可按其显示方式分为段式、字符式、点阵式等。
除了黑白显示外,液晶显示器还有多灰度有彩色显示等。
如果根据驱动方式来分,可以分为静态驱动(Static)、单纯矩阵驱动(Simple Matrix)和主动矩阵驱动(Active Matrix)三种。
③液晶显示器各种图形的显示原理:线段的显示点阵图形式液晶由M×N个显示单元组成,假设LCD显示屏有64行,每行有128列,每8列对应1字节的8位,即每行由16字节,共16×8=128个点组成,屏上64×16个显示单元与显示RAM区1024字节相对应,每一字节的内容和显示屏上相应位置的亮暗对应。
lcd1602程序流程图
lcd1602程序流程图lcd1602程序流程图1、引脚3(对⽐调整电压)接正电源时对⽐度最低,接地时对⽐度最⾼,通常通过⼀个10k的电位器相连后接地,上电后需要对电位器进⾏调整以显⽰出相应的字符(就像调节电视的对⽐度使图像清晰,这⾥是使字符清晰)2、D0~D7为8为数据总线,⽤于与单⽚机之间的数据传送了解了引脚功能后,我们再来看其内置芯⽚关于HD44780HD44780内部含有DDRAM,CGROM,CGRAM下⾯我来简单介绍⼀下这三个存储器DDRAM是⽤于寄存待显⽰字符代码的,其内部带有80字节的RAM 缓冲区,与LCD屏幕的位置⼀⼀对应。
通常我们只使⽤前16个地址(两⾏32个),这样⼀来,我们便可以将这32个地址当作是我们的坐标,⽐如要在DDRAM的02H 地址(对应的是屏幕第⼀⾏第三个)显⽰字符“A”,我们就可以分两步⾛,⾸先⽤程序先找到“坐标点”,也就是将地址转到02H(具体如何不做详细说明),然后在这个位置写⼊“A”,写⼊地址和数据都是通过D0~D7实现的,详细的程序在⽂章的后⾯举例说明。
CGROM与CGRAM是LCD内部固化的字模存储器,这相当于芯⽚内部划出的⼀块区域,CGROM⾥⾯存放着我们⽇常所使⽤的⼀些字符(192个),⽽CGRAM则允许⽤户⾃定义⼀些字符(8个)。
具体对应关系如下,0x00~0x0F就是⽤户⾃定义的CGRAM区。
再回到之前的问题,在DDRAM的02H地址显⽰字符“A”,⾸先通过程序找到地址02H,然后在该地址写⼊41H,从图中也可看出该位置对应的字符就是“A”。
我们再来理⼀理这个过程,有关字符显⽰,⾸先便是找到DDRAM 中我们所要显⽰位置对应的地址,接着便是在这个地址写⼊⼀个地址(单⽚机中的间接寻址),LCD根据这个地址在CGROM中找到对应的字符,然后在02H这个位置显⽰出来,这个过程也到此结束。
由于CGROM中的字符代码与PC中的字符代码基本⼀致,通常我们也直接在02H地址直接写⼊“A”,简化了程序设计。
51单片机的液晶显示超声波测距仪
#include"1602.h"#define uchar unsigned char#define uint unsigned intsbittring = P1^3; //超声波控制端sbit echo = P3^2; //回波必须接在外部中断引脚上sbitledwarn = P2^0; //报警灯,低电平亮sbit beep = P2^1; //报警蜂鸣器uintdisplayCount;//显示计数uint time = 0;//时间unsigned long distance ;//距离float distancef;//浮点型的数据uintflagSucceed = 0; //测量成功标志位uintflagDisplay = 0; //开显示标志位void delay_20us(){uchari ;for(i=0;i<140;i++);}voidinit_shuju(){tring = 0;distance = 0;displayCount = 0;}void init_waibu0(){IT0 = 0; //外部引脚为低时触发中断EX0=0; //关闭外部中断}void timer0_Init(){TMOD = 0x11; //定时器0和1工作在16位方式TH0 = (65535-45872)/256;TL0 = (65535-45872)%6;TR0 = 1; //启动定时器ET0 = 1; //允许定时器0中断}void timer1_Init(){TMOD = 0x11; //定时器0和1工作在16位方式TH1 = 0;TL1 = 0;ET1 = 1; //定时器1中断允许}void wbzd0() interrupt 0//下降沿触发{time =TH1*256+TL1; //取出定时器的值flagSucceed = 1; //置成功测量的标志EX0=0; //关闭外部中断// TR1=0;}void timer0() interrupt 1 // 定时器0{TH0 = (65535-45872)/256;TL0 = (65535-45872)%6;displayCount ++;if (displayCount>= 20) //1秒钟显示一次{flagDisplay = 1; //开显示displayCount = 0;}}void start_csb() //启动csb模块{tring = 1;delay_20us();tring = 0;}void main(){EA=0;init_shuju();init_waibu0();timer0_Init();timer1_Init();L1602_init();L1602_string(1,1,"welcome my ");L1602_string(2,1,"test distance "); delay1(1);while(1){EA=0;//关闭总中断start_csb();while(echo==0);//变高则进入下一步flagSucceed = 0;TR1=1; //启动定时器1开始计数EA = 1;EX0=1;TH1= 0;TL1= 0;TF1= 0; //定时器1溢出标志位while (TH1<90) ; //盲区TR1 = 0; //关闭定时器1EX0 = 0; //关闭外部中断if(flagSucceed==1) //一次测试成功,则计算距离,单位为厘米{distancef = time * 1.085;//微妙为单位distancef /=58;//单位为厘米distance = distancef*10+0.5;//如果距离小于20cm,则声光报警if ((flagSucceed == 1) && (distance <= 200)){ledwarn = 0;beep = 0;delay1(1);beep = 1;delay1(1);}else{ledwarn = 1;beep = 1;}}if (flagDisplay == 1) //1秒显示时间到{if(flagSucceed==0)//没有测试成功{L1602_string(1,1," can't distance ");L1602_string(2,1," ------ ");}else{//LCD显示数据L1602_string(1,1,"distance result:");L1602_string(2,1," cm ");L1602_int(2,5,distance);}flagDisplay = 0;}}}。
超声波测距程序(LCD1602液晶显示)
#include<reg52.h>#include<intrins.h>#define uint unsignedint#define uchar unsigned char#define NOP() {_nop_();_nop_();_nop_();_nop_();}//------LCD引脚-----sbit LCD_RS=P2^6;sbit LCD_RW=P2^5;sbit LCD_EN=P2^7;//------超声波引脚-------sbitTx=P3^3; //触发控制信号输入Trigsbit Rx=P3^2; //回响信号输出Echouchar code table[]={"Distance Test:"}; //LCD第一行显示uchartemp_dis[]= {"000.0 cm"}; //LCD第二行longintt,distance;uchar cache[4]={0,0,0,0};//--------延时-------void delay(uintms){uint t;while(ms--)for(t=0;t<120;t++);}//-------读LCD状态-------ucharread_lcd_state(){uchar state;LCD_RS=0;LCD_RW=1;LCD_EN=1;_nop_();state=P0;LCD_EN=0;_nop_();return state;}//-------忙等待------voidlcd_busy_wait(){while((read_lcd_state() & 0x80)==0x80);NOP();}//----------LCD写指令----------voidlcd_write_com(uchar com){lcd_busy_wait();LCD_RS=0; //RS为0时,写指令,RS为1时,写数据LCD_RW=0;P0=com;NOP();LCD_EN=1;NOP();LCD_EN=0;}//----------LCD写数据----------voidlcd_write_data(uchardat){lcd_busy_wait();LCD_RS=1;LCD_RW=0;P0=dat;NOP();LCD_EN=1;NOP();LCD_EN=0;}//-------LCD初始化-------voidlcd_init(){LCD_EN=0;lcd_write_com(0x38); //LCD显示模式设置lcd_write_com(0x0c); //LCD显示开/关及光标设置lcd_write_com(0x06); //当写一个字符后地址指针加1,且光标加1 lcd_write_com(0x01); //显示清屏}//---------设置液晶显示位置-----------voidset_lcd_pos(uchar p){lcd_write_com(p|0x80);}//---------液晶显示程序----------voidlcd_print(ucharp,uchar *s,uint low){uintnum;set_lcd_pos(p);for(num=0;num<low;num++){lcd_write_data(s[num]);delay(1);}}void HC05_Init(){Tx=1; //触发脉冲NOP();NOP();NOP();NOP();Tx=0;distance=0.17*t; //距离计算}voiddistance_convert(long intdat){cache[0]=dat/1000;cache[1]=dat/100%10;cache[2]=dat/10%10;cache[3]=dat%10;temp_dis[0]=cache[0]+'0';temp_dis[1]=cache[1]+'0';temp_dis[2]=cache[2]+'0';temp_dis[4]=cache[3]+'0';}//------------主程序-----------void main(){lcd_init();delay(5);TMOD=0x19;EA=1; //开总中断TR0=1; //启动定时器EX0=1; //开外部中断IT0=1; //设置为下降沿中断方式while(1){HC05_Init();distance_convert(distance);lcd_print(0x01,table,14);lcd_print(0x44,temp_dis,8);}}//外部中断0void int0() interrupt 0{t=(TH0*256+TL0); //计算高电平持续的时间,上升沿到来时候开始计时,下降沿到来进入外部中断,关闭计时器,停止计时TH0=0;TL0=0;}。
超声波测距LCD1602显示
超声波测距LCD1602显示超声波测距模块:1、采用IO口TRIG触发测距,给至少10us的高电平信号;2、模块自动发送8个40khz的方波,自动检测是否有信号返回;3、有信号返回,通过IO口ECHO输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。
测试距离=(高电平时间*声速(340M/S))/2。
液晶LCD1602电路接口超声波测距LCD1602显示程序源代码/*******************超声波测距1602显示********************* 单片机:51单片机* 开发环境:keil* 名称:超声波测距1602显示注意:用杜邦线将超声波模块的VCC接开发板5V对外供电接口用杜邦线将超声波模块的GND接开发板GND用杜邦线将超声波模块的Trig接单片机的P1.5用杜邦线将超声波模块的Echo接单片机的P1.6/************************包含头文件************************/#include <reg51.h>#define LCD_Data P0#define Busy 0x80/**************************宏定义**************************/#define SPEED_30C 3495 //30摄氏度时的声速,声速V=331.5+0.6*温度;#define SPEED_23C 3453 //23摄氏度时的声速,声速V=331.5+0.6*温度;/**************************位定义**************************/sbit ECHO = P2^1; //回声接收端口sbit TRIG = P2^0; //超声触发端口sbit BEEP = P2^3; //蜂鸣器sbit LCD_RS = P1^0;sbit LCD_RW = P1^1;sbit LCD_E = P2^5;/**********************定义变量和数组**********************/long int distance = 0; //距离变量unsigned char code table0[] = {" SL-51A "};unsigned char code table1[] = {" NO ECHO "};unsigned char code table2[] = {"Distance:xxx.xcm"};unsigned char count;void Delay5Ms(void);void delay(int In,int Out);void WriteDataLCD(unsigned char WDLCD);void WriteCommandLCD(unsigned char WCLCD,BuysC);unsigned char ReadDataLCD(void);unsigned char ReadStatusLCD(void);void LCDInit(void);void DisplayOneChar(unsigned char X,unsigned char Y,unsigned char DData);void DisplayListChar(unsigned char X,unsigned char Y,unsigned char code *DData); /**********************************************************//* 函数名称 : Delay_xMs *//* 函数描述 : 延时函数 *//* 输入参数 : x *//* 参数描述 : 延时时间 *//* 返回值 : 无 *//**********************************************************/void Delay_xMs(unsigned int x){unsigned int i,j;for(i=0;i<x;i++){for(j=0;j<3;j++){;}}}/**********************************************************//* 函数名称 : delayt *//* 函数描述 : 延时函数 *//* 输入参数 : x *//* 参数描述 : 延时时间数据 *//* 返回值 : 无 *//**********************************************************/void delayt(unsigned int x){unsigned char j;while(x-->0){for(j=0;j<125;j++){;}}}/*************************5ms延时函数**********************/void Delay5Ms(void){unsigned int TempCyc = 3552;while(TempCyc--);}/**************************延迟函数************************/void delay(int In,int Out) {int i,j;for(i=0;i<In;i++){for(j=0;j<Out;j++){;}}}/**********************************************************//* 函数名称 : Alarm *//* 函数描述 : 蜂鸣器发声函数 *//* 输入参数 : t *//* 参数描述 : 发声的次数 *//* 返回值 : 无 *//**********************************************************/void Alarm(unsigned char t){unsigned char i;for(i=0;i<t;i++){BEEP=0;delay(10,1000);BEEP=1;delay(10,1000);}}/**********************************************************//* 函数名称 : Init_timer *//* 函数描述 : 初始化单片机函数 *//* 输入参数 : 无 *//* 参数描述 : 无 *//* 返回值 : 无 *//**********************************************************/void Init_timer(void){TMOD=0x01; //定时器2初始化,设置为16位自动重装模式TL0=0x66;TH0=0xfc; //1msET0=1; //开定时器2EA=1; //总中断使能}/**********************************************************//* 函数名称 : Init_Parameter *//* 函数描述 : 初始化参数和IO口函数 *//* 输入参数 : 无 *//* 参数描述 : 无 *//* 返回值 : 无 *//**********************************************************/void Init_Parameter(void){TRIG=1;ECHO=1;count=0;distance=0;}/**********************************************************//* 函数名称 : display *//* 函数描述 : 显示数字 *//* 输入参数 : number,address *//* 参数描述 : number写入的数据 *//* 返回值 : 无 *//**********************************************************/ void display(int number){unsigned char b,c,d,e;b=(number/1000);c=(number/100)%10;d=(number/10)%10;e=number%10; DisplayOneChar(9,1,(0x30+b));DisplayOneChar(10,1,(0x30+c));DisplayOneChar(11,1,(0x30+d));DisplayOneChar(13,1,(0x30+e));}/**********************************************************//* 函数名称 : Trig_SuperSonic *//* 函数描述 : 发出声波函数 *//* 输入参数 : 无 *//* 参数描述 : 无 *//* 返回值 : 无 *//**********************************************************/ void Trig_SuperSonic(void) //出发声波{TRIG=1;delayt(1);TRIG=0;}/**********************************************************//* 函数名称 : Measure_Distance *//* 函数描述 : 计算距离函数 *//* 输入参数 : 无 *//* 参数描述 : 无 *//* 返回值 : 无 *//**********************************************************/ void Measure_Distance(void){unsigned char l;unsigned int h,y;TR0=1;while(ECHO){;}TR0=0;l=TL0;h=TH0;y=(h<<8)+l;y=y-0xfc66; //us部分distance=y+1000*count; //计算总时间TL0=0x66;TH0=0xfc;delayt(30);distance=SPEED_30C*distance/20000;}/*********************写数据函数***************************/void WriteDataLCD(unsigned char WDLCD){ReadStatusLCD(); //检测忙LCD_Data=WDLCD;LCD_E=0; //若晶振速度太高可以在这后加小的延时LCD_E=0; //延时LCD_RS=1;LCD_RW=0;LCD_E=1;LCD_E=0;}/***********************写指令函数*************************/void WriteCommandLCD(unsigned char WCLCD,BuysC) //BuysC为0时忽略忙检测{if (BuysC) ReadStatusLCD(); //根据需要检测忙LCD_Data=WCLCD;LCD_E=0;LCD_E=0;LCD_RS=0;LCD_RW=0;LCD_E=1;LCD_E=0;}/************************读数据函数************************/unsigned char ReadDataLCD(void){LCD_RS=1;LCD_RW=1;LCD_E=0;LCD_E=0;LCD_E=1;return(LCD_Data);}/************************读状态函数************************/unsigned char ReadStatusLCD(void){LCD_Data=0xFF;LCD_RS=0;LCD_RW=1;LCD_E=0;LCD_E=0;LCD_E=1;while (LCD_Data & Busy); //检测忙信号return(LCD_Data);}/************************LCD初始化*************************/void LCDInit(void) //LCD初始化{LCD_Data=0;WriteCommandLCD(0x38,0);Delay5Ms(); //三次显示模式设置,不检测忙信号WriteCommandLCD(0x38,0);Delay5Ms();WriteCommandLCD(0x38,0);Delay5Ms();WriteCommandLCD(0x38,1); //显示模式设置, 开始要求每次检测忙信号 WriteCommandLCD(0x08,1); //关闭显示WriteCommandLCD(0x01,1); //显示清屏WriteCommandLCD(0x06,1); //显示光标移动设置WriteCommandLCD(0x0C,1); //显示开及光标设置}/***********************清屏函数***************************/void LCD_Clear(void){WriteCommandLCD(0x01,1);Delay5Ms();}/*******************按指定位置显示一个字符******************/void DisplayOneChar(unsigned char X,unsigned char Y,unsigned char DData){Y&=0x1;X&=0xF; //限制X不能大于15,Y不能大于1if(Y)X|=0x40; //当要显示第二行时地址码+0x40;X|=0x80; //算出指令码WriteCommandLCD(X, 0); //这里不检测忙信号,发送地址码WriteDataLCD(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]); //显示单个字符ListLength++;X++;}}}/**********************************************************//* 函数名称 : main *//* 函数描述 : 主函数 *//* 输入参数 : 无 *//* 参数描述 : 无 *//* 返回值 : 无 *//**********************************************************/void main(void){LCDInit();Init_timer();Init_Parameter();Alarm(2);DisplayListChar(0,0,table0);DisplayListChar(0,1,table1);while(1){Trig_SuperSonic(); //触发超声波发射while(ECHO==0){;} //等待回声Measure_Distance(); //计算脉宽并转换为距离DisplayListChar(0,1,table2);display(distance); //显示距离Init_Parameter(); //参数重新初始化delayt(100); //延时,两次发射之间要至少有10ms间隔 }}/**********************************************************//* 函数名称 : timer0 *//* 函数描述 : T0中断处理函数 *//* 输入参数 : 无 *//* 参数描述 : 无 *//* 返回值 : 无 *//**********************************************************/void timer0 (void) interrupt 1{TF0=0;TL0=0x66;TH0=0xfc;count++;if(count==18) //超声波回声脉宽最多18ms{TR0=0;TL0=0x66;TH0=0xfc;count=0;}}。
51单片机LCD1602液晶显示程序
LCD1602_E = 1; //写入时序
Lcd1602_Delay1ms(5);
LCD1602_E = 0;
}
#endif
/******************************************************************************
*
*函数名 * 函数功能
: 初始化 LCD 屏 :无 :无
*******************************************************************************
/
#ifndef
LCD1602_4PINS
void LcdInit()
//LCD 初始化子程序
{ LcdWriteCom(0x38); //开显示
//以下程序都是在 VC++6.0 上调试运行过的程序,没有错误,没有警告。 //单片机是 STC89C52RC,但是在所有的 51 52 单片机上都是通用的。51 只是一个学习的基础 平台,你懂得。 //程序在关键的位置添加了注释。 //用//11111111111111111 代表第一个程序。//2222222222222222222222222 代表第二个程序, 以此类推
for(a=1;a>0;a--); } }
//误差 0us
}
/******************************************************************************
*
*函数名 * 函数功能
: LcdWriteCom : 向 LCD 写入一个字节的命令
LCD1602_E = 0;
51单片机超声波模块程序
51单片机超声波模块程序//main.c#include#include#include "lcd1602.h"unsigned char TimeH, TimeL;unsigned int time;float distance;char temp[16];sbit Trig = P1^0;sbit Echo = P1^1;void Timer0Init();void main(){Lcd1602Init();Trig = 0; //初始化while(1){Timer0Init();Trig = 1;while(Echo == 0); //当Echo变为高电平时立即启动定时器以减小误差TR0 = 1;while (Echo == 1);//等待捕获Echo从高到低的跳变TimeL = TL0; //当Echo由高到低,立即将TH0,TL0的值记下TimeH = TH0;Trig = 0;TR0 = 0;time = TimeH;time <<= 8;time += TimeL;distance = time * 0.017;//将distance的值以%f的格式,格式输出到字符数组temp中,变成字符串,//便于显示//sprintf在头文件stdio.h中sprintf(temp, "%f", distance);Lcd1602WriteStr(0x80, temp);}}void Timer0Init(){TMOD = 0X01;TH0 = 0;TL0 = 0;TF0 = 0;EA = 1;}void timer0() interrupt 1 //定时器0中断,防止溢出{TH0 = 0;TL0 = 0;}//lcd1602.h#ifndef __LCD1602_H__#define __LCD1602_H__#includesbit Lcd1602E = P2^7;sbit Lcd1602RW = P2^5;sbit Lcd1602RS = P2^6;void Lcd1602WriteCmd (unsigned char cmd);void Lcd1602WriteData (unsigned char dat);void Lcd1602BusyCheck();void Lcd1602WriteStr(unsigned char addr, unsigned char str[]); void Lcd1602Init ();#endif//lcd1602.c#include "lcd1602.h"#include#define Lcd1602DataPort P0#define Busy 0x80unsigned char ix;void Lcd1602Init (){Lcd1602WriteCmd (0x38);Lcd1602WriteCmd (0x0c);Lcd1602WriteCmd (0x06);Lcd1602WriteCmd (0x01);Lcd1602WriteCmd (0x80);}void Lcd1602WriteCmd(unsigned char cmd) {Lcd1602BusyCheck();Lcd1602RS = 0;Lcd1602RW = 0;Lcd1602DataPort = cmd;for (ix = 0xff; ix > 0; --ix);//延时Lcd1602E = 1;for (ix = 0xff; ix > 0; --ix);Lcd1602E = 0;for (ix = 0xff; ix > 0; --ix);Lcd1602RW = 1;}void Lcd1602WriteData (unsigned char dat) {Lcd1602BusyCheck();Lcd1602RS = 1;Lcd1602RW = 0;Lcd1602DataPort = dat;for (ix = 0xff; ix > 0; --ix);Lcd1602E = 1;for (ix = 0xff; ix > 0; --ix);Lcd1602E = 0;for (ix = 0xff; ix > 0; --ix);Lcd1602RW = 1;}void Lcd1602BusyCheck() //忙检测{Lcd1602RS = 0;Lcd1602RW = 1;for (ix = 0xff; ix > 0; --ix);Lcd1602E = 1;while ((Lcd1602DataPort & Busy) != 0); Lcd1602E = 0;}void Lcd1602WriteStr(unsigned char addr, unsigned char str[]) {unsigned char i;Lcd1602WriteCmd (addr);for (i = 0; i < strlen(str); i++)Lcd1602WriteData(str[i]);}。
超声波测距—1602显示
#include <reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intsbit ech0=P3^2;sbit trig=P1^4;sbit rs=P1^2;sbit rw=P1^1;sbit en=P1^0;unsigned int time,timeH,timeL,distance;unsigned char succeed_flag;/**************************延时函数*******************************/ void delay(unsigned int z){unsigned char x,y;for(x=z;x>0;x--)for(y=110;y>0;y--); //延时1ms}/*************************延时20us***********************************/ void delay_20us(){unsigned char a;for(a=0;a<10;a++);}/**************液晶1602显示程序**************************/void write_com(unsigned char com) //写命令{rs=0;rw=0;P2=com;delay(5);en=1;delay(5);en=0;}void write_data(unsigned char date) //写数据{rs=1;rw=0;P2=date;delay(5);en=1;delay(5);en=0;}/************************液晶字符输入**************************/ void zifu_1602(unsigned char *str) //写字符{while(*str!='\0'){write_data(*str);str++;}}/**************************数字输入*****************************/ void shuzi_1602(unsigned char dat) //写数字{unsigned char dat1;dat1=dat+'0';write_data(dat1);}/************************液晶输入的位置*************************/ void weizhi_1602(unsigned char x,unsigned char y){if(x==1){write_com(0x80+y); //第一行}if(x==2){write_com(0x80+0x40+y); //第二行}}/***************************液晶显示函数***************************/ void display(unsigned int k){unsigned char aa,bb,cc;aa=distance / 100;bb=distance / 10%10;cc=distance % 10;weizhi_1602(1,4);shuzi_1602(aa);weizhi_1602(1,5);shuzi_1602(bb);weizhi_1602(1,6);shuzi_1602(cc);}/****************************液晶初始化******************************/ void init(){rw=0;en=0;write_com(0x38);write_com(0x0c);write_com(0x06);write_com(0x01);write_com(0x80);weizhi_1602(1,2);zifu_1602("S");weizhi_1602(1,3);zifu_1602("=");weizhi_1602(1,7);zifu_1602("c");weizhi_1602(1,8);zifu_1602("m");}void main(){init();trig=0;EA=1;TMOD=0X10; //定时器1,16位工作方式while(1){EA=0;trig=1; //触发控制信号delay_20us();trig=0; //产生一个延时为20us的波while(ech0==0); //等待echo回波引脚边为高电平succeed_flag=0; //清测量成功标志EA=1;EX0=1; //开外部中断0TH1=0;TL1=0; //定时器1清0TF1=0; //计数溢出标志TR1=1; //启动定时器1delay(20); //等待测量结果TR1=0; //关闭定时器1EX0=0; //关闭外部中断0if(succeed_flag==1){time=timeH*256+timeL;distance=time*1.87/100; //cmdisplay(distance);}if(succeed_flag==0) //无回波,清0{distance=0;}}}void exter() interrupt 0 //外部中断0,判断回波电平{timeH=TH1;timeL=TL1; //取出定时器值succeed_flag=1; //成功测量的标志EX0=0; //关闭外部中断}void timer1() interrupt 3 //定时器1中断,用做超声波测距计时{TH1=0;TL1=0;}。
51单片机加HC—SR04超声波测距仪用LCD1602显示
51单片机加HC—SR04超声波测距仪用LCD1602显示#include ;#include ;#define uchar unsigned char#define uint unsigned intsbit lcden=P1^2;sbit lcdrs=P1^0;sbit lcdrw=P1^1;sbit RX=P2^1;sbit TX=P2^0;uint time=0;unsigned long S=0;bit flag =0;uchar disdat[4]={ 0,0,0,0,};void delay(uint z) //延时子程序{uint x,y;for(x=z;x>;0;x--)for(y=110;y>;0;y--);}void write_com(uchar com)//定义一个带参数的写命令子程序{lcdrs=0; //1602的rs为0时,接收命令,为1时接收数据P0=com;//把void write_com(uchar com)中的COM中的数据给P0口delay(5);lcden=1;delay(5);lcden=0;delay(5);}void write_shu(uchar shu)//定义一个带参数的写数据子程序{lcdrs=1; //1602的rs为0时,接收命令,为1时接收数据P0=shu;//把void write_shu(uchar shu)中的COM中的数据给P0口delay(5);lcden=1;delay(5);lcden=0;delay(5);}void write_1602(uchar add,uchar dat){write_com(0x80+0x40+add);write_shu(dat);}void zifuchuan(uchar *ch){while(*ch!=0)write_shu(*ch++);delay(20);}void init()//定义一个初始化子程序{lcden=0;lcdrw=0;write_com(0x38);//调用 write_com子程序并把0x38赋给P0口,显示模式打开delay(2);write_com(0x0c);//调用 write_com子程序并把“开显示,显示光标,光标不闪烁”指令码赋给P0口write_com(0x06);//调用 write_com子程序并把“地址指针加1,整屏不移动”指令码赋给P0口write_com(0x80);//数据指针初始化,让指针指向最左端,显示从第一行开始write_com(0x01);//调用 write_com子程序并把"清零指"令码赋给P0口zifuchuan("HHSY Zhoujiaoshi");}/************************************************ ********/void Conut(){time=TH0*256+TL0;TH0=0;TL0=0;//S=(time*1.7)/100;S=time/58;//算出来是CMdisdat[0]=S%1000/100;disdat[1]=S%1000%100/10;disdat[2]=S%1000%10 %10;write_1602(1, disdat[0]+0x30);write_1602(2, disdat[1]+0x30);write_1602(3, disdat[2]+0x30);write_1602(4,'.');write_1602(5, disdat[3]+0x30);write_1602(6, 'C');write_1602(7, 'm');}/************************************************ ********/void zd0() interrupt 1 //T0中断用来计数器溢出,超过测距范围{flag=1;//中断溢出标志}/********************************************************/void StartModule()//启动模块{TX=1; //启动一次模块 _nop_(); _nop_(); _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();TX=0;}/************************************************ *********/void main(void){delay(400); //启动等待,等LCD讲入工作状态init(); //LCD初始化TMOD=0x01;//设T0为方式1,GATE=1;TH0=0;TL0=0;ET0=1; //允许T0中断EA=1;//开启总中断while(1){StartModule();while(!RX); //当RX为零时等待TR0=1;//开启计数while(RX);//当RX为1计数并等待TR0=0;//关闭计数Conut();//计算delay(20);}}。
超声波测距lcd1602显示
#include <reg52.h>#include <intrins.h>#define uchar unsigned char // 以后unsigned char就可以用uchar代替#define uint unsigned int // 以后unsigned int 就可以用uint 代替sbit LcdRs_P = P2^6; // 1602液晶的RS管脚sbit LcdRw_P = P2^5; // 1602液晶的RW管脚sbit LcdEn_P = P2^7; // 1602液晶的EN管脚sbit Trig_P = P2^2; // 超声波模块的Trig管脚sbit Echo_P = P2^3; // 超声波模块的Echo管脚/*********************************************************/ // 毫秒级的延时函数,time是要延时的毫秒数/*********************************************************/ void DelayMs(uint time){uint i,j;for(i=time;i>0;i--)for(j=112;j>0;j--);}/*********************************************************/ // 1602液晶写命令函数,cmd就是要写入的命令/*********************************************************/ void LcdWriteCmd(uchar cmd){LcdRs_P = 0;LcdRw_P = 0;LcdEn_P = 0;P0=cmd;DelayMs(1);LcdEn_P = 1;DelayMs(1);LcdEn_P = 0;}/*********************************************************/ // 1602液晶写数据函数,dat就是要写入的命令/*********************************************************/ void LcdWriteData(uchar dat){LcdRs_P = 1;LcdRw_P = 0;LcdEn_P = 0;P0=dat;DelayMs(1);LcdEn_P = 1;DelayMs(1);LcdEn_P = 0;}/*********************************************************/ // 1602液晶初始化函数/*********************************************************/ void LcdInit(){LcdWriteCmd(0x38); // 16*2显示,5*7点阵,8位数据口LcdWriteCmd(0x0C); // 开显示,不显示光标LcdWriteCmd(0x06); // 地址加1,当写入数据后光标右移LcdWriteCmd(0x01); // 清屏}/*********************************************************/ // 液晶光标定位函数/*********************************************************/ void LcdGotoXY(uchar line,uchar column){// 第一行if(line==0)LcdWriteCmd(0x80+column);// 第二行if(line==1)LcdWriteCmd(0x80+0x40+column);}/*********************************************************/ // 液晶输出字符串函数/*********************************************************/ void LcdPrintStr(uchar *str){while(*str!='\0')LcdWriteData(*str++);}/*********************************************************/ // 液晶输出数字/*********************************************************/ void LcdPrintNum(uint num){LcdWriteData(num/1000+0x30); // 千位LcdWriteData(num%1000/100+0x30); // 百位LcdWriteData(num%100/10+0x30); // 十位LcdWriteData(num%10+0x30); // 个位}/*********************************************************/// 计算测到的距离/*********************************************************/uint GetDistance(void){uint ss; // 用于记录测得的距离Trig_P=1; // 给超声波模块一个开始脉冲DelayMs(1);Trig_P=0;while(!Echo_P); // 等待超声波模块的返回脉冲TH0=0;TL0=0;TF1=0; //计数溢出标志TR0=1; // 启动定时器,开始计时while(Echo_P); // 等待超声波模块的返回脉冲结束TR0=0; // 停止定时器,停止计时ss=((TH0*256+TL0)*0.34)/2; // 距离cm=(时间us * 速度cm/us)/2TH0=0;TL0=0;return ss;}/*********************************************************/// 按键扫描/*********************************************************//*********************************************************/// 报警判断/*********************************************************/void main(){uint dist;LcdInit(); // 01、首先,执行液晶初始化TMOD = 0x01; // 02、选择定时器0,并且确定是工作方式1 ,用于计时LcdGotoXY(0,1); // 03、定位到第0行第1列LcdPrintStr("US-100 System"); // 04、第0行显示“us-100 System”LcdGotoXY(1,5); // 05、定位到第1行第1列LcdPrintStr("S= mm"); // 06、第0行显示“S= mm”while(1){dist=GetDistance(); // 07、通过超声波模块获取距离LcdGotoXY(1,7); // 08、定位到第0行第1列LcdPrintNum(dist); // 09、将获取到的距离在液晶上面显示}}。
基于51单片机的用 LCD1602 显示时钟的程序
用LCD1602 显示的时钟2012-04-30 15:04有这样一个题目:求一个为51 单片机编写的LCD 电子时钟的设计,简单就好!希望说一下怎么设计这个时钟,都需要些什么东西,最重要的——把这个设计需要的程序写出来。
设计的任务:以单片机控制的时钟,在LCD 显示器上显示当前的时间。
设计的基本要求:1.使用文字型LCD 显示器显示当前时间。
2.显示格式为“时时:分分:秒秒”。
3.用4个功能键操作来设置当前时间。
各个功能键的功能如下:K1:进入设置现在的时间。
K2:设置小时。
K3:设置分钟。
K4:确认完成设置。
4. 程序执行后工作指示灯LED 闪烁,表示程序开始执行,LCD 显示“00:00:00”,然后开始计时。
题目链接:/question/416705477.html//==================================================提到设计时钟,很多人都想到了时钟芯片DS1302,都说它简单、准确。
其实,这是个误区。
仅仅使用一般的单片机,简单的编程,达到相同DS1302 的准确度,并不是难事。
如果不要求计算平闰年、不要求分清大小月、不要求计算星期几,只是要求一个简单的时钟(及日历),用DS1302,就是自寻烦恼。
大家可以打开题目链接,看看其中的一些答案,就可以看出使用DS1302 是多么的繁琐了,简直就是一场噩梦。
做而论道以前就使用普通的单片机和LCD1602 设计过《时钟与日历》,程序设计的非常合理,时间精度就完全取决于晶振的精度。
设计出来的时钟,几个月都差不上一秒。
针对这个题目,做而论道翻出了以前的设计,删节了一些不需要的功能,设计出了符合题目要求的时钟,用PROTEUS 仿真截图如下:程序用C 语言编写,全部代码如下://---------------------------------------------------#include<reg52.h>#define uchar unsigned char#define uint unsigned int#define KEY_IO P3#define LCD_IO P0sbit LCD_RS = P2^0;sbit LCD_RW = P2^1;sbit LCD_EN = P2^2;sbit SPK = P1^2;sbit LED = P2^4;bit new_s, modify = 0;char t0, sec = 50, min = 59, hour = 23;char code LCD_line1[] = "Designed by ZELD"; char code LCD_line2[] = "Timer: 00:00:00 "; char Timer_buf[] = "23:59:50";//---------------------------------------------------void delay(uint z){uint x, y;for(x = z; x > 0; x--) for(y = 100; y > 0; y--);//---------------------------------------------------void W_LCD_Com(uchar com) //写指令{LCD_RS = 0; LCD_IO = com; // LCD_RS和R/W都为低电平时,写入指令LCD_EN = 1; delay(5); LCD_EN = 0; //用EN输入一个高脉冲}//---------------------------------------------------void W_LCD_Dat(uchar dat) //写数据{LCD_RS = 1; LCD_IO = dat; // LCD_RS为高、R/W为低时,写入数据LCD_EN = 1; delay(5); LCD_EN = 0; //用EN输入一个高脉冲}//---------------------------------------------------void W_LCD_STR(uchar *s) //写字符串{while(*s) W_LCD_Dat(*s++);}//---------------------------------------------------void W_BUFF(void) //填写显示缓冲区{Timer_buf[7] = sec % 10 + 48; Timer_buf[6] = sec / 10 + 48;Timer_buf[4] = min % 10 + 48; Timer_buf[3] = min / 10 + 48;Timer_buf[1] = hour % 10 + 48;Timer_buf[0] = hour / 10 + 48;W_LCD_Com(0xc0 + 7); W_LCD_STR(Timer_buf);}//---------------------------------------------------uchar read_key(void){uchar x1, x2;KEY_IO = 255;x1 = KEY_IO;if (x1 != 255) {delay(100);x2 = KEY_IO;if (x1 != x2) return 255;while(x2 != 255) x2 = KEY_IO;if (x1 == 0x7f) return 0;else if (x1 == 0xbf) return 1;else if (x1 == 0xdf) return 2;else if (x1 == 0xef) return 3;else if (x1 == 0xf7) return 4;}return 255;//---------------------------------------------------void Init(){LCD_RW = 0;W_LCD_Com(0x38); delay(50);W_LCD_Com(0x0c);W_LCD_Com(0x06);W_LCD_Com(0x01);W_LCD_Com(0x80); W_LCD_STR(LCD_line1);W_LCD_Com(0xC0); W_LCD_STR(LCD_line2);TMOD = 0x01; //T0定时方式1TH0 = 0x4c;TR0 = 1; //启动T0PT0 = 1; //高优先级, 以保证定时精度ET0 = 1;EA = 1;}//---------------------------------------------------void main(){uint i, j;uchar Key;Init();while(1) {//-------------------------------if (new_s) { //如果出现了新的一秒, 修改时间new_s = 0; sec++; sec %= 60;if(!sec) { min++; min %= 60;if(!min) { hour++; hour %= 24;}}W_BUFF(); //写显示//-------------------------------if (!sec && !min) { //整点报时for (i = 0; i < 200; i++) {SPK = 0; for (j = 0; j < 100; j++);SPK = 1; for (j = 0; j < 100; j++);} }}//-------------------------------Key = read_key(); //读出按键switch(Key) { //分别处理四个按键case 0: modify = 1; break;case 1: if(modify) {min++; min %= 60; W_BUFF(); break;}case 2: if(modify) {hour++; hour %= 24; W_BUFF(); break;}case 3: modify = 0; break;} }}//---------------------------------------------------void timer0(void) interrupt 1 //T0中断函数, 50ms执行一次{TH0 = 0x4c;t0++; t0 %= 20; //20, 一秒钟if(t0 == 0) {new_s = 1; LED = ~LED;}if(modify) LED = 0;}//===================================================呵呵,全部程序,也不过120 行左右。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
S=(time*1.7)/10; //算出来是MM
if((S>=7000)||flag==1) //超出测量范围
{
flag=0;
DisplayListChar(0, 1, table1);
}
else
{
disbuff[0]=S%10;
#include <reg52.h> //器件配置文件
#include <intrins.h>
#include <stdio.h>
sbit RX=P3^6;
sbit TX=P3^7;
sbit LCM_RW=P2^5 ;//定义LCD引脚
sbit LCM_RS=P2^4;
sbit LCM_E=P2^6;
{
unsigned char i=100,j;
for(;ms;ms--)
{
while(--i)
{
j=10;
while(--j);
}
}
}*/
void Timer_Count(void)
{
TR0=1; //开启计数
while(RX); //当RX为1计数并等待
LCM_RS = 0;
LCM_RW = 1;
LCM_E = 0;
LCM_E = 0;
LCM_E = 1;
while (LCM_Data & Busy); //检测忙信号
return(LCM_Data);
}
void LCMInit(void) //LCM初始化
{
LCM_Data = 0;
void StartModule() //启动模块
{
TX=1; //启动一次模块
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
unsigned char code table[]="Distance:000.0cm";
unsigned char code table1[]="!!! Out of range";
//static unsigned char DisNum = 0; //显示用指针
unsigned int time=0;
WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
Delay5Ms();
WriteCommandLCM(0x38,0);
Delay5Ms();
WriteCommandLCM(0x38,0);
Delay5Ms();
WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
void Decode(unsigned char ScanCode);
void WriteDataLCM(unsigned char WDLCM);//LCD1602写数据函数
void WriteCommandLCM(unsigned char WCLCM,BuysC);//LCD写命令函数
TMOD=0x01;//设T0为方式1,GATE=1;
EA=1;
TH0=0;
TL0=0;
ET0=1; //允许T0中断
//开启总中断
while(1)
{
RX=1;
StartModule();
#define LCM_Data P0
sbit Key_Data=P3^1; //定义Keyboard引脚
sbit Key_CLK=P3^2;
#define Busy 0x80 //用于检测LCM状态字中的Busy标识
void LCMInit(void);//LCD初始化函数
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);//LCD显示一个字符函数
X |= 0x80; //算出指令码
WriteCommandLCM(X, 1); //发命令字
WriteDataLCM(DData); //发数据
}
//按指定位置显示一串字符
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);//LCD显示一个字符串函数
void Delay5Ms(void);//延时5毫秒函数
void Delay400Ms(void);//延时400毫秒函数
DisplayOneChar(11, 1, ASCII[disbuff[1]]);
DisplayOneChar(12, 1, ASCII[10]);
DisplayOneChar(13, 1, ASCII[disbuff[0]]);
}
}
/********************************************************/
WriteCommandLCM(0x08,1); //关闭显示
WriteCommandLCM(0x01,1); //显示清屏
WriteCommandLCM(0x06,1); // 显示光标移动设置
WriteCommandLCM(0x0c,1); // 显示开及光标设置
}
//按指定位置显示一个字符
{
unsigned char ListLength;
ListLength = 0;
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
while (DData[ListLength]>0x19) //若到达字串尾则退出
{
if (X <= 0xF) //X坐标应小于0xF
while(TempCycB--);
};
}
/********************************************************/
void Conut(void)
{
time=TH0*256+TL0;
TH0=0;
TL0=0;
unsigned long S=0;
bit flag =0;
unsigned char disbuff[4]={ 0,0,0,0,};
//写数据
void WriteDataLCM(unsigned char WDLCM)
{
ReadStatusLCM(); //检测忙
LCM_Data = WDLCM;
LCM_RS = 1;
LCM_RW = 0;
LCM_E = 0; //若晶振速度太高可以在这后加小的延时
LCM_E = 0; //延时
LCM_E = 1;
}
//写指令
void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测
TR0=0; //关闭计数
Conut(); //计算
}
/*********************************************************/
void main(void)
{
unsigned int valA;
void zd0() interrupt 1 //T0中断用来计数器溢出,超过测距范围
{
flag=1; //中断溢出标志
RX=0;
}
/********************************************************/
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
{
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;
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
while(TempCyc--);
}
//400ms延时
void Delay400Ms(void)
{
unsigned char TempCycA = 5;
unsigned int TempCycB;
while(TempCycA--)
{
TempCycB=7269;