相信玩過51的童鞋應(yīng)該都玩過DS18B20吧,雖然用在ARM11上面,但是操作還是一樣,多了一點就是讀寫IO前需要切換IO方向,其實51在讀取之前需要切換到高電平的,這個一般由編譯器完成的,
/*************************************************************************************************************
* 文件名: ds18b20.c
* 功能: S3C6410 DS18B20驅(qū)動
* 作者: cp1300@139.com
* 創(chuàng)建時間: 2012年9月17日22:45
* 最后修改時間:2012年9月17日
* 詳細: 需要延時函數(shù)支持
* 注意延時精度盡可能的高
* 讀取的時候不要長時間的被中斷,因為1wire對時間要求很嚴(yán)格
*************************************************************************************************************/
#include "system.h"
#include "timer.h"
#include "delay.h"
#include "ds18b20.h"
//DS18B20使用的是GPIOE0
#define Set18b20IOout() (rGPECON |= 1) //設(shè)置DS18B20 IO為輸出,
#define Set18b20IOin() (rGPECON &= (~0xf)) //設(shè)置DS18B20 IO為浮空輸入,
#define Read18b20IO() ((rGPEDAT & BIT0) ? 1 : 0) //讀取DS18B20 IO
#define Write18b20IO(x) (x ? (rGPEDAT |= BIT0) : (rGPEDAT &= ~BIT0)) //寫DS18B20 IO
/*************************************************************************************************************************
*函數(shù) : u8 DS18B20_Reset(void)
*功能 : 復(fù)位DS18B20
*參數(shù) : 無
*返回 : 0:成功;1:失敗
*依賴 : 底層宏定義
*作者 : cp1300@139.com
*時間 : 20120917
*最后修改時間: 20120917
*說明 :無
*************************************************************************************************************************/
u8 DS18B20_Reset(void)
{
u8 i = 0;
Set18b20IOout(); //主機端口推挽輸出模式
Write18b20IO(1);
Delay_US(1);
Write18b20IO(0); //拉低總線480us~240us
Delay_US(500); //>480US延時
Write18b20IO(1);
Delay_US(2); //復(fù)位完成
Set18b20IOin(); //主機端口浮空輸入模式
while(Read18b20IO()) //等待低電平應(yīng)答信號
{
i ++;
Delay_US(1);
if(i > 100)
return 1; //等待超時,初始化失敗,返回1;
}
Delay_US(250); //跳過回復(fù)信號
return 0x00; //檢測到DS18B20,并且初始化成功
}
/*************************************************************************************************************************
*函數(shù) : u8 DS18B20_ReadData(void)
*功能 : 讀取DS18B20數(shù)據(jù)
*參數(shù) : 無
*返回 : 數(shù)據(jù)
*依賴 : 底層宏定義
*作者 : cp1300@139.com
*時間 : 20120917
*最后修改時間: 20120917
*說明 :無
*************************************************************************************************************************/
u8 DS18B20_ReadData(void)
{
u8 i,data = 0;
for(i = 0;i < 8;i ++)
{
Set18b20IOout(); //主機端口推挽輸出模式
Write18b20IO(0); //拉低總線10-15us
data >>= 1;
Delay_US(12);
Write18b20IO(1); //釋放總線
Set18b20IOin(); //主機端口浮空輸入模式
Delay_US(1);
if(Read18b20IO()) //讀取數(shù)據(jù),讀取后大約延時40-45us
data |= 0x80;
Delay_US(42);
}
return data;
}
/*************************************************************************************************************************
*函數(shù) : void DS18B20_WriteData(u8 data)
*功能 : 向DS18B20寫數(shù)據(jù)
*參數(shù) : 數(shù)據(jù)
*返回 : 無
*依賴 : 底層宏定義
*作者 : cp1300@139.com
*時間 : 20120917
*最后修改時間: 20120917
*說明 :無
*************************************************************************************************************************/
void DS18B20_WriteData(u8 data)
{
u8 i;
Set18b20IOout(); //主機端口推挽輸出模式
for(i = 0;i < 8;i ++)
{
Write18b20IO(0); //拉低總線10-15us
Delay_US(12);
Write18b20IO(data & 0x01); //寫入數(shù)據(jù)位,保持20-45us
Delay_US(30);
Write18b20IO(1); //釋放總線
data >>= 1;
Delay_US(2);
}
}
/*************************************************************************************************************************
*函數(shù) : s16 DS18B20_ReadTemper(void)
*功能 : 讀取DS18B20溫度
*參數(shù) : 無
*返回 : 溫度值
*依賴 : 底層宏定義
*作者 : cp1300@139.com
*時間 : 20120917
*最后修改時間: 20120917
*說明 :溫度值擴大了100倍,溫度值是個有符號數(shù).
*************************************************************************************************************************/
s16 DS18B20_ReadTemper(void)
{
u8 th, tl;
s16 data;
if(DS18B20_Reset())
{
return 0xffff; //返回錯誤
}
DS18B20_WriteData(0xcc); //跳過讀序列號
DS18B20_WriteData(0x44); //啟動溫度轉(zhuǎn)換
DS18B20_Reset();
DS18B20_WriteData(0xcc); //跳過讀序列號
DS18B20_WriteData(0xbe); //讀取溫度
tl = DS18B20_ReadData(); //讀取低八位
th = DS18B20_ReadData(); //讀取高八位
data = th;
data <<= 8;
data |= tl;
data *= 6.25; //溫度值擴大100倍,精確到2位小數(shù)
return data;
}
DS18B20.H
#ifndef DS18B20_H_
#define DS18B20_H_
s16 DS18B20_ReadTemper(void); //讀取DS18B20溫度
#endif /*DS18B20_H_*/
DELAY.C
/*************************************************************************************************************
* 文件名: delay.c
* 功能: 延時函數(shù),調(diào)用定時器1進行延時的
* 作者: cp1300@139.com
* 創(chuàng)建時間: 2012年9月17日22:32
* 最后修改時間:2012年9月17日
* 詳細: 延時誤差1-2us,使用定時器1
* 不能在中斷服務(wù)程序中使用
*************************************************************************************************************/
#include "system.h"
#include "timer.h"
#include "delay.h"
/*************************************************************************************************************************
*函數(shù) : void Delay_US(u32 Delay)
*功能 : US延時
*參數(shù) : Delay:延時時間,單位US
*返回 : 無
*依賴 : 底層宏定義
*作者 : cp1300@139.com
*時間 : 20120917
*最后修改時間: 20120917
*說明 :調(diào)用定時器0進行延時的,那么定時器0就不能使用了,延時誤差1US
*************************************************************************************************************************/
void Delay_US(u32 Delay)
{
rTCFG0 |= 65; //定時器0預(yù)分頻65+1,由PCLK=66提供時鐘,66分頻產(chǎn)生1MHz的定時器時鐘
rTCON &= (~0xff); //清除設(shè)置
rTCON |= BIT3; //定時器0自動更新使能
rTCNTB0 = Delay; //重裝值
rTINT_CSTAT |= BIT5; //清除中斷標(biāo)志
rTINT_CSTAT &= ~BIT0; //關(guān)閉定時器0中斷
//以下操作啟動定時器0
rTCON |= BIT1; //手動更新
rTCON &= ~BIT1; //結(jié)束手動更新
rTCON |= BIT0; //啟動定時器0
while(!(rTINT_CSTAT & BIT5)); //等待延時到達
rTINT_CSTAT |= BIT5; //清除中斷標(biāo)志
}
/*************************************************************************************************************************
*函數(shù) : void Delay_MS(u32 Delay)
*功能 : MS延時
*參數(shù) : Delay:延時時間,單位US
*返回 : 無
*依賴 : 底層宏定義
*作者 : cp1300@139.com
*時間 : 20120918
*最后修改時間: 20120918
*說明 :調(diào)用定時器0進行延時的,那么定時器0就不能使用了,延時誤差<1ms
*************************************************************************************************************************/
void Delay_MS(u32 Delay)
{
while(Delay --)
{
Delay_US(1000);
}
}
后面將這個程序移植到LINUX上面當(dāng)做DS18B20驅(qū)動