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指令