平台: 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單總線讀寫時對時序要求很嚴格,每次讀寫時關閉中斷即可得到穩定數據。