********************************************************************
** 这是学习 msp430g2553 单片机时写的 DS18b20 的程序 **
** DS18b20 单总线,时序严格,完全自学明白浪费了n久!! **
** 最高精度0.0625,即温度每变 0.0625 就能被检测到 **
** 网上一些 *0.0625 、*256/1000 、 /16 的都是错误的(I think) **
** DQ 接 p2.4 **
********************************************************************
********************************************************************
** DS18b20
操作时序: **
** 1. DS18b20
初始化 **
** 2.
对64位ROM进行操作 **
** 读ROM **
** 搜索ROM **
** 跳过ROM **
** 告警搜索 **
** 3.
对寄存器进行操作 **
** 4. 精度默认的为0.0625
,无法重新设定,没找到相应的指令 **
** 相对应的转换时间为750ms **
********************************************************************
#include
#include
#define DQ_1 P2OUT |= BIT4
#define DQ_0 P2OUT &= ~BIT4
#define
DQ_in P2DIR &= ~BIT4
#define DQ_out P2DIR |=
BIT4
#define DQ_val (P2IN & BIT4)
#define Read_ROM 0x33 //读ROM
#define Match_ROM 0x55 //匹配ROM
#define Skip_ROM 0xcc //跳过ROM
#define Search_ROM
0xf0 //搜索ROM
#define Alarm_Search 0xec //告警搜索
#define Convert_Temperature 0x44 //温度转换
#define Read_Scratchpad 0xbe //读暂存存储器9字节内容
#define Write_Scratchpad 0x4e //写暂存存储器,写的是TH and TL , 接着发送两位数据就可以
****************************************************
** 内部暂存存储器9字节内容 **
** 1.
温度低8位 **
** 2.
温度高8位 **
** 3.
温度上限TH **
** 4.
温度下线TL **
** 5.
配置 **
** 6.7.8
保留 **
** 9. CRC
校验码 **
****************************************************
unsigned int Check_val; //初始化检测变量
unsigned int Temp;//温度整数值
****************************************************************************************
** DS18b20
初始化方法: **
** 1 主机发送 480 - 960 us
的低电平,释放总线 **
** 2 等待 15 - 60
us **
** 3
检测DQ上是否有低电平出现 **
** 有:复位成功 ,通常时间为 60-240
us **
** 无:复位失败,继续等待 **
** 4
DQ上出现低电平后,低电平持续15us,然后DS18b20开始对单片机发送的数据进行采样 **
****************************************************************************************
unsigned int DS18b20_init(void)
{
DQ_out;
DQ_0;
__delay_cycles(600);
DQ_1;
__delay_cycles(60);
DQ_in;
_NOP();
if(DQ_val)
{
Check_val =
0; //初始化失败
}
else
{
Check_val =
1; //初始化成功
}
__delay_cycles(10);
DQ_out;
DQ_1;
__delay_cycles(100);
return Check_val;
}
************************************************************************
** DS18b20
写数据方法: **
** 1 DS18b20
是“一位一位”的写‘0’和‘1’ **
** 2 每写一次‘1’或‘0’为一个周期,每个周期约为 45 - 60
us **
** 3 DQ拉低 1 us
,表示写周期开始,释放总线,让DQ随写入的值变化 **
** 4 若写1:
DQ拉高至少60us,保证在采样周期内采到的值均为高 **
** 5 若写0:
DQ拉低至少60us,保证在采样周期内采到的值均为低 **
** 6
释放总线 **
** ************************************************************* **
** 单片机发送数据时,是从写的数据的最低位开始发送 **
************************************************************************
void DS18b20_write_byte(unsigned int dat)
{
unsigned
int i;
for(i = 0; i < 8;i++)
{
DQ_0;
__delay_cycles(2);
if(dat &
0X01)
DQ_1;
else
DQ_0;
__delay_cycles(60);
dat >>=
1;;
DQ_1;
__delay_cycles(10);
}
}
**************************************************************************************************
** DS18b20
读数据方法: **
** 1 DS18b20
是“一位一位”的读‘0’和‘1’ **
** 2 每读一次‘1’或‘0’为一个周期,每个周期约为 45 - 60
us **
** 3 DQ拉低 1 us
,表示读周期开始,释放总线,让DQ随DS18b20传送的值变化 **
** 4
若传1:则检测到高电平,持续时间为60us左右,所以检测一次后要延时60us, **
** 再检测下一位传送的数据 **
** 5
若传0:则检测到低电平,持续时间为60us左右 **
*******************************************************************************************
** DS18b20 传送数据也是从最低位开始传,所以要把单片机中存储DS18b20发送数据的变量先右移, **
** 把最低位移到最前面 **
**************************************************************************************************
unsigned int DS18b20_read_byte(void)
{
unsigned i;
unsigned int byte = 0;
for(i = 0;i < 8;i++)
{
byte >>=
1;
DQ_0;
__delay_cycles(2);
DQ_1;
__delay_cycles(2);
DQ_in;
_NOP();
if(DQ_val)
byte |= 0x80;
__delay_cycles(60);
DQ_out;
DQ_1;
__delay_cycles(10);
}
return byte;
}
**************************************************************************************************
** 当用一个DS18b20进行温度测量时步骤: **
** 1
DS18b20 初始化 **
** 2 跳过
ROM **
**
3 控制寄存器:进行温度转换、读9_data ROM、读取温度第八位、读取温度高八位 **
*******************************************************************************************
** 注意: 单总线,所以每次读写都要分开: **
** 写数据要初始化一次,把所有的数据都写进去 ** ** 读数据要初始化一次,把所有的数据都读出来 **
**************************************************************************************************
unsigned int get_one_temperature(void)
{
unsigned int
Temp_l;
unsigned int Temp_h;
DS18b20_init();
DS18b20_write_byte(Skip_ROM);
DS18b20_write_byte(Convert_Temperature);
__delay_cycles(500000);
DS18b20_init();
DS18b20_write_byte(Skip_ROM);
DS18b20_write_byte(Read_Scratchpad);
Temp_l=DS18b20_read_byte();
Temp_h=DS18b20_read_byte();
Temp_l>>=4;
Temp_h<<=4;
Temp=Temp_h+Temp_l;
return Temp;
}
上一篇:LCD1602_8 data
下一篇:128*64液晶显示功能实现
推荐阅读最新更新时间:2024-03-16 15:25