个人成长笔记--使用89C52在1602液晶屏上显示日期和温度

个人成长笔记–使用89C52在1602液晶屏上显示日期和温度

LCD1602配置过程:

#include "config.h"
#include "Lcd1602.h"//首先判断1602忙不忙
void Read_Busy()
{uint8 busy;LCD_DB = 0xFF;//首先复位数据总线LCD_RS = 0;LCD_RW = 1;do{LCD_EN = 1;//先使能,才可以发送数据busy = LCD_DB;//发送数据LCD_EN = 0;//拉低使能,以便下一次产生上升沿}while(busy & 0x80);//与D7相与,为1表示忙,程序一直循环等待//while(busy |= 0x01);//错了,D7是最高位,所以选择要与最高位相比较
}//写命令
void Write_Cmd_Byte(uint8 cmd)
{Read_Busy();//记住先判断忙不忙LCD_RS = 0;LCD_RW = 0;LCD_DB = cmd;//写入指令LCD_EN = 1;//使能LCD_EN = 0;//每次都要记得拉低使能位,方便下次产生上升沿
}//写数据
void Write_Data_Byte(uint8 dat)
{Read_Busy();//记住先判断忙不忙LCD_RS = 1;LCD_RW = 0;LCD_DB = dat;//写入数据LCD_EN = 1;//使能LCD_EN = 0;//每次都要记得拉低使能位,方便下次产生上升沿
}//清屏
void Clear_Screen()
{Write_Cmd_Byte(0x01);//清除数据
}//打开光标闪烁
void Open_Cursor()
{Write_Cmd_Byte(0x0F);//打开光标
}//关闭光标
void Close_Cursor()
{Write_Cmd_Byte(0x0C);//关闭光标
}//设置指令在哪个位置显示
void Set_Cursor(uint8 x,uint8 y)
{if(y){x |= 0x40;//如果y=1;就在第二行显示,x等于多少就在多少列显示}x |= 0x80;//否则,在第一行显示,//还要写指令,不然怎样显示Write_Cmd_Byte(x);
}//在指定位置显示一个字符串
void Dis_OneChar(uint8 x,uint8 y,uint8 dat)
{									 Set_Cursor(x,y);Write_Data_Byte(dat);
}//在指定位置显示字符串
void Dis_Str(uint8 x,uint8 y,uint8 *str)
{Set_Cursor(x,y);while(*str != '\0'){Write_Data_Byte(*str++);}
}//1602初始化
void LCD1602_Init()
{Write_Cmd_Byte(0x38);//显示模式设置Write_Cmd_Byte(0x0C);//开显示,关闭光标Write_Cmd_Byte(0x06);//读写一字节后地址指针加1Write_Cmd_Byte(0x01);//显示清屏
}

DS18B20配置过程:

#include "config.h"
#include "DS18B20.h"//前提是晶振在11.0952情况下
//us延时函数,执行一次us---所需6.5us进入一次函数需要11.95us
void Delay_us(uchar us)
{while(us--);
}//单总线初始化时序
bit Ds_Init()
{bit i;EA = 0;//禁止总中断DS18B20_IO = 1;//先置高释放一下总线_nop_();//延时5us,稳定一下DS18B20_IO = 0;//再把总线置低,开始复位Delay_us(75);//至少拉低480us,总线将全部被复位,75*6.5+11.95=499.45usDS18B20_IO = 1;//释放总线Delay_us(4);//延时4*6.5+11.95=37.95us,等待18B20发回存在信号i = DS18B20_IO;//把返回值赋值给iDelay_us(20);//延时20*6.5+11.95=141.95us,读取存在信号的时间DS18B20_IO = 1;//释放总线_nop_();//延时5us,稳定一下EA = 1;//使能总中断return(i);//如果i=0则存在总线上,并且DS18B20已经准备好了。
}//写一个字节
void Write_Byte(uchar dat)
{//一次只能写一位,一个字节8位,所以循环8次uchar i;EA = 0;//禁止总中断for(i=0;i<8;i++){DS18B20_IO = 0;//初始化化的时候已经释放总线了,现在直接拉低_nop_();//延时大于1us产生写时序DS18B20_IO = dat & 0x01;//从最低位开始写Delay_us(10);//10*6.5+11.95=76.95us,写0时需要60~120us。写1时需要60us以上,所以都符合DS18B20_IO = 1;//释放总线_nop_();//两个周期之间需要间隔大于1usdat>>=1;//把读到最低位放进高位,然后在把低位放高位,最后最低位就会到最低位}EA = 1;//使能总中断
}//读一个字节
uchar Read_Byte()
{//一次只能读一位,一个字节8位,所以循环8次uchar i,j,dat;EA = 0;//禁止总中断for(i=0;i<8;i++){DS18B20_IO = 0;//初始化化的时候已经释放总线了,现在直接拉低_nop_();//延时大于1us产生读时序DS18B20_IO = 1;//释放总线,交给18B20控制_nop_();j = DS18B20_IO;//从最低位读取,一个读一个位Delay_us(10);//10*6.5+11.95=76.95us,读一位需要延时60~120usDS18B20_IO = 1;//释放总线_nop_();//两个周期之间需要间隔大于1usdat = (j<<7) | (dat>>1);//j把读到最低位左移7位到达dat最高位,dat在整体左移一位}EA = 1;//使能总中断return(dat);
}//启动一次18B20温度转换
bit Start_DS18B20()
{bit ack;ack = Ds_Init();//获取18B20应答if(ack == 0)//如果ack值为0,则应答,if语句就为真{Write_Byte(0xCC);//总线上只有一个18B20,所以跳过ROM操作Write_Byte(0x44);//启动一次温度转换}return ~ack;//ack等于0就是应答,取反就是1,返回1就代表启动成功
}//读取DS18B20转换温度值
bit Get_DS18B20_Temp(int16 *temp)
{bit ack;uint8 LSB,MSB;//16位的温度值的低字节和高字节ack = Ds_Init();//获取18B20应答if(ack == 0)//如果ack值为0,则应答,if语句就为真{Write_Byte(0xCC);//总线上只有一个18B20,所以跳过ROM操作Write_Byte(0xBE);//发送读命令LSB = Read_Byte();//先读低位,一共8位,低位数据存在最低位MSB = Read_Byte();//在读高位,一共8位,高位数据存在最高位*temp = ((int16)MSB << 8) + LSB;//把MSB强制转换成16位,MSB左移8位,把高8位存到高八位,加LSB的低8位,正好转换成整型16位}return ~ack;//ack等于0就是应答,取反就是1,返回1就代表获取成功
}

然后再应用写调用函数:

//获取温度,并显示到液晶屏上
//ops:为0时,只有温度变化才刷新,非0则立即刷新
void RefreshTemp(uint8 ops)
{int16 temp;uint8 pdata str[6];static int16 backup = 0;Get_DS18B20_Temp(&temp);//获取当前温度值Start_DS18B20();//启动下一次转换temp >>= 4;//舍弃4位小数位if((backup!=temp) || (ops!=0))//按照需要刷新液晶显示{str[0] = (temp/10) + '0';//十位转ASCII码str[1] = (temp%10) + '0';//个位转ASCII码str[2] = '\'';//用'C代替°Cstr[3] = 'C';str[4] = '\0';//字符串结束符Dis_Str(12,1,str);//显示到液晶上backup = temp;//刷新上一次温度值}
}

结果显示:
这里以上代码对温度的显示,日期和时间是之前所写。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部