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