📄 q.c
字号:
#include<reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
/*******************宏定义**************************************************/
#define TH0_value 0x3C
#define TL0_value 0xB0
#define TMOD_value 0x01
#define TCON_value 0x15
#define IE_value 0x82
#define P0_value 0x0ff
/*******************端口定义及开辟相应的存储单元***************************/
sbit DQ = P2^2; //DS18B20单总线接入点
bit flag ; //检测芯片是否存在的标志位
bit signal; //温度符号标志位
sbit b=P1^0; //芯片存在P1.0置0点亮LED灯
sbit c=P1^1; //芯片不存在P1.1置0点亮LED灯
unsigned char code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf};
//8段数码管0~9数字的共阴显示代码
uchar buf[3] ; //存储转换后温度的高8位与低8位
uchar buf1[3];
uchar temper_value; //存储转化后温度的结果值
/***************************************************************************
* 函数名: 延时子函数delay
* 函数功能:延时
* 入口参数:i
* 出口参数:无
***************************************************************************/
void delay(uchar i)
{
while(--i);
}
/***************************************************************************
* 函数名: 初始化子函数 reset_signal
* 函数功能:信号复位进行初始化
* 入口参数:无
* 出口参数:无
***************************************************************************/
reset_signal()
{
DQ = 1;
_nop_();
DQ = 0; //主机发送复位脉冲至少持续480uS
delay(250); //480uS~960uS之间
DQ = 1;
delay(20); //延时至少16uS
flag = DQ; //DS18B20 等待16uS后发送存在脉冲(低电平)持续60uS~240uS
if(flag==0) //若flag=0则表示存在
{
delay(90); //延时60uS~240uS之间
}
DQ = 1;
}
/*******************************************************************************
* 函数名: 写命令子函数 w_order
* 函数功能:写入将要执行操作的命令
* 入口参数:cmd
* 出口参数:无
******************************************************************************/
void w_order(unsigned char cmd)
{
uchar i;
for(i=0;i<8;i++)
{
if(cmd&(0x01<<i)) //写1
{
DQ = 0; //主机将数据线拉至低电平产生写时间片
_nop_(); //最好是拉至低电平后就释放(但延时至少1uS以上),这样才能在15uS内恢复到高电平
_nop_(); //15uS内必须拉至高电平(因为DS18B20在15uS~60uS之间对数据线进行采样)
DQ = 1;
delay(28); //延时60uS(因为一个写周期至少延时60uS)
}
else //写0
{
DQ = 0; //主机将数据线拉至低电平产生写时间片
delay(40); //延时60uS以上(因为一个写周期至少延时60uS)
DQ = 1;
_nop_(); //恢复延时(因为个写周期之间至少有1uS的恢复时间)
_nop_();
_nop_();
_nop_();
}
}
}
/******************************************************************************
* 函数名: 读数据子函数 r_data
* 函数功能:读出转换后的温度结果存入 buf 1中
* 入口参数:无
* 出口参数:无
*******************************************************************************/
void r_data()
{
uint i,j;
for(j=0;j<2;j++)
{
buf[j] = 0;
for(i=0;i<8;i++)
{
DQ = 1;
_nop_();
DQ = 0; //主机将数据线拉至低电平产生读时间片
_nop_(); //最好是拉至低电平后就释放(但延时至少1uS以上),这样才能在15uS内恢复到高电平
_nop_(); //15uS内必须驱动至高电平(因为DS18B20输出数据在读时间片下降沿后15uS有效)
DQ = 1;
_nop_();
if(DQ) //提高总线后马上读取
{
buf[j]|=(1<<i);
}
else
{
buf[j]&=~(1<<i);
}
delay(28); //每个读周期至少持续60uS
DQ = 1;
_nop_(); //恢复延时(因为个读周期之间至少有1uS的恢复时间)
}
}
}
/****************************************************************************
* 函数名: 获取温度子函数 get_temper_value
* 函数功能:获得当前的温度值
* 入口参数:无
* 出口参数:无
****************************************************************************/
void get_temper_value()
{
DQ = 1;
reset_signal(); //初始化 ,检测是否存在 DS18B20
if(flag==0)
{
w_order(0xcc); //跳过ROM
w_order(0x44); //启动温度变换
reset_signal(); //复位
w_order(0xcc); //跳过ROM
w_order(0xbe); //准备读暂存器
r_data(); //读暂存器中温度变化的结果
}
}
/***************************************************************************
* 函数名: 二-十进制转换子函数Conversion
* 函数功能:将二进制数转入十进制中
* 入口参数:无
* 出口参数:无
***************************************************************************/
void Conversion()
{
signal = (buf[1]&0xf8); //检温度测是正还是负
buf1[2] = 0; //温度的符号位
if(signal)
{
buf[0]=~buf[0];
buf[1]=~buf[1];
buf1[2]=10;
}
buf[0]=(buf[0]>>4); //将温度转换结果的低8位的高4位移入低4位
//这里我们抛弃了温度转换结果的第四位(小数部分,因为我们不需要那么准确)
buf[0]=(buf[0]&0x0f); //保留低4位并存入buf[0]中
buf[1]=(buf[1]<<4); //将温度转换结果的高8位的低4位移入高4位
buf[1]=(buf[1]&0xf0); //保留高4位并存入buf[1]中
temper_value=(buf[0]|buf[1]); //将buf[0]与buf[1]相或得温度转换结果存入temper_value中
if(signal)
{temper_value++;} //为负时取反加1
buf1[0]=temper_value%10; //将个位保存在buf1[0]中
buf1[1]=temper_value/10; //将十位保存在buf1[1]中
}
/*******************************************************************************
* 函数名: LED显示子函数display
* 函数功能:将获得的温度结果通过LED显示
* 入口参数:无
* 出口参数:无
*****************************************************************************/
void display()
{
uchar i,a;
long int j;
for(i=0;i<3;i++)
{
P2=~(0x10<<i); //动态扫描显示
a =buf1[i];
P0=~tab[a]; //P0口输出显示数据
for(j=400;j>0;j--);
}
}
/******************************************************************************
* 函数名: 中断函数timer0
* 函数功能:定时对DS18B20的转换温度进行更新
* 入口参数:无
* 出口参数:无
******************************************************************************/
void timer0(void) interrupt 1 using 0
{
TH0 =TH0_value;
TL0 =TL0_value;
get_temper_value();
Conversion();
}
/******************************************************************************
* 函数名: 主函数main
* 函数功能:通过温度传感器测当前室温
* 入口参数:无
* 出口参数:无
*****************************************************************************/
void main()
{
TMOD=TMOD_value;
TH0 =TH0_value;
TL0 =TL0_value;
TCON=TCON_value;
IE =IE_value ;
P0 =P0_value;
while(1)
{
display(); //将当前温度值送入LED显示
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -