📄 ds1820.c
字号:
#include <avr/io.h>
#include <avr/wdt.h>
#include <stdio.h>
#include <avr/delay.h>
#include <avr/signal.h>
#include "MyDef.h"
#include "ds1820.h"
const uchar CRC_Code[256]={ //DS1820 CRC校验表
0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65,
157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220,
35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98,
190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255,
70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7,
219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154,
101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36,
248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185,
140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205,
17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80,
175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238,
50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115,
202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139,
87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22,
233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168,
116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53
};
uchar Init_DS1820(void) //DS1820初始化
{
uchar flg;
SET_1820_DATOUT;
CLR_1820_DAT;
delay_nus(500);
SET_1820_DATIN; //输入 释放
delay_nus(80);
if(CHECK_1820_DAT) //等待回复
flg = 0;
else
flg = 1; //0表示初始化成功
delay_nus(240); //回复的低电平在60到240US
SET_1820_DATOUT;
SET_1820_DAT; //回到初始DQ=1;
return flg;
}
//-------------- 写DS1820温度 --------------------
void write_DS1820(uchar dat) //写DS1820温度
{
uchar i;
SET_1820_DATOUT; //控制脚定义成输出
for(i=0;i<8;i++)
{
CLR_1820_DAT;
delay_nus(5);
if(dat&1) //写数据,从低位开始
{
SET_1820_DAT; // bit=1
}
else
{
CLR_1820_DAT; // bit=0
}
delay_nus(60); // wait for 60us ,total > 60us
SET_1820_DAT; //再次拉高
delay_nus(10); //写两个位之间的间隔
dat>>=1;
}
SET_1820_DAT;
}
//--------------- 读DS1820温度 -------------------
uchar read_DS1820(void) //读DS1820温度
{
uchar i, dat=0; // dat用于存储读到的数据
SET_1820_DATOUT; //第一次拉低,设置引脚为输出
for(i=0;i<8;i++)
{
dat>>=1;
CLR_1820_DAT;
delay_nus(5); //拉低5微秒
SET_1820_DATIN; //定义成输入,读入状态
delay_nus(5); //等DS1820响应
if(CHECK_1820_DAT) //读状态,放入dat中
{
dat |=0x80; //放到最高位,左移
}
delay_nus(80); //wait for 60~120us
SET_1820_DAT;
SET_1820_DATOUT; //再次定义成输出
}
return dat;
}
uchar DS1820CRCDETECT(void)
{
uchar i;
uchar rom64[8];
uchar crc_temp=0;
Init_DS1820(); //初始化,然后读出温度值
write_DS1820(0xCC); //发送ROM命令,不进行匹配
write_DS1820(0x4E); //发送功能命令,写配置寄存器
write_DS1820(0x02); // TH
write_DS1820(0x80); // TL
write_DS1820(0x7F); // Config :0x1F:9位, 0x3F:10位 ,0x5F:11位 ,0x7F:12位
// 所需时间: 93.75ms 187.75ms 375ms 750ms
Init_DS1820(); //初始化,然后读出温度值
write_DS1820(0x33); //发送ROM命令,读64-bit ROM 值
for(i=0;i<8;i++)
{
rom64[i]=read_DS1820();
}
crc_temp = CRC_Code[rom64[0]]; //算第一个CRC码
for(i=1;i<7;i++) //后面的CRC码:I = (当前CRC) EXOR (输入字)
{
crc_temp = CRC_Code[rom64[i]^crc_temp];
}
if(crc_temp == rom64[7])
{
#ifdef Debug
// printf("\nDS1820 ROM CRC SUCCESS");
#endif
return 1;
}
else
{
#ifdef Debug
// printf("\nDS1820 ROM CRC FAIL");
#endif
}
return 0;
}
float GetTemperature(void)
{
float temperature;
ulong temp;
uchar scr_pad[9];
uchar crc_temp=0;
uchar i=0;
Init_DS1820(); //初始化DS1820
write_DS1820(0xCC); //发送ROM命令,不进行匹配
write_DS1820(0x44); //启动DS1820进行转换
delay_nms(1000); //延时等转换完成
Init_DS1820(); //初始化,然后读出温度值
write_DS1820(0xCC); //发送ROM命令,不进行匹配
write_DS1820(0xBE); //发送功能命令,读出暂存寄存器中内容
for(i=0;i<9;i++)
{
scr_pad[i]=read_DS1820(); //读出9位scratchpad 的值
}
//----------下面校验读出的值是否正确---------------
crc_temp = CRC_Code[scr_pad[0]]; //选算第一个CRC码
for(i=1;i<8;i++)
{
crc_temp = CRC_Code[scr_pad[i]^crc_temp];
}
if( crc_temp==scr_pad[8] ) //如果结果正确则显示
{
if(scr_pad[1]&0x08)
{
scr_pad[1]=~scr_pad[1];
scr_pad[0]=~scr_pad[0];
SREG=SREG&(~(1<<SREG_C)); //清零 C 进位
scr_pad[0]++;
if(SREG&(1<<SREG_C)) //如果有进位,则高位加1
scr_pad[1]++;
}
temp = scr_pad[1];
temp = (temp << 8) + scr_pad[0];
temperature = temp*0.0625; //得到真实十进制温度值,因为DSDS1820
#ifdef Debug
// printf("\nCurrent Temperature: %5.1f Degrees",temperature);
#endif
}
else //结果不正确则提示错误
{
temperature = -100; // 用 -100表示 温度输出错误
#ifdef Debug
// printf("\nError Occured!!! Wrong Temperature");
#endif
}
return temperature;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -