DS18B20温度传感器实现代码
平台: freescale CodeWarrior
MCU:MC9S12G128(汽车级芯片)
#include "Ds18b20.h"
/************************************************************
* DS18B20 status initialization
************************************************************/
#pragma MESSAGE DISABLE C12056 //屏蔽警告
INT8U Ds18b20StsInit(void)
{
INT8U ack = DB_OK;
INT16U outTime = 500;
//DisableInterrupts
/* 初始化状态 */
BUS_DIR = HIGH;
BUS = HIGH;
DelayUs(8);
/* 拉低BUS,延时500us */
BUS = LOW;
DelayUs(480);
/* BUS上拉,延时15us-60us */
BUS = HIGH;
DelayUs(30);
/* BUS设置为输入 */
BUS_DIR = LOW;
/* 等待DS18B20存在脉冲做出回应,0正常,60-240us */
DelayUs(8);
while(BUS)
{
--outTime; //超时处理
if(outTime == 0)
{
ack = DB_ERR;
break;
}
}
/* 等待DS18B20恢复稳定 */
DelayUs(128);
/* BUS上拉 */
BUS_DIR = HIGH;
BUS = HIGH;
DelayUs(280);
//EnableInterrupts
return (ack);
}
/************************************************************
* Write data to ds18b20
************************************************************/
PRIVATE void Ds18b20WriteData(INT8U cmd)
{
INT8U i;
DisableInterrupts
for(i = 0; i < 8; i++)
{
//BUS = LOW; //HIGH->LOW 启动写时序
//Tim_Delay8Us(2);
if(cmd & 0x01) //从低位开始发送数据,15us完成
{
BUS = 0; //写1时序
DelayUs(5);
BUS = 1;
}
else
{
BUS = 0; //写0时序
DelayUs(5);
}
DelayUs(60); //等待从器件采集数据
BUS = HIGH; //拉高总线,起始状态
DelayUs(8);
cmd >>= 0x01;
}
EnableInterrupts
}
#if 1
/************************************************************
* Read data from ds18b20
************************************************************/
PRIVATE INT8U Ds18b20ReadData(void)
{
INT8U i;
INT8U data = 0x00;
BUS = HIGH;
DelayUs(8);
DisableInterrupts
for(i = 0; i < 8; i++)
{
data >>= 0x01;
BUS = LOW; //拉低总线,进行读时序操作
DelayUs(8);
BUS = HIGH; //拉低总线,进行读时序操作
DelayUs(8);
BUS_DIR = LOW; //配置为输入
asm("nop");
//Tim_Delay8Us(1);
if(BUS)
{
data |= 0x80;
}
DelayUs(60); //等待数据读缓存
BUS_DIR = HIGH;
BUS = HIGH;
DelayUs(8);
}
EnableInterrupts
return (data);
}
#endif
INT8U Dt = 0, Dt1 = 0;
/************************************************************
* Get data from ds18b20
************************************************************/
INT16U Ds18b20GetTemperature(void)
{
INT16U data = CLEAR;
INT8U temp[2] = {0};
Dt = Ds18b20StsInit();
Ds18b20WriteData(0xcc); //跳过rom命令
Ds18b20WriteData(0x44); //启动温度转换
Dt1 = Ds18b20StsInit();
Ds18b20WriteData(0xcc); //跳过rom命令
Ds18b20WriteData(0xbe); //读暂存寄存器
temp[0] = Ds18b20ReadData();
temp[1] = Ds18b20ReadData();
data = (temp[1] << 8) | temp[0];
return (data);
}
调试DS18B20遇到采集数据不稳定情况:
不稳定现象:每读到几个正常数据后会有几个不正常的数据
不稳定原因:因为中断在打断我数据的读写以及采集
解决办法:因为DS18B20单总线读写时对时序要求很严格,每次读写时关闭中断即可得到稳定数据。