上个程序俺用数码管显示温度,这次就贴个用LCD1602显示的吧,呵呵……
lcd1602硬件连接:
/*----------------------------------------------------------------------------------------------------
TC1602A(16*2)模拟口线接线方式
连接线图:
---------------------------------------------------
|LCM-----51 | LCM-----51 | LCM------51 |
-------------------------------------------------------------------
|D0-----P0.0 | D4-----P0.4 | RW------接地 (只能写) |
|D1-----P0.1 | D5-----P0.5 | RS-------P3.5 |
|D2-----P0.2 | D6-----P0.6 | E---------P3.4 |
|D3-----P0.3 | D7-----P0.7 | VLCD接1K电阻到GND|
--------------------------------------------------- ----------------
[注:AT89c52使用11.0592M晶振]
---------------------------------------------------------------------------------------------------------*/
DS18B20的硬件连接:
这个没有变,和上一个程序一样
程序如下:
#include "reg52.h"
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int
sbit DS=P2^2;
sbit dula=P2^6;
sbit wela=P2^7;
sbit LCD1602_E=P3^4;
sbit LCD1602_RS=P3^5;
uchar flag;
uint temp;
uchar tflag; //温度正负标志位
uint tvalue; //呵呵 刚开始又犯了那个错误,就是tvalue的类型要声明为int型
uchar data disdata[5];
uchar table1[]="temperature:"; //lcd第一行要显示的字符
uchar table2[]=" "; //lcd第二行初始化时使用
/***********************************************
LCD1602 的操作
***********************************************/
void delay(uint x) //延时子函数
{
uint a,b;
for(a=x;a>0;a--)
for(b=10;b>0;b--);
}
/*---------------------------------------------
写指令,看着时序图编写就可以了
------------------------------------------------ */
void lcd_write_cmd(uchar cmd)
{
P0=cmd;
LCD1602_RS=0;
LCD1602_E=0;
delay(10);
LCD1602_E=1;
delay(10);
LCD1602_E=0;
}
/*-----------------------------------
读指令,同样要看着时序图写
-------------------------------------*/
void lcd_write_data(uchar data1)
{
P0=data1;
LCD1602_RS=1;
LCD1602_E=0;
delay(10);
LCD1602_E=1;
delay(10);
LCD1602_E=0;
}
/*-----------------------------------
lcd1602 的初始化设置
-------------------------------------*/
void init_lcd1602(void)
{
dula=0;
wela=0;
lcd_write_cmd(0x38);
delay(20);
lcd_write_cmd(0x0e);
delay(20);
lcd_write_cmd(0x06);
delay(20);
lcd_write_cmd(0x01);
delay(20);
}
/*-----------------------------------
初始化lcd1602的显示时用到的显示函数
-------------------------------------*/
void display(unsigned char *p)
{
while(*p!='\0')
{
lcd_write_data(*p);
p++;
delay(20);
}
}
/*-----------------------------------
初始化lcd1602的显示
-------------------------------------*/
void init_lcd_display(void)
{
init_lcd1602();
lcd_write_cmd(0x80); //设定第一行显示初始地址
delay(20);
display(table1);
lcd_write_cmd(0xc0); //设定第而行显示的初地址
delay(20);
display(table2);
}
/***********************************************
DS18B20 的操作
***********************************************/
/*-----------------------------------
延时函数
-------------------------------------*/
void TempDelay (uchar us)
{
while(us--);
}
/*ds18b20 的初始化*/
void ds_reset(void)
{
DS=1;
_nop_(); //1us
DS=0;
TempDelay(80); //当总线停留在低电平超过480us,总线上所以器件都将被复位,这里延时约530us
//总线停留在低电平超过480μs,总线上的所有器件都将被复位。
_nop_();
DS=1; //产生复位脉冲后,微处理器释放总线,让总线处于空闲状态,原因查18b20中文资料
TempDelay(5); //释放总线后,以便从机18b20通过拉低总线来指示其是否在线,
//存在检测高电平时间:15~60us, 所以延时44us,进行1-wire presence detect(单线存在检测)
_nop_();
_nop_();
_nop_();
if(DS==0)
flag=1; //detect 18b20 success
else
flag=0; //detect 18b20 fail
TempDelay(20); //存在检测低电平时间:60~240us,所以延时约140us
_nop_();
_nop_();
DS=1; //再次拉高总线,让总线处于空闲状态
/**/
}
/*-----------------------------------------------------------
读/写时间隙:
DS1820 的数据读写是通过时间隙处理
位和命令字来确认信息交换。
-------------------------------------------------------------*/
bit ds_read_bit(void) //读一位
{
bit dat;
DS=0; //单片机(微处理器)将总线拉低
_nop_(); //读时隙起始于微处理器将总线拉低至少1us
DS=1; //拉低总线后接着释放总线,让从机18b20能够接管总线,输出有效数据
_nop_();
_nop_(); //小延时一下,读取18b20上的数据 ,因为从ds18b20上输出的数据在读"时间隙"下降沿出现15us内有效
dat=DS; //主机读从机18b20输出的数据,这些数据在读时隙的下降沿出现15us内有效
TempDelay(10); //所有读"时间隙"必须60~120us,这里77us
return(dat); //返回有效数据
}
uchar ds_read_byte(void ) //读一字节
{
uchar value,i,j;
value=0; //一定别忘了给初值
for(i=0;i1;
if(onebit) //写 1
{
DS=0;
_nop_();
_nop_(); //看时序图,至少延时1us,才产生写"时间隙"
DS=1; //写时间隙开始后的15μs内允许数据线拉到高电平
TempDelay(5); //所有写时间隙必须最少持续60us
}
else //写 0
{
DS=0;
TempDelay(8); //主机要生成一个写0 时间隙,必须把数据线拉到低电平并保持至少60μs,这里64us
DS=1;
_nop_();
_nop_();
}
}
}
/*--------------------------------------------------------------------------------------
进行温度转换:
先初始化
然后跳过ROM:跳过64位ROM地址,直接向ds18B20发温度转换命令,适合单片工作
发送温度转换命令
----------------------------------------------------------------------------------------*/
void tem_change()
{
ds_reset();
delay(1); //约2ms
ds_write_byte(0xcc);
ds_write_byte(0x44);
}
/*----------------------------------------
获得温度:
------------------------------------------*/
uint get_temperature()
{
float wendu;
uchar a,b;
ds_reset();
delay(1); //约2ms
ds_write_byte(0xcc);
ds_write_byte(0xbe);
a=ds_read_byte();
b=ds_read_byte();
temp=b;
temp