|
電路原理圖如下:
采用11.0592Mhz晶振,stc89c52芯片實(shí)時(shí)LCD602實(shí)時(shí)顯示DS18B20溫度值.
主程序
#include"ds18b20.h"
#include"lcd1602.h"
void main()
{
uint i;
uchar L,M;
uchar display[3];
ds_init();
write_byte(0xcc);//發(fā)送跳躍ROM指令
write_byte(0x4e);//寫暫存器指令
write_byte(0x7f);
write_byte(0xf7);
write_byte(0x7f);//配置工作在12位模式下
ds_init(); //初始化DS18B20
write_byte(0xcc);//發(fā)送跳躍ROM指令
write_byte(0x48);//寫入EEPROM
LCD_init(); //lcd初始化
while(1)
{
ds_init(); //初始化DS18B20
write_byte(0xcc);//發(fā)送跳躍ROM指令
write_byte(0x44);//發(fā)送溫度轉(zhuǎn)換指令
Delay_Ms(1);
ds_init(); //初始化DS18B20
write_byte(0xcc);//發(fā)送跳躍ROM指令
write_byte(0xbe);//讀取DS18B20暫存器值
L = read_byte(); //L
M = read_byte(); //H
i = M;
i <<= 8;
i |= L;
i = i * 0.0625 * 10 + 0.5;
display[0]=(uint)i/100;
display[1]=(uint)i%100/10;
display[2]=(uint)i%10;
Write_Cmd(0x80|0x00);
Write_Dat(display[0]+0x30);
Write_Cmd(0x80|0x01);
Write_Dat(display[1]+0x30);
Write_Cmd(0x80|0x02);
Write_Dat('.');
Write_Cmd(0x80|0x03);
Write_Dat(display[2]+0x30);
//Delay_Ms(20);
}
}
DS18B20.h文件
#ifndef _ds18b20_h_
#define _ds18b20_h_
#include"reg52.h"
#include"intrins.h"
#define MAIN_Fosc 11059200UL //宏定義主時(shí)鐘HZ
//#define uchar unsigned char //定義無(wú)符號(hào)字符型變量
//#define uint unsigned int //定義無(wú)符號(hào)整型變量
typedef unsigned char INT8U;
typedef unsigned char uchar;
typedef unsigned int INT16U;
typedef unsigned int uint;
/*硬件接口位聲明*/
sbit DS = P2^2; //DS18B20單總線
/*描述:12T 51單片機(jī)自適應(yīng)主時(shí)鐘毫秒級(jí)延時(shí)函數(shù)*/
void Delay_Ms(INT16U ms);
/*單總線初始化時(shí)序*/
bit ds_init();
/*寫一個(gè)字節(jié)*/
void write_byte(uchar dat);
/*讀一個(gè)字節(jié)*/
uchar read_byte();
/*us延時(shí)函數(shù),執(zhí)行一次US--所需6.5us進(jìn)入一次函數(shù)需要11.95us*/
void Delay_us(uchar us);
void Delay_5us();
#endif
DS18B20.c文件
#include"ds18b20.h"
void Delay_Ms(INT16U ms)
{
INT16U i;
do{
i = MAIN_Fosc; // 96000
while(--i); //96T per loop
}while(--ms); //
}
/*單總線初始化時(shí)序*/
bit ds_init()
{
bit i;
DS = 1;
_nop_();//
DS = 0;
Delay_us(75); //拉低總線75*6.5+11.95=499.45us 掛接在總線上的18B20將會(huì)全部被復(fù)位
DS = 1; //釋放總線
Delay_us(4); //4*6.5+11.95=37.95us 等待50.95us
i = DS;
Delay_us(20); //20*6.5+11.95=141.95us 讀取存在信號(hào)
DS = 1; //釋放總線
_nop_();//
return (i);
}
/*寫一個(gè)字節(jié)*/
void write_byte(uchar dat)
{
uchar i;
for(i=0;i<8;i++)
{
DS = 0;
_nop_();//產(chǎn)生些時(shí)序
DS = dat & 0x01;
Delay_us(10);//10*6.5+11.95=76.95us
DS = 1; //釋放總線準(zhǔn)備下一次數(shù)據(jù)寫入
_nop_();
dat >>= 1;
}
}
/*讀一個(gè)字節(jié)*/
uchar read_byte()
{
uchar i, j, dat;
for(i=0;i<8;i++)
{
DS = 0;
_nop_();//產(chǎn)生讀時(shí)序
DS = 1;
_nop_();//釋放總線
j = DS;
Delay_us(10);//6.5*10+11.95=76.95us
DS = 1;
_nop_();
dat = (j<<7)|(dat>>1);
}
return (dat);
}
/*us延時(shí)函數(shù),執(zhí)行一次US--所需6.5us.進(jìn)入和出去一次函數(shù)需要11.95us*/
void Delay_us(uchar us)
{
/*****************11us延時(shí)函數(shù)*************************/
while(us--);
}
/*12T 51單片機(jī)5微秒延時(shí)函數(shù)自適應(yīng)時(shí)鐘(11.0592M,12M,22.1184M*/
void Delay_5us()
{
#if MAIN_Fosc == 11059200
_nop_();
#elif MAIN_Fosc == 12000000
_nop_();
#elif MAIN_Fosc == 22118400
_nop_(); _nop_(); _nop_();
#endif
}
LCD1602.c文件
#include<lcd1602.h>
#include<reg52.h>
sbit RS = P3^5;
sbit RW = P3^6;
sbit EN = P3^4;
//#define uchar unsigned char
//#define uint unsigned int
//判斷液晶忙,如果忙則等待
/*void Read_Busy()
{
uchar busy;
P0=0xff; //p0置1
RS=0; //數(shù)據(jù),命令選擇端為0,表示數(shù)據(jù)
RW=1; //寫
do
{
EN=1;
busy=P0;
EN=0;
}
while(busy&0x80); //最高位為1,則為忙。
} */
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=112;y>0;y--);
}
//寫LCD1602命令一個(gè)字節(jié)
void Write_Cmd(uchar cmd)
{
RS = 0;
RW = 0;
P0 = cmd;
EN = 1;
EN = 0;
delay(5);
}
//寫一個(gè)字節(jié)數(shù)據(jù),一個(gè)字符uchar類型
void Write_Dat(uchar dat)
{
RS = 1;
RW = 0;
P0 = dat;
EN = 1;
EN = 0;
}
//lcd1602初始化
void LCD_init()
{
delay(15);
Write_Cmd(0x38);//第一步:顯示模式設(shè)置。設(shè)置16*2顯示 0011 100
delay(15);
Write_Cmd(0x38);//第一步:顯示模式設(shè)置。設(shè)置16*2顯示 0011 100
delay(15);
Write_Cmd(0x38);//第一步:顯示模式設(shè)置。設(shè)置16*2顯示 0011 100
delay(15);
Write_Cmd(0x38);//第一步:顯示模式設(shè)置。設(shè)置16*2顯示 0011 100
Write_Cmd(0x08);
//Write_Cmd(0x0f);//第二步:顯示開(kāi)/關(guān)光標(biāo)設(shè)置 0000 1 D C B D=1:開(kāi)顯示 C=1:顯示光標(biāo)反之。B=1:光標(biāo)閃爍B=0;光標(biāo)不閃爍
Write_Cmd(0x01);//第三步:清屏指令 ,以免之前殘留在LCD上的數(shù)據(jù)
Write_Cmd(0x06);//第四步:0000 01NS 。N=1;地址指針加1,光標(biāo)加1.地址指針移位命令,讀或?qū)懸粋(gè)字符后,地址指針加1,且光標(biāo)加1
Write_Cmd(0x0f);//顯示開(kāi)及光標(biāo)設(shè)置
}
//x:要顯示的橫坐標(biāo)取值0-40,y:要顯示的行坐標(biāo)取值0-1(0為第一行,1為第二行) *str:需要顯示的字符串
void LCD1602_Dis_Str(uchar x, uchar y, uchar *str)
{
if(y)
x |= 0x40;
x |= 0x80;
Write_Cmd(x);
while(*str != '\0')
{
Write_Dat(*str++);
}
}
//x:要顯示的橫坐標(biāo)取值0-40,y:要顯示的行坐標(biāo)取值0-1(0為第一行,1為第二行) dat:需要顯示的數(shù)據(jù)以ASCLL形式顯示
void LCD1602_Dis_OneChar(uchar x, uchar y,uchar dat)
{
if(y)
x |= 0x40;
x |= 0x80;
Write_Cmd(x);
Write_Dat(dat);
}
#ifndef _LCD_H_
#define _LCD_H_
LCD1602.h文件
#include"reg52."
#include"intrins.h"
#define uchar unsigned char
#define uint unsigned int
//uchar x,y,*str,dat,cmd;
void Read_Busy(); //判斷液晶忙?
void delay(uint z);
void Write_Cmd(uchar cmd); //寫入一字節(jié)指令
void Write_Dat(uchar dat); //寫入一字節(jié)數(shù)據(jù)
void LCD_init(); //lcd初始化
void LCD1602_Dis_Str(uchar x, uchar y, uchar *str); //顯示字符串
void LCD1602_Dis_OneChar(uchar x, uchar y,uchar dat); //顯示一個(gè)字符
#endif //定義結(jié)束
|
評(píng)分
-
查看全部評(píng)分
|