OneWire.h
#ifndef _ONEWIRE_H
#define _ONEWIRE_H
sbit ONEWIRE_PIN = P1^4; //檢查通信引腳是否正確!
bit OneWire_reset();
void OneWire_write(uint8_t dat);
uint8_t OneWire_read();
#define OneWire_skip() OneWire_write(0xCC) //跳過ROM指令
#endif // _ONEWIRE_H
OneWire.c
/**
* 文件名:OneWire.c
* 描 述:單總線協議驅動模塊
*/
#include <reg52.h>
#include <intrins.h>
#include "stdint.h"
#include "OneWire.h"
/**
* 軟件延時函數,延時時間(t*10)us
* 時鐘晶振:11.0592MHz
* 機器週期 = 12 * 時鐘週期
*/
static void delayX10us(uint16_t t) { //注意!uint8_t會溢出!
//t *= 6;
do {
_nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_();
} while (--t);
}
/* 復位單總線,獲取存在脈衝,以啓動一次讀寫操作 */
bit OneWire_reset() {
bit ack;
EA = 0; //禁止總中斷
ONEWIRE_PIN = 0; //產生500us復位脈衝
delayX10us(50);
ONEWIRE_PIN = 1;
delayX10us(6); //延時60us
ack = ONEWIRE_PIN; //讀取存在脈衝
while (!ONEWIRE_PIN); //等待存在脈衝結束
EA = 1; //重新使能總中斷
return ack;
}
/* 向單總線寫入一個字節,dat-待寫入字節 */
void OneWire_write(uint8_t dat) {
uint8_t mask;
EA = 0; //禁止總中斷
//低位在先,依次移出8個bit
for (mask = 0x01; mask != 0; mask <<= 1) {
ONEWIRE_PIN = 0; //產生2us低電平脈衝
_nop_();
_nop_();
if ((mask & dat) == 0) //輸出該bit值
ONEWIRE_PIN = 0;
else
ONEWIRE_PIN = 1;
delayX10us(6); //延時60us
ONEWIRE_PIN = 1; //拉高通信引腳
}
EA = 1; //重新使能總中斷
}
/* 從單總線讀取一個字節,返回值-讀到的字節 */
uint8_t OneWire_read() {
uint8_t dat, mask;
EA = 0; //禁止總中斷
//低位在先,依次採集8個bit
for (mask = 0x01; mask != 0; mask <<= 1) {
ONEWIRE_PIN = 0; //產生2us低電平脈衝
_nop_();
_nop_();
ONEWIRE_PIN = 1; //結束低電平脈衝,等待18B20輸出數據
_nop_(); //延時2us
_nop_();
if (ONEWIRE_PIN) //讀取通信引腳上的值
dat |= mask;
else
dat &= ~mask;
delayX10us(6); //再延時60us
}
EA = 1; //重新使能總中斷
return dat;
}
/* 跳躍ROM指令 */
#define OneWire_skip() OneWire_write(0xCC) //跳過ROM指令