?? ds1820.c
字號:
//**********************************************************************
//功能 : 實時時鐘DS1820操作模塊
//作者 : lihj
//創建日期 : 2004-07-10
//版本 : V1.0
//修改記錄 :
//***********************************************************************
#include <reg51.h>
#include <std.h>
#include <ds1820.h>
sbit TMDAT = P3^4; //根據實實際情況設定
//函數功能:延時(12MHz晶振)
//輸入參數:<count>延時時間長度,單位1ms
void Delay_ms (U16 count)
{
U16 i;
while (count)
{
i = 123;
while (i>0) i--;
count--;
}
}
//函數功能:復位芯片(至少480us長的低電平信號)
void ResetChip (void)
{
U16 i;
TMDAT = 0; //480us~960us長低電平:復位
i = 150;
while (i--); //延時約900 uS(12Mhz時)
TMDAT = 1;
i = 5;
while (i--); //DS1820檢測到上升沿后,過15~60us后輸出“存在”信號
}
//函數功能: 判斷DS1820是否存在
//返回參數: TRUE:芯片存在
// FALSE:芯片不存在
U8 ChipPresenceCheck(void)
{
U16 i;
ResetChip();
//等待70us,應該檢測到低電平
i = 11;
while(i--);
if(TMDAT)
{
return FALSE;
}
//等待400us,應檢測到高電平,低電平信號保持60~240us
i = 65;
while (i--);
if(TMDAT)
{
return TRUE;
}
else
{
return FALSE;
}
}
//函數功能:從總線上讀取1位信號
bit RdBit (void)
{
U16 i;
bit b0;
TMDAT = 0; i++; //下降沿之后,保持低電平至少1us //
TMDAT = 1; i++; i++; //微量延時(既作輸入又作輸出的I/O腳,讀數據時,先拉高電平)
b0 = TMDAT;
i = 9;
while (i--); //延時60us
return (b0);
}
//函數功能:從總線上讀取1個字節信號
U8 RdByte (void)
{
U8 i,j,byRdData=0;
for (i=0;i<8;i++)
{
j = RdBit ();
byRdData >>= 1;
byRdData = (j << 7) | byRdData;
}
return (byRdData);
}
//函數功能:向總線上寫一位數據
void WrBit(bit b0)
{
U8 i;
if (b0)
{
TMDAT = 0; //產生一個下降沿,低電平至少保持1us //
i++; i++;
TMDAT = 1; //輸出1
i = 9; while (i--); //高電平保持60us //
}
else
{
TMDAT = 0; // 寫0
i = 9; while (i--); //低電平保持60us //
TMDAT = 1;
i++; i++;
}
}
//向總線上寫一個字節
void WrByte (U8 dat)
{
U8 i;
bit testb;
for (i=0;i<8;i++)
{
testb = dat & 0x01;
dat = dat >> 1;
WrBit(testb);
}
}
//函數功能 :寫1-Wire協議頭操作(復位芯片、選擇芯片、寫命令碼)
//輸入參數 :<pSN>芯片序號
// : <byCommand>命令碼
void SendHeaderData(U8 *pSN, U8 byCommand)
{
U8 i;
ResetChip(); //復位
Delay_ms(1); //延時
//***********************
//如果總線上只有一個設備,不需要選擇芯片操作
#if (CHIP_NUM_IN_WIRE == 1)
WrByte(0xcc); //總線上只有一個設備,跳過芯片匹配步驟
#else
WrByte(0x55); //發送ROM匹配命令
for(i=0;i<8;i++)
{
WrByte(*pSN++); //發送64位序列號
}
#endif
WrByte(byCommand); //發送讀取中間寄存器命令
}
//函數功能 : 讀溫度芯片中間寄存器(從偏移地址0開始)
//輸入參數 : <pSN>溫度芯片的序號(ROM碼)
// : <pRdData> 存放讀取出的數據
// : <byLen>需讀取的數據的長度
void RdScratchpad(U8 *pSN, U8 *pRdData, U8 byLen)
{
U8 i;
//輸入參數檢查
if(byLen > 9)
{
byLen = 9;
}
SendHeaderData(pSN, 0xbe);
//讀出數據
for(i=0;i<byLen;i++)
{
*pRdData++ = RdByte();
}
ResetChip(); //復位芯片,結束讀操作
Delay_ms(1); //延時
}
//函數功能 : 寫溫度芯片中間寄存器(從偏移地址2開始)
//輸入參數 : <pSN>溫度芯片的序號(ROM碼)
// : <pWrData> 寫到中間寄存器的源數據
// : <byLen>寫入數據的長度
void WrScratchpad(U8 *pSN, U8 *pWrData, U8 byLen)
{
U8 i;
//輸入參數檢查
if(byLen > 2)
{
byLen = 2;
}
SendHeaderData(pSN, 0x4e); //發送協議頭
//寫入數據
for(i=0;i<byLen;i++)
{
WrByte(*pWrData++);
}
ResetChip(); //復位芯片,結束寫操作
Delay_ms(1); //延時
}
//函數功能:啟動溫度轉換過程
//輸入參數:<pSN>芯片序號
void StartConvertTmpt (U8 *pSN) //
{
U8 byBusyFlag=0;
SendHeaderData(pSN, 0x44); //發送協議頭
while(1) //某些情況下,這里可能出現死循環
{
byBusyFlag = RdByte();
if(byBusyFlag == 0xff)
{
break;
}
}
ResetChip (); //復位,保持低電平480-960us //
Delay_ms(1);
}
//函數功能 :讀取溫度
//輸入參數 : <pSN>芯片序號
//輸出參數 : 溫度值,放大10倍的整數
S16 RdTemperture (U8 *pSN) //
{
U8 byRdData[8];
U8 byTEMP_READ;
U8 byCOUNT_PER_C;
U8 byCOUNT_REMAIN;
S16 t;
float ft;
RdScratchpad(pSN, byRdData, 8); //讀取數據,沒有讀CRC校驗碼
//0.5攝氏度精度的計算方法
// t = byRdData[0]+(byRdData[1]<<8); //1表示0.5攝氏度
// return t;
t = byRdData[0]+(byRdData[1]<<8);
byTEMP_READ = t>>1;
byCOUNT_REMAIN = byRdData[6];
byCOUNT_PER_C = byRdData[7];
ft = (float)byTEMP_READ - 0.25 + (float)(byCOUNT_PER_C - byCOUNT_REMAIN)/(float)byCOUNT_PER_C;
t = ft*10;
return t; //1表示0.1攝氏度
}
//函數功能 :讀取芯片序號(只能在總線只有一個器件時調用)
//輸入參數 : <pSN>返回的芯片序號存放地址
void ReadROM(U8 *pSN) //
{
U8 i;
ResetChip (); //復位
Delay_ms (1); //延時
WrByte(0x33); //發送讀序列號子程序
for(i=0;i<8;i++)
{
*pSN ++ = RdByte(); //讀取第一個序列號,應為10H; //
}
}
//功能 :寫溫度報警上下限
//輸入參數 : <pSN>溫度芯片序號
// : <nHighAlarmLim> 溫度報警上限
// : <nLowAlarmLim> 溫度報警下限
U8 WrTmptAlarmLim(U8 *pSN, S16 nHighAlarmLim, S16 nLowAlarmLim)
{
U8 byWrData[2];
U8 byRdData[4];
byWrData[0] = nHighAlarmLim;
byWrData[1] = nLowAlarmLim;
WrScratchpad(pSN, byWrData, 2); //寫入數據
RdScratchpad(pSN, byRdData, 4); //讀出數據進行校驗
if((byRdData[2] != nHighAlarmLim) || (byRdData[3] != nLowAlarmLim))
{
return FALSE;
}
//將中間寄存器數據拷貝到E2RAM(存放報警限數據)
SendHeaderData(pSN, 0x48);
Delay_ms (6); //延時6ms
ResetChip(); //復位芯片,結束本次操作
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -