📄 复件 (2) db18b20.c
字号:
/* MCU:89C4051 P1.0,P1.1接10K左右上拉电阻,晶振11.0592M
/* sbit DQ=P3^7; 89C4051的11脚接DS18B20 */
#include <reg52.h>
#include <stdio.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define _Nop() _nop_();
#define Disdata P1 //段码输出口
#define Discan P3 //扫描口
uint h;
uint temp;
sbit DQ=P3^7;
sbit DIN=P1^7;
uchar code dis_7[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};
////*共阳LED段码表 0 1 2 3 4 5 6 7 8 9 不亮 - */
uchar code scan_con[4]={0xfe,0xfd,0xfb,0xf7}; //列扫描控制字
uchar data temp_data[2]={0x00,0x00}; //读出温度暂放
uchar display[5]={0x08,0x08,0x08,0x0b,0x00};//显示单元数据,共4个数据,一个运算暂存用
/***************11us延时函数******************/
//--------------------------------------------------------------------------------------------------
// 函数名称: delay
// 入口参数: N
// 函数功能:延时子程序,实现(16*N+24)us的延时
// 系统采用11.0592MHz的时钟时,延时满足要求,其它情况需要改动
//--------------------------------------------------------------------------------------------------
void delay(uint t)
{
int i;
for(i=0;i<t;i++);
}
/******************显示扫描函数******************/
scan()
{
char k;
for(k=0;k<4;k++) //4位LED扫描控制
{
Disdata=dis_7[display[k]];
if(k==1) {DIN=0;}
Discan=scan_con[k];delay(120);Discan=0xff;
}
}
/*************DS18B20复位函数*****************/
uchar ow_reset(void)
{
uchar deceive_ready;
DQ=0; //拉低DQ线
delay(35); //延时至少480us~960us(471uS)
DQ=1; //将DQ线设置位逻辑高
delay(3); //延时等待deceive_ready响应 (54uS)
deceive_ready=DQ; //采样deceive_ready信号
delay(25); //等待时序结束 (340uS)
return(deceive_ready); //有deceive_ready信号时返回0,否则返回1
}
/************DS18B20写命令函数******************/
//--------------------------------------------------------------------------------------------------
// 函数名称: write_bit
// 入口参数: bitval
// 函数功能:写一个bit子程序
//--------------------------------------------------------------------------------------------------
void write_bit(unsigned char bitval)
{
DQ=0; //拉低DQ线开始时序
if(bitval==1)
DQ=1; //如果写逻辑为高
delay(5); //延时 (80uS)
DQ=1; //升高DQ线
}
//向1-WIRE总线上写1个字节
void write_byte(uchar val)
{
uchar i,temp;
for(i=0;i<8;i++)
{
temp=val>>i; //将val位右移i位赋值给比temp
temp=temp&0x01; //取temp最低位
write_bit(temp);
delay(5); //延时至时序结束 (80uS)
}
}
/************DS18B20读命令函数******************/
//--------------------------------------------------------------------------------------------------
// 函数名称:read_bit
// 入口参数: 无
// 返回接收的数据
// 函数功能:读一个bit子程序
//--------------------------------------------------------------------------------------------------
unsigned char read_bit(void)
{
unsigned char i;
DQ=0; //拉低DQ线开始时序
DQ=1; //升高DQ线
for(i=0;i<3;i++); //延时至时序开始15us
return(DQ); //返回DQ值
}
//--------------------------------------------------------------------------------------------------
// 函数名称: read_byte
// 返回接收的数据 value
// 函数功能:读一个byte子程序
//--------------------------------------------------------------------------------------------------
unsigned char read_byte(void)
{unsigned char i,m,receive_data;
m=1;receive_data=0; //初始化
for(i=0;i<8;i++)
{
if(read_bit())
{
receive_data=receive_data+(m<<i);
} //每读一位数据据,左移一位
delay(6); //延时至时序结束 (93uS)
}
return(receive_data); //返回value
}
/*******************读出温度函数******************/
read_temp()
{
uchar n=0;
uchar z,jssyz,mdjsz;
ow_reset(); //总线复位
write_byte(0xCC); //发出跳过ROM命令
write_byte(0xBE); //发读命令
temp_data[0]=read_byte(); //温度低8位
temp_data[1]=read_byte(); //温度高8位
z=read_byte(); //TH
z=read_byte(); //TL
z=read_byte(); //18B20保留
z=read_byte(); //18B20保留
jssyz=read_byte();//计数剩余值
mdjsz=read_byte();//每度计数值
ow_reset(); //总线复位 */
write_byte(0xCC); //发出跳过ROM命令
write_byte(0x44); //发转换命令
if(temp_data[1]>127)
{temp_data[1]=(~temp_data[1]);temp_data[0]=((~temp_data[0])|0x01);n=1;}
//temp_data[0]=0x91; temp_data[1]=0x01; */
//temp=temp_data[0]&0x0f; //作为暂存
//display[0]=ditab[temp]; //小数部分查表法
//temp=((temp_data[0]>>4)|((temp_data[1]&0x07)<<4));
//x=(temp.c[1]*256+temp.c[0])*6.25; //扩大10倍
//T实际=(T整数-0.25℃)+(M每度-M剩余)/M每度
temp=(temp_data[0]>>4)|((temp_data[1]&0x07)<<4);
temp=temp*100-25; //扩大100倍
z=((mdjsz-jssyz)*100)/mdjsz;
temp=(temp+z)/100;
display[3]=temp/100; //百位
display[2]=temp%100/10; //十位
display[1]=temp%10; //个位
temp=(temp_data[0]&0x0f)*625;
display[0]=temp/1000; //小数
if(n) //温度为负数
{
if(!display[2]) //十位为0
{
display[3]=0x0a; //百位不显示
display[2]=0x0b; // 十位显示负号
}
else
display[3]=0x0b; //否则百位上显负号
}
else //温度为正数
{
if(!display[3]) //百位为0
{
display[3]=0x0a; //dis_7[display[3]]=dis_7[10]=0xFF,为不显示
if(!display[2]) //十位为0
{
display[2]=0x0a; //十位不显示
}
}
}
}
/**************************************/
/* 主函数 */
/**************************************/
main()
{
Disdata=0xff;
Discan=0xff;
ow_reset(); //开机复位
write_byte(0xCC); //跳过ROM
write_byte(0x44); //发出转换命令
for(h=0;h<150;h++) //开机显示2秒的“8888”
{
scan();
}
while(1)
{
read_temp(); //读出DS18B20温度数据
scan(); //调用显示子程序
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -