#include \"reg51.h\"
#include \"intrins.h\"
#define uchar unsigned char
#define uint unsigned int
#define LCD_data P1 //定义液晶的数据口为P1口
sbit LCD_PSB=P0^0; //串并行
sbit LCD_RST=P0^1; //复位
sbit LCD_RS =P0^2; //指令和数据
sbit LCD_RW =P0^3; //写和读
sbit LCD_EN =P0^4; //使能端
sbit DQ =P0^5; //定义P2^7口为ds18b20的数据口
uint a,b,c,d,e,f,g,h,temp;
uchar
tmp[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,
0x45,0x46}; //数字0-9,A-F的ASCII码
void delay(uchar i) //ds18b20的延时程序
{
while(--i);
}
void resetds() {
DQ = 1; delay(1); DQ = 0; delay(250); DQ = 1; //DS18B20初始化
//不要也行。
//稍做延时
//拉低总线
//精确延时,维持480us-960us
//释放总线
delay(100); //延时足够长时间,确保DS18B20发出存在脉冲。
}
uchar re_one_byte() //读取一个字节的数据
{
uchar i = 0;
uchar dat = 0;
for(i=8;i>0;i--)
{
DQ = 1; _nop_();
DQ = 0; _nop_(); //读数据时,数据以字节的最低有效位先从总线移出
//总线拉低
dat >>= 1; //让从总线上读到的位数据,依次从高位移动到低位。
DQ = 1; //释放总线,此后DS18B20会控制总线,把数据传输到总线上
delay(1); //延时7us,此处参照推荐的读时序图,尽量把控制器采样时间放到读时序后的15us内的最后部分
if(DQ) //控制器进行采样
dat |= 0x80; //若总线为1,即DQ为1,就把dat的最高位置1;若为0,则不进行处理,保持为0
delay(10); //此延时不能少,确保读时序的长度60us。
}
return (dat);
}
void wr_one_byte(uchar dat)
{
uchar i = 0;
for(i=8;i>0;i--)
{
DQ = 0; //拉低总线
_nop_(); DQ = dat&0x01; 的15us内,
delay(10); DQ = 1; dat >>= 1;
delay(1);
}
}
//从字节的最低位开始传输
//指令dat的最低位赋予给总线,必须在拉低总线后//因为15us后DS18B20会对总线采样。
//必须让写时序持续至少60us
//释放总线
void get_number() //读取ds18b20的序列号
{
resetds();
wr_one_byte(0x33); a=re_one_byte(); b=re_one_byte();
c=re_one_byte();
d=re_one_byte();
e=re_one_byte();
f=re_one_byte();
g=re_one_byte();
h=re_one_byte();
}
//读ROM,读ds18b20的位序列号
//连续读取8个字节,从低位到高位依次读取
void delay2(uint z)
{
int i,j;
for(i=0;ifor(j=0;j<10;j++);}
void wr_cmd(uint cmd) {
LCD_RS=0; LCD_RW=1;
do
{
LCD_EN=1;
//写指令
delay2(1);
temp=P1;
LCD_EN=0;
}
while(temp&0x80); LCD_RW=0;
LCD_data=cmd;
delay2(1);
LCD_EN=1;
delay2(1);
LCD_EN=0;
}
void wr_data(uchar wdata)
//写数据
{
LCD_RS=0;
LCD_RW=1;
do
{
LCD_EN=1;
delay2(1);
temp=P1;
LCD_EN=0;
}
while(temp&0x80);
LCD_RS=1;
LCD_RW=0;
LCD_data=wdata;
delay2(1);
LCD_EN=1;
delay2(1);
LCD_EN=0;
}
void LCD_init() {
LCD_RST=0; delay2(1);
LCD_RST=1; LCD_PSB=1; wr_cmd(0x30);
//液晶初始化
//复位
//复位端置高
//选择并行模式
//使用基本指令集
delay2(1);
wr_cmd(0x0c); //开显示,游标OFF,游标位置OFF
delay2(1);
wr_cmd(0x01); delay2(10);
}
void disnumber()
{
wr_cmd(0x90); wr_data(tmp[(h&0xf0)>>4]); wr_data(tmp[(h&0x0f)]);
wr_data(tmp[(g&0xf0)>>4]);
wr_data(tmp[(g&0x0f)]);
//清除DDRAM
//在液晶的第二行显示数据
//显示ds18b20的位序列号
wr_data(tmp[(f&0xf0)>>4]);
wr_data(tmp[(f&0x0f)]);
wr_data(tmp[(e&0xf0)>>4]);
wr_data(tmp[(e&0x0f)]);
wr_data(tmp[(d&0xf0)>>4]);
wr_data(tmp[(d&0x0f)]);
wr_data(tmp[(c&0xf0)>>4]);
wr_data(tmp[(c&0x0f)]);
wr_data(tmp[(b&0xf0)>>4]);
wr_data(tmp[(b&0x0f)]);
wr_data(tmp[(a&0xf0)>>4]);
wr_data(tmp[(a&0x0f)]);
}
main()
{
LCD_init(); //液晶初始化
while(1)
{
get_number() ; disnumber(); }
}
//读取序列号
//显示序列号