📄 ds18b20.c
字号:
#include <stdio.h>
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
typedef unsigned char byte;
typedef unsigned int word;
uchar temp1;
uint temp;
uchar flag=0;
sbit RS=P1^5; //液晶端口定义
sbit RW=P1^6;
sbit E=P1^7;
char position=3;
sbit DQ=P1^0;
sbit clk1302 =P1^1;
sbit data1302 =P1^2;
sbit cs1302 =P1^3;
sbit key =P1^4;
uchar set_time[7]={0x06,0x02,0x11,0x18,0x12,0x02,0x07};
uchar Year,Month,Day,hour,minutes,seconds,xingqi,wendu;
uchar to_count=0; // 中断调用显示变量
uchar re_flag=0; //刷新显示标志位
uchar code table1[]={"今天是星期 "};
uchar code table2[]={"温度是 "};
uchar code table5[]={"0123456789 "}; //半字符数字码表
uchar code table6[]={"20年月日时分秒:"};
//=============================================================
//函数名称: void delay(unint k)
//函数功能:延时K*1ms,12.000MHZ
//日期:2007.11.20
//=============================================================
void delay(uint k)
{
uint i,j;
for(i=0;i<k;i++)
{
for(j=0;j<60;j++)
{;}
}
}
//延时
void delay2(word useconds)
{
for(;useconds>0;useconds--);
}
//=============================================================
//函数名称: void busycheck()
//函数功能:忙状态检查
//日期:2007.11.20
//=============================================================
void busycheck()
{
uchar i;
RS=0;
RW=1;
E=1; //忙检查的时候 这句必须放在这里
P0=0xff;
while(P0&0x80);
i=6;
while(i--);
//E=1 不可以放在这里 否册没有显示
E=0;
}
//=============================================================
//函数名称: void sendbyte(uchar byte)
//函数功能:送数据给LCD 显示
//日期:2007.11.20
//=============================================================
void sendbyte(uchar byte)
{
uchar i;
busycheck();
RS=1; // 不可以弄错
RW=0; //错了没有显示 必须是 RS=1 RW=0
P0=byte;
i=7;
while(i--);
E=1;
E=0;
}
//=============================================================
//函数名称: void sendorder(uchar order)
//函数功能:送命令给LCD实行
//日期:2007.11.20
//=============================================================
void sendorder(uchar order)
{
uchar i;
busycheck(); //写命令前要先检测忙状态
RS = 0;
RW = 0;
P0=order; //写如命令
i=7; // 其实不用延迟也可以显示
while(i--); //但是夜晶刷新太快了 不好
E=1;
E=0;
}
//--------------------------------------------------
void step12864(uchar order,uchar *p)
{
uchar i=0;
sendorder(order);
for(i=0;i<2;i++)
{
sendbyte(*p);
p++;
}
}
//=============================================================
//函数名称: void init12864()
//函数功能:初始化12864
//日期:2007.11.20
//=============================================================
void init12864()
{
uchar i;
sendorder(0x30); // 8位数据 基本指令功能 0xof 是反白允许
sendorder(0x0c); // 显示开 游标关 游标位置 0x0c 是反白不允许
sendorder(0x01); // 清屏
delay(50);
sendorder(0x80); //第1行初始化
for(i=0;i<20;i++)
{
sendbyte(table1[i]);
}
sendorder(0x90); //第2行初始化
for(i=0;i<12;i++)
{
sendbyte(table2[i]);
}
step12864(0x88,&table6[0]); // 显示20
step12864(0x8a,&table6[2]); // 显示年
step12864(0x8c,&table6[4]); // 显示月
step12864(0x8e,&table6[6]); // 显示日
step12864(0x99,&table6[8]); // 显示时
step12864(0x9b,&table6[10]);// 显示分
step12864(0x9d,&table6[12]);// 显示秒
}
//=====================================================
//函数名称:void display(uint value)
//函数功能:显示4位半字符数据驱动,数字前面补空格,调用前先送液晶地址
//日期:2007.11.20
//=====================================================
void display(uint value)
{
if(value<100) //判断是否要前面补空格
{
//sendbyte(table5[10]);
goto send2;
}
if(value<1000)
{
sendbyte(table5[10]);
goto send1;
}
sendbyte(table5[value/1000]);
send1:
sendbyte(table5[value%1000/100]);
send2:
sendbyte(table5[value%100/10]);
sendbyte(table5[value%10]);
}
//=====================================================
//函数名称:void write1302(uchar order,uchar byte)
//函数功能:写数据给1302 先送地址后送数据 两次都是上升沿送出数据
//日期:2007.11.20
//=====================================================
void write1302(uchar order,uchar byte)
{ uchar i;
if(order==0x8c)
{byte=byte+1;
set_time[6]=byte;}
/* {
if(key==0)
{ delay(10);
if(key==0)
byte=byte+1;
set_time[6]=byte;
}
}*/
cs1302 =0;
clk1302 =0;
cs1302 =1;
for(i=0;i<8;i++) //写入地址
{
clk1302=0;
data1302=order&0x01;
clk1302=1;
order=order>>1;
}
for(i=0;i<8;i++) //对相应的地址写入数据
{
clk1302=0;
data1302=byte&0x01;
clk1302=1;
byte=byte>>1;
}
clk1302 =0;
cs1302 =0;
}
//=====================================================
//函数名称:uchar read1302(uchar address)
//函数功能:从1302 读出数据 先送地址 (上升沿有效)
// 读出数据是下降沿读出数据 函数有返回值
//日期:2007.11.20
//=====================================================
uchar read1302(uchar address)
{
uchar i,shuju,shiwei;
cs1302 =0;
clk1302 =0;
cs1302 =1;
for(i=0;i<8;i++) //写入地址命令
{
clk1302=0;
data1302=address&0x01;
clk1302=1;
address=address>>1;
}
shuju=0;
for(i=0;i<8;i++) //读出当前地址的内容
{
shuju=shuju>>1;
clk1302=0;
if(data1302==1)
shuju=shuju|0x80;
clk1302=1;
}
clk1302=0;
cs1302=0;
shiwei=shuju/16; //数据整合 因为1302的高4为
shuju=shuju%16; //默认放的十位
shuju=shiwei*10+shuju;
return shuju ;
}
//=====================================================
//函数名称: init1302()
//函数功能:初始化1302 使其正常工作
//日期:2007.11.20
//=====================================================
void init1302()
{
uchar n;
uchar address=0x80;
cs1302 = 0;
clk1302 = 0;
write1302(0x8e,0x00); //允许写入数据
write1302(0x90,0x00); //禁止涡流充电
for(n=0;n<7;n++)
{
write1302(address,set_time[n]);
address=address+2;
}
write1302(0x8e,0x80); //写保护,不允许读写
}
///温度测量
/*******************************************
************** DS18B20温度测量************/
//复位
byte ow_reset(void)
{
byte presence;
DQ = 0; //pull DQ line low
delay2(29); // leave it low for 480us
DQ = 1; // allow line to return high
delay2(3); // wait for presence
presence = DQ; // get presence signal
delay2(25); // wait for end of timeslot
return(presence); // presence signal returned
} // 0=presence 1 = no part
//从 1-wire 总线上读取一个字节
byte read_byte(void)
{
byte i;
byte value = 0;
for (i=8;i>0;i--)
{
value>>=1;
DQ = 0; // pull DQ low to start timeslot
DQ = 1; // then return high
delay2(1); //for (i=0; i<3; i++);
if(DQ)value|=0x80;
delay(6); // wait for rest of timeslot
}
return(value);
}
//向 1-WIRE 总线上写一个字节
void write_byte(char val)
{
byte i;
for (i=8; i>0; i--) // writes byte one bit at a time
{
DQ = 0; // pull DQ low to start timeslot
DQ = val&0x01;
delay2(5); // hold value for remainder of timeslot
DQ = 1;
val=val/2;
}
delay(5);
}
//读取温度
char Read_Temperature(void)
{
union{
byte c[2];
int x;
}temp;
ow_reset();
write_byte(0xCC); // Skip ROM
write_byte(0xBE); // Read Scratch Pad
temp.c[1]=read_byte();
temp.c[0]=read_byte();
ow_reset();
write_byte(0xCC); //Skip ROM
write_byte(0x44); // Start Conversion
return temp.x/2;
}
//=====================================================
//函数名称: void main()
//函数功能:主函数 main()
//日期:2007.11.20
//=====================================================
void main()
{
/* TMOD =0X01; //不宜采用中断显示
TH0=(65536-50000)/256; // 因为经过实验证明
TL0=(65536-50000)%256; // 显示秒的时候 有时
ET0=1; // 候快有时候慢 不合乎
EA=1; //常态显示
TR0=1; */
init12864();
init1302();
/// Init_DS18B20();
while(1)
{
if(key==0)
{ delay(100);
if(key==0)
{flag++;}
}
wendu=Read_Temperature() ;
Year=read1302(0x8d);
Month=read1302(0x89);
xingqi=read1302(0x8b);
Day =read1302(0x87);
hour=read1302(0x85);
minutes=read1302(0x83);
seconds=read1302(0x81);
//if(re_flag==1)
// {
re_flag=0;
sendorder(0x89);
display(Year);
sendorder(0x8b);
display(Month);
sendorder(0x85);
display(xingqi);
sendorder(0x8d);
display(Day);
sendorder(0x98);
display(hour);
sendorder(0x9a);
display(minutes);
sendorder(0x9c);
display(seconds);
sendorder(0x93);
display(wendu);
// }
}
}
//------------------------------------------
/*void t0() interrupt 1
{ unsigned char i;
i++;
if(i==20)
{i=0;
seconds++;
if(seconds==60)
{seconds=0;minutes++;}
if(minutes==60)
{minutes=0;hour++;}
if(hour==24)
{hour=0;Day++;}
if(Day==32)
{Day=1;Month++;}
if(Month==13)
{Month=1; Year++;}
}
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
}*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -