DS18B20测温程序/读序列号STC-Y3系列+软串口发送 支持负温度测量+摄氏度/华氏度转换
#include "reg51.h"
#include "intrins.h"
#include "stdio.h"
sbit LED=P3^4; //LED端口
sbit DQ=P3^5; //18B20数据线
sbit txd=P3^1; //数据发送口
sbit key=P3^2; //摄氏度与华氏度选择位 (高电平摄氏度,低电平华氏度)
#define U8 unsigned char
#define U16 unsigned int
#define U32 unsigned long
U8 asciitemp;
U8 ds18b20_id; //DS18B20序列号
union N16 {
U8 c;
int i;
};
void delay_uart(){ //11.0592Mhz@9600Bps
U8 a,b;
for(b=3;b>0;b--)
for(a=94;a>0;a--);
}
void txd_data(U8 i){ //串口发字节
U8 j=1,k=8;
delay_uart();
txd=0;
while(k--){
delay_uart();
txd=(i&j)/j;
j<<=1;
}
delay_uart();
txd=1;
}
void send_text(U8 *text){ //发送字符串
for(;*text!=0;text++){ //遇到停止符0结束发送
txd_data(*text); //发送数据
}
}
void send_hex(U8 c,bit u){ //串口发16进制字节 参数1:待发字节 参数2:1大写0小写
U8 d,i;
for(i=0;i<2;i++){
d= i ? c&15 : c>>4;
txd_data((d >= 0 && d <=9?48:u?55:87)+d);
}
}
void delay15us() //@11.0592MHz
{
U8 i;
_nop_();
_nop_();
i = 38;
while (--i);
}
void delayx15us(U8 t){ //延时N个15us
while(--t) delay15us();
}
void delay1ms() //@11.0592MHz
{
U8 i, j;
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
void delayxms(U16 t){ //延时N个1ms
while(--t) delay1ms();
}
bit ds18b20_init(){ //DS18B20初始化 检测DS18B20是否接入 成功返回1失败返回0
bit dat=0;
DQ=1; //置高电平
_nop_();_nop_(); //延时4个NOP
_nop_();_nop_();
DQ=0; //置低电平
delayx15us(40); //延时600us 范围480~960us
DQ=1;
delayx15us(4);
dat=DQ;
delayx15us(48); //延时720us
return !dat;
}
U8 ds18b20_r8(){ //DS18B20读字节
U8 i,dat=0;
for(i=8;i>0;i--){
DQ=0;
dat>>=1;
_nop_();
DQ=1;
if(DQ) dat|=0x80;
delayx15us(4);
}
return dat;
}
void ds18b20_w8(U8 dat){ //DS18B20写字节
U8 i;
for (i=8; i>0; i--){
DQ = 0;
delay15us();
DQ= dat&1;
delayx15us(3);
DQ=1;
dat >>=1;
}
}
void ds18b20_rid(){ //DS18B20读ID(序列号)
U8 i;
ds18b20_init();
ds18b20_w8(0x33);
for(i=0;i<8;i++) {
ds18b20_id=ds18b20_r8();
}
}
U8 ds18b20_crc8(){ //DS18B20序列号CRC8校验 (返回0为正确)
U8 i,j,x,k=0;
for(x=0;x<8;x++){
j=ds18b20_id;
for(i=0;i<8;i++){
k= (k^j)&1 ? (k^0x18)>>1|0x80 : k>>1;
j >>=1;
}
}
return k;
}
float ds18b20_rt(){ //DS18B20读温度 失败返回-100
union N16 r;
if(!ds18b20_init()) return -100;
ds18b20_w8(0xCC); // 跳过读序号列号的操作
ds18b20_w8(0x44); // 启动温度转换
delayxms(10);
if(!ds18b20_init()) return -100;
ds18b20_w8(0xCC);
ds18b20_w8(0xBE);
r.c=ds18b20_r8(); //低位
r.c=ds18b20_r8(); //高位
return (float)(r.i*0.0625);
}
float c2f(float c){ //摄氏度转华氏度
return 1.8*c+32;
}
void ds18b20_sendid(){ //发送DS18B20序列号
U8 i;
send_text("DS18B20 ID:");
for(i=0;i<8;i++){
send_hex(ds18b20_id,1);
}
send_text("\r\n");
}
void main(){
float rt=0; //温度摄氏度
ds18b20_rid();
ds18b20_sendid();
if(ds18b20_crc8()){
send_text("DS18B20 CRC8 Error! \r\n");
while(1);
}
while(1){
rt=ds18b20_rt(); //查询DS18B20温度
if(rt == -100){ //返回-100表示未接入
send_text("Read DS18B20 Error! \r\n");
} else {
LED = !(rt>=30); //大于30摄氏度 LED点亮
if(key){
sprintf(asciitemp,"%7.4f °C\r\n",rt);
} else {
sprintf(asciitemp,"%7.4f °F\r\n",c2f(rt));
}
send_text(asciitemp); //从内存发送字符串
}
delayxms(100);
}
}
谢谢分享 楼上回答正解 222 发表于 2018-11-17 12:11
楼上回答正解
你这是发错了吧 谢谢分享
页:
[1]