📄 18b20.c
字号:
#include "reg52.h"
#include"intrins.h"
#define uch unsigned char //给unsigned char起别名 uch
#define NOP() _nop_ ()
bit read_flag=0;
sbit BEEP=P1^3;
sbit relay=P1^2;
sbit clk=P1^0;
sbit din=P1^1;
sbit DQ=P2^0;
unsigned char code ledcode[]={0x11,0x7D,0x23,0x29,0x4D, 0x89,0x81,0x3D,0x01,0x09,0x05,\
0xc1,0x8f,0x61,0x83,0x87}; //数码管段码
//实验目的:熟悉DS18B20的使用
//4位数码管显示温度结果,其中整数部分2位,小数部分2位
//每次按下RB0键后进行一次温度转换。
//硬件要求:把DS18B20插在18B20插座上
// 拨码开关S10第1位置ON,其他位置OFF
// 拨码开关S5、S6全部置ON,其他拨码开关全部置OFF
unsigned char TLV=0 ; //采集到的温度高8位
unsigned char THV=0; //采集到的温度低8位
unsigned char TZ=0; //转换后的温度值整数部分
unsigned char TX=0; //转换后的温度值小数部分
unsigned int wd; //转换后的温度值BCD码形式
unsigned char shi; //整数十位
unsigned char ge; //整数个位
unsigned char shifen; //十分位
unsigned char baifen; //百分位
unsigned char qianfen; //千分位
unsigned char wanfen; //万分位
//------------------------------------------------
//延时函数
void delay(char x,char y)
{
char z;
do{
z=y;
do{;}while(--z);
}while(--x);
}
//其指令时间为:7+(3*(Y-1)+7)*(X-1)如果再加上函数调用的call 指令、页面设定、传递参数花掉的7 个指令。
//则是:14+(3*(Y-1)+7)*(X-1)。
//--------------------------------------------------
//结果显示函数
//系统初始化函数
void leddisp(unsigned char num)
{
unsigned char i,k;
k=ledcode[num];
for(i=0;i<8;i++)
{
if((k&0x01)==0x01)
din=1;
else
din=0;
clk=0;
clk=1;
k>>=1;
}
}
//-----------------------------------------------
//复位DS18B20函数
void reset(void)
{
bit presence=1;
while(presence==1)
{
DQ=0 ; //主机拉至低电平
delay(2,70); //延时503us
DQ=1; //释放总线等电阻拉高总线,并保持15~60us
delay(2,7); //延时70us
if(DQ==1) presence=1; //没有接收到应答信号,继续复位
else presence=0; //接收到应答信号
//delay(2,60); //延时430us
delay(2,60);
}
BEEP=1;
}
//-----------------------------------------------
//写18b20写字节函数
void write_byte(uch val)
{
uch i;
uch temp;
for(i=8;i>0;i--)
{
temp=val&0x01; //最低位移出
DQ=0;
NOP();
NOP();
NOP();
NOP();
NOP(); //从高拉至低电平,产生写时间隙
if(temp==1) DQ=1; //如果写1,拉高电平
delay(2,7); //延时63us
DQ=1;
NOP();
NOP();
val=val>>1; //右移一位
}
}
//------------------------------------------------
//18b20读字节函数
uch read_byte(void)
{
uch i;
uch value=0; //读出温度
static bit j;
for(i=8;i>0;i--)
{
value>>=1;
DQ=0;
NOP();
NOP();
NOP();
NOP();
NOP();
NOP(); //6us
DQ=1; //拉至高电平
NOP();
NOP();
NOP();
NOP();
NOP(); //4us
j=DQ;
if(j) value|=0x80;
delay(2,7); //63us
}
return(value);
}
//-------------------------------------------------
//启动温度转换函数
void get_temp()
{
int i;
DQ=1;
reset(); //复位等待从机应答
write_byte(0XCC); //忽略ROM匹配
write_byte(0X44); //发送温度转化命令
for(i=50;i>0;i--)
{
// display(); //调用多次显示函数,确保温度转换完成所需要的时间
}
reset(); //再次复位,等待从机应答
write_byte(0XCC); //忽略ROM匹配
write_byte(0XBE); //发送读温度命令
TLV=read_byte(); //读出温度低8
THV=read_byte(); //读出温度高8位
DQ=1; //释放总线
TZ=(TLV>>4)|(THV<<4)&0X3f; //温度整数部分
TX=TLV<<4; //温度小数部分
if(TZ>100)TZ/100; //不显示百位
ge=TZ%10;//个位 //整数部分个位
shi=TZ/10;//十位 //整数十位
wd=0;
if (TX & 0x80) wd=wd+5000;
if (TX & 0x40) wd=wd+2500;
if (TX & 0x20) wd=wd+1250;
if (TX & 0x10) wd=wd+625; //以上4条指令把小数部分转换为BCD码形式
shifen=wd/1000; //十分位
baifen=(wd%1000)/100; //百分位
qianfen=(wd%100)/10; //千分位
wanfen=wd%10; //万分位
NOP();
NOP();
}
//--------------------------------------------------
//主函数
void main()
{
while(1)
{
get_temp(); //调用温度转换函数
leddisp(shi); //调用结果显示函数 ,温度十位
leddisp(ge); //温度个位
leddisp(shifen);//温度十分位
leddisp(baifen);//温度百分位
delay(200,200); //调用延时函数
delay(200,200);
delay(200,200);
delay(200,200);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -