DS18B20的温度值显示程序设计
一.DS1820 单线数字温度计特性
• 独特的单线接口仅需一个端口引脚进行通讯
• 简单的多点分布应用
• 无需外部器件
• 可通过数据线供电
• 零待机功耗
• 测温范围-55~+125℃,以 0.5℃递增。华氏器件-67~+2570F,以 0.90F 递增
• 温度以 9 位数字量读出
• 温度数字量转换时间 200ms(典型值)
• 用户可定义的非易失性温度报警设置
• 报警搜索命令识别并标志超过程序限定温度(温度报警条件)的器件
• 应用包括温度控制、工业系统、消费品、温度计或任何热感测系统
二. ROM 操作指令
Read ROM(读 ROM) [33H]
Match ROM(匹配 ROM) [55H]
Skip ROM(跳过 ROM] [CCH]
Search ROM(搜索 ROM) [F0H]
Alarm search(告警搜索) [ECH]
三. 存储器操作命令
Write Scratchpad(写暂存存储器) [4EH]
Read Scratchpad(读暂存存储器) [BEH]
Copy Scratchpad(复制暂存存储器) [48H]
Convert Temperature(温度变换) [44H]
Recall EPROM(重新调出) [B8H]
Read Power supply(读电源) [B4H]
话不多说,直接上代码。
1.初始化子函数
主机将数据线DQ拉低480us后释放总线,延时15 ~ 60 us 后的60 ~ 240 us时间内检测DQ是否为低电平,再延时240us 保证起始时序的完整。
bit init_ds18b20(void)
{
bit initflag = 0;
DQ = 1; //主机拉低总线
Delay_OneWire(12);
DQ = 0; //主机释放总线
Delay_OneWire(80); // 延时大于480us
DQ = 1;
Delay_OneWire(10); // 14
initflag = DQ; // initflag等于1初始化失败
Delay_OneWire(5); //适当延时保证时序完整
return initflag;
}
2.通过单总线向DS18B20写一个字节
注意 :传输数据低位在前面
写周期开始的时候,主机先把总线拉低大于1us表示写周期的开始。
若主机写0,则继续拉低电平最少60us直到写周期结束,然后释放总线为高电平
若主机写1,在拉低总线电平1us后,释放总线为高电平,直到写周期结束。
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ = 0; //主机拉低总线开始写
DQ = dat&0x01; //数据传输 低位在前 去最低置兼延时
Delay_OneWire(5); //使从机有时间去取到该位置
DQ = 1; //送完当前位后释放总线
dat >>= 1; // 为送入下一位做准备
//注意:左移还是右移,先移还是后移
}
Delay_OneWire(5);
}
3.从DS18B20读取一个字节
读周期开始的时候,主机先把总线拉低大于1us,然后释放总线。主机释放总线后:
若主机发送0,则继续拉低总线并保持至少从读周期开始15us,然后释放总线为高电平。
若主机发送1,则在主机释放总线后不拉低总线,为高电平。
主机必须在读周期开始的15us内检测总线电平的高低
unsigned char Read_DS18B20(void) //调用返回读取的字节
{
unsigned char i; //能用局部变量就不用全局变量
unsigned char dat;
// unsigned char index = 0;
for(i=0;i<8;i++) //每次读一位
{
DQ = 0; //主机拉低总线至少一微秒开始读当前位
dat >>= 1; //位移兼延时,第一次右移位 无作用
DQ = 1; //主机释放总线
Delay_us(); //延时 使得从机得到响应
if(DQ) //如果检测到了1 或写成(DQ==1)
{
dat |= 0x80; //将 dat 置于最高位 1000 1000
}
Delay_OneWire(5); //适当延时,度周期至少60US
}
return dat; //将接收好的字节反送给调用处
}
4.DS18B20温度采集程序
unsigned char rd_temperature(void)
{
char temp,flag,xiaoshu1,xiaoshu2;
int low,high;
init_ds18b20();
Write_DS18B20(0xcc); //跳过写rom指令
Write_DS18B20(0x44); //启动温度转换
Delay_OneWire(50);
init_ds18b20();
Write_DS18B20(0xcc); //跳过写rom指令
Write_DS18B20(0xbe); //启动温度转换 转换期间必须10us(最多) 给单总线强上拉
Delay_OneWire(50);
low=Read_DS18B20(); //传输过程中 先是低八位传输 后是 高八位传输
high=Read_DS18B20();
temp=low/16+high*16 ; //温度组装成为字节
//相当于 temp=(low>>4)|(high<<4) ;低字节右移四位 高字节左移
if(temp>=127) //符号位是1,则结果是负 此处判断标志位
{
flag = 1; //若符号位是1,则 温度为负数
temp = ~temp+1; //补码转换为原码
}
xiaoshu1 = (low&0x0f)*10/16; //取出温度第一位小数
xiaoshu2 = (low&0x0f)*100/16%10; //取出温度第二位小数
//另外一种写法
/*
xiaoshu1 = (low&0x0f)*625/1000;
xiaoshu2 = (low&0x0f)*625/100%10;
*/
return temp;
}
/CCH 跳过rom指令 则 1100 1100 则写入的时候 0011 0011
//BEH 写的时候低位前,高位后 1011 1110 则送进寄存器的段码是0111 1101
// 8421 a 10 1010 b 11 1011 c 12 1100 d 13 1101 e 14 1110 f 15 1111
5.延时子函数
void Delay_OneWire(unsigned int t)
{
unsigned char i;
while(t--){
for(i=0;i<12;i++);
}
}
void Delay_us(void)
{
unsigned char i;
i = 30;
while (--i);
}
希望可以对你有所帮助。