📄 ds1820.c
字号:
//文件名:DS18B20.c
#define uchar unsigned char
#define uint unsigned int
#define XF_MCU 1 //定义用哪一种单片机,1时,用于PIC; 0时,用于MSP430;
#if XF_MCU==0
#include <msp430x14x.h>
#include "DS1820.h"
#else
#include <pic.h>
#include "DS1820.h"
uchar pa_out;
uchar pb_out;
uchar pc_out;
uchar pd_out;
uchar pe_out;
#endif
const unsigned char digit[10] = {'0','1','2','3','4','5','6','7',
'8','9'};
unsigned char temp_display [9] = {'x','0','0','0','.','0','0','0','\0'};
//定义
unsigned char Error = 0;
float Temper=0.0; //真正有效温度值
int temperature=0; //读取两字节温度数据
unsigned char symbol = 1 ; //温度正负符号
//----------------------------------
//功能:us 级别延时
// n=10,则延时10*5+6=56uS
//----------------------------------
void DelayNus(unsigned int n)
{
while(n--){};
}
//-----------------------------------
//功能:写18B20
//-----------------------------------
void Write_18B20(unsigned char n)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ0;
_NOP();_NOP(); //延时5us
_NOP();_NOP();_NOP();
if((n&0X01)==0X01) //DQ=1
DQ1;
else
DQ0; //DQ=0
n=n>>1; //下一位
DelayNus(6); //延时50us 以上
DQ1;
}
}
//------------------------------------
//功能:读取18B20
//------------------------------------
unsigned char Read_18B20(void)
{
unsigned char i;
unsigned char temp;
for(i=0;i<8;i++)
{
temp=temp>>1; //移向下一位
DQ0;
_NOP(); //延时1us
DQ1;
_NOP();_NOP(); //延时5us
_NOP();
DQIO_IN; //DQ口设为输入
if((DS_IN&DS_IT)==0) //DQ是否等于0
{
temp=temp&0x7F; //读入DQ为0
}
else
{
temp=temp|0x80; //读入DQ为1
}
DelayNus(5); //延时40us
DQIO_OUT; //DQ口设为输出
DQ1; //DQ输出1
}
return temp; //返回一个数据
}
//-----------------------------------
//复位说明:复位要求主CPU将数据线下拉500us,然后释放,
//当DS18B20收到信号后等待16~60us左右,后发出60~240微秒的存在低脉冲,
//主CPU收到此信号表示复位成功。
//初始化DS18B20
void Init (void)
{
DQ0;
DelayNus(50); //延时500us
DQ1;
DelayNus(12); //延时16~60us
DQIO_IN; //设DQ为输入
if((DS_IN&DS_IT)==DS_IT) //1000 0000b=1f,DQ是否为1
{
Error =1; //失败1
DQIO_OUT; //设DQ为输输出
}
else
{
Error = 0; //初始化成功
DQIO_OUT; //设DQ为输输出
DQ1;
}
}
//----------------------------------
//指令描述:跳过ROM命令,指定代码为CCH,忽略64位ROM地址,直接向DS1820发温度变换
//命令,适用于单片机工作.
void Skip(void)
{
Write_18B20(0xcc);
}
//----------------------------------
//指令描述:温度转换命令,指定代码为44H.启动DS1820进行温度转换,12位转换时最长
//为750ms(9位为93.75ms).结果存入内部9字节RAM中.
void Convert (void)
{
Write_18B20(0x44);
}
//----------------------------------
//指令描述:读暂存器,指定代码为BEH.读内部RAM中9字节的内容.
void ReadDo (void)
{
Write_18B20(0xbe);
}
//----------------------------------
//读取温度值
void ReadTemp (void)
{
char temp_low, temp_high; //温度值
temp_low = Read_18B20(); //读低位
temp_high = Read_18B20(); //读高位
if((temp_high|positive)==positive)
symbol=1; //测到的温度为正
else
symbol=0; //测到的温度为负
temperature=(temp_high&0x0f);//屏蔽高4位
temperature<<=8; //将temp_high部分数据移到temperature高8位
temperature|=temp_low; //将高低两字节内部合并成一个16位数据
if(symbol==0) //是否为负温度
{ temperature = (~temperature)+1; //将其取反后加1
}
Temper=temperature*0.0625; //计算真实温度值
}
//----------------------------------
//MCU对DS18B20进行温度转换时,其操作必须满足以下过程:
// 1- 每一次读写之前都要对DS18B20进行复位.
// 2- 完成复位后发送一条ROM命令到DS18B20.
// 3- 最后发送一条RAM命令到DS18B20.
// 以上系列动作是根据DS18B20的通讯协议所得.
//读取温度
void GetTemp(void)
{
Init(); //DS1820初始化
Skip(); //跳过64位ROM(ROM命令)
Convert(); //转换(RAM命令)
DelayNus(60000); //60000x5us=0.3s
DelayNus(60000); //0.3s
DelayNus(60000); //0.3s
Init(); //DS1820初始化
Skip(); //跳过64位ROM
ReadDo(); //读暂存器
ReadTemp(); //读取温度值
}
//END--------------------------------------------------------------
//另外,由于MSP430F14与44的DCO时钟有所不同,各位如要引用DS18B20程序时请加于注意操作时序。
//引用时可能出现过复位不成功或读到全为FF...
//这些大部分都是由于程序上的时序不能满足DS18B20所至。
//以下关于14与4系列的DCO默认时钟:
//4系列默认时钟 ACLK = LFXT1 = 32768Hz, MCLK = SMCLK = DCO = 32xACLK = 1048576Hz时钟周期为0.95us
//14系列默认时钟 ACLK= n/a, MCLK= SMCLK= default DCO ~800k 时钟周期为1.25us
//MC430F14 DS18B20实验主程序
void main(void)
{
#if XF_MCU==0
WDTCTL=WDTPW+WDTHOLD; //停止WDT
mcuinit(); //MSP430F14初始化
#else
LCM141_DIR_OUT;
#endif
while(1)
{
GetTemp(); //读取温度
display_number(Temper); //数据变换
;
}
}
//将温度值转换成可显示十进制值
//取数范围整数3位,小数点后3位.
void display_number(float f_data)
{ unsigned long value;
float n;
n=f_data *1000;
value = (unsigned long int)n;
temp_display[1] = digit[value/100000]; //100位
value = value%100000;
temp_display[2] = digit[value/10000]; //10位
value = value%10000;
temp_display[3] = digit[value/1000]; //1位
value = value%1000;
temp_display[5] = digit[value/100]; //0.1位
value = value%100;
temp_display[6] = digit[value/10]; //0.01位
value = value%10;
temp_display[7] = digit[value/1]; //0.001位
}
//--------------------------------------------------------------------
//---------------------------------------------------------------------
//MSP430F14初始化
void mcuinit(void)
{
DQIO_OUT; //设为输出
DQ1; //输出高电平;
}
//---------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -