我最近正在研究使用AVR来驱动MAXIN的DS18B20,琢磨了几天,终于把它的驱动程序写好了.
使用IAR C++编译器
#ifndef DS18B20_H
#define DS18B20_H
/****************************************只需在源程序里定义以下宏
#define seDDS() (seDB0())
#define clDDS() (clDB0())
#define seDS() (sePB0())
#define clDS() (clPB0())
#define GetDS() (GetPB0())
*********************************************/
/*********************************** 函数说明 *********************
void DS18B20::DS18B20(void) 构造函数
void DS18B20::init()初始化DS18B20
char DS18B20::GetID()读取器件ID,成功返回1,并且器件的64位id号保存到DS18B20.id[4],里,失败返回0
char DS18B20::convter()读取温度,成功返回1,并且温度值保存到DS18B20.temp里,未就绪返回0。此程序需要调用数次才能正确转换
调用周期不得低于2ms
char DS18B20::GetPower()读取总线供电模式,正常返回1,寄生返回0
char DS18B20::SearchAlarm()读取报警,有报警返回1,没有返回0
****************************************************/
#define DS_ReadROM 0x33
#define DS_CopyROM 0x48
#define DS_MatchROM 0x55
#define DS_SkipROM 0xCC
#define DS_SearchROM 0xF0
#define DS_AlarmSearch 0xEC
#define DS_Convert 0x44
#define DS_ReadRAM 0xBE
#define DS_WriteRAM 0x4E
#define DS_ReadPower 0xB4
#define DS_9BIT 0
#define DS_10BIT 1
#define DS_11BIT 2
#define DS_12BIT 3
#include "c:incstatus.h"
#include "c:inccrc8.c"
#include "c:incdelay.c"
#include "c:incformat.h"
#include
class DS18B20
{
public:
float temp;// 温度
int rel;// 温度偏移量
char id[8];// 器件ID号
char mode;// 转换模式9-12bit
unsigned char TH;// 预警温度上限
unsigned char TL;// 预警温度下限
char power;// 0:寄生供电 1:电源供电
char status;// 单线总线状态0: 无连接 1:已连接
char sbuf[10];
private:
char setup;
/****************************************复位总线***********************/
char Reset_DS()
{
unsigned int x;
seDS();
seDDS();
DELAY_80us();
if(GetDS())
{
clDS();
DELAY_600us();
seDS();
clDDS();
for(x=0;x<30;)
{
if(GetDS())x++;
else
{
for(x=0;x<30;)
{
if(GetDS())
{
seDDS();
DELAY_600us();//
return 1;
}
else
x++;
DELAY_10us();
}
clDDS();
return 0;
}
DELAY_10us();//
}
}
clDDS();
return 0;
}
/**************************************************写总线*******************/
void Write_DS(unsigned dat,unsigned char wide)// dat:数据 wide:数据宽度(位数)
{
unsigned char i,sreg;
seDDS();
for(i=0;i
sreg=SREG;
SREG&=0x7F;// 关中断
if(dat&0x01)
{
clDS();
DELAY_10us();
seDS();
DELAY_80us();
}
else
{
clDS();
DELAY_80us();
seDS();
DELAY_10us();
}
SREG=sreg;// 恢复中断 发生的中断将依次执行
dat>>=1;
}
}
/***************************************************读总线*******************/
unsigned char Read_DS(unsigned char wide)
{
unsigned char dat,i,sreg;
for(i=dat=0;i
if(GetDS())
{
sreg=SREG;
SREG&=0x7F;
clDS();
seDDS();
DELAY_10us();
seDS();
clDDS();
dat>>=1;
DELAY_10us();
if(GetDS())dat|=0x80;
seDDS();
SREG=sreg;
DELAY_80us();
}
else
{
setup=0;
}
}
return dat;
}
char getid()
{
char i;
for(i=0;i
return 1;
return 0;
}
public:
char convert()// 本程序调用周期至少2ms或以上
{
static unsigned char sbuf[9];
static unsigned int i;
switch(setup)
{
case 0:
if(Reset_DS())// 开始
{
status=1;
setup++;
}
else
status=0;
break;
case 1:
if(getid())
{
Write_DS(DS_MatchROM,8);// 匹配ROM
for(i=0;i<8;i++)
Write_DS(id,8);
}
else
{
Write_DS(DS_SkipROM,8);// 跳过匹配
}
Write_DS(DS_Convert,8);// 启动转换
i=power?0:500;// 选择电源方式,以达到最快速度
setup++;
break;
case 2:
if(i)// 延时
{
i--;
}
else if(Read_DS(8)==0xFF)// 等待转换结束
{
Reset_DS();
if(getid())
{
Write_DS(DS_MatchROM,8);// 匹配ROM
for(i=0;i<8;i++)
Write_DS(id,8);
}
else
Write_DS(DS_SkipROM,8);
Write_DS(DS_ReadRAM,8);
i=0;
setup++;
}
break;
case 3:
sbuf=Read_DS(8);
if(i>=9)
{
Reset_DS();
if(GetCRC8(sbuf,8)==sbuf[8])// 校验CRC
{
int i;
i=sbuf[1]*0x100+sbuf[0];
i+=rel;
temp=i/16+(i%16)*0.125;
setup=0;
status=1;
return 1;
}
setup=0;
}
break;
}
return 0;
}
char GetPower()
{
unsigned char x;
if(Reset_DS())
{
Write_DS(DS_SkipROM,8);
Write_DS(DS_ReadPower,8);
x=Read_DS(8);
Reset_DS();
if(x)
return 1;
}
return 0;
}
/*************************************预警搜索****************************/
char SearchAlarm()
{
if(Reset_DS())
{
Write_DS(DS_AlarmSearch,8);
if(Read_DS(2)==0x80)// 读两个位
{
Reset_DS();
return 1;
}
}
Reset_DS();
return 0;
}
//TH:高温限制 TL:低温限制
//mode:转换模式 0:9bit(93.75ms) 1:10bit(187.5ms) 2:11bit(375ms) 3:12bit(750ms)
//power:总线的电源模式
//ID:器件ID号
char init()
{
unsigned char i,sbuf[9];
if(Reset_DS())
{
if(getid())
{
Write_DS(DS_MatchROM,8);
for(i=0;i<8;i++)
Write_DS(id,8);
}
else
Write_DS(DS_SkipROM,8);
Write_DS(DS_WriteRAM,8);
Write_DS(TH,8);
Write_DS(TL,8);
Write_DS(((mode&0x03)<<5)|0x1F,8);
Reset_DS();
if(getid())
{
Write_DS(DS_MatchROM,8);
for(i=0;i<8;i++)
Write_DS(id,8);
}
else
Write_DS(DS_SkipROM,8);
Write_DS(DS_ReadRAM,8);
for(i=0;i<9;i++)
sbuf=Read_DS(8);
if(GetCRC8(sbuf,8)==sbuf[8])// 校验CRC
{
if(sbuf[2]==TH&&sbuf[3]==TL)
{
Reset_DS();
if(getid())
{
Write_DS(DS_MatchROM,8);
for(i=0;i<8;i++)
Write_DS(id,8);
}
else
Write_DS(DS_SkipROM,8);
Write_DS(DS_CopyROM,8);
DELAY_200ms();
Reset_DS();
power=GetPower();
Reset_DS();
return 1;// 完成
}
}
}
return 0;
}
/*********************************************读取DS18B20的64位ROM******************/
char GetID()
{
unsigned char i;
unsigned char sbuf[8];
if(Reset_DS())
{
Write_DS(DS_ReadROM,8);
for(i=0;i<8;i++)
{
sbuf=Read_DS(8);
}
Reset_DS();
if(GetCRC8(sbuf,7)==sbuf[7])// 校验CRC
{
for(i=0;i<8;i++)
id=sbuf;// 拷贝数据到ROM
return 1;
}
}
return 0;
}
char* disp(char width=0)
{
int i=(int)temp;
int j=(int)(temp*10);
j%=10;
if(temp<0)
j=0-j;
switch(width)
{
case 2:
sprintf(sbuf,"%2d.%d",i,j);
break;
case 3:
sprintf(sbuf,"%3d.%d",i,j);
break;
default:
sprintf(sbuf,"%d.%d",i,j);
break;
}
return sbuf;
}
DS18B20()
{
format(id,sizeof(id),0);
mode=DS_12BIT;
TH=100;
TL=0;
power=0;
rel=0;
status=0;
setup=0;
seDDS();
seDS();
}
};
#endif
上一篇:avr单片机ds1302时钟程序详解
下一篇:AVR定时器1的相位修正PWM模式设置
推荐阅读最新更新时间:2024-11-09 10:49
设计资源 培训 开发板 精华推荐
- LTC3400BES6 单节电池至 3.3V 同步升压转换器的典型应用电路
- USB Type-C™和电力输送双端口接口板,带汽车级STUSB1702Y USB Type-C控制器
- 无刷电调
- 使用 Infineon Technologies AG 的 OM185SR 的参考设计
- OP497FSZ平方根放大器典型应用电路
- 使用具有 PowerPath 和 2A 输入限制的 LTC4162EUFD-L40M 9V 至 35V、2 节、3.2A 充电器的典型应用
- AKD4643-B,带有内置 MIC/HP/RCV/SPK 放大器的 AK4643 立体声编解码器的评估板
- LT3091MPFE 12V 至 ±3.3V 低噪声电源的典型应用
- 通过仔细的 IF 信号链设计最大限度地提高 16 位、105Msps ADC 的性能
- AR0132AT6M00XPEAH3-GEVB: 1.2 MP Sunex DSL945D 1/3" iBGA CIS HB
- ADI学霸型讲师又来了,探讨MEMS传感器和工业设备的故障监测
- 现场抽取PS5等诸多好礼 SiFive RISC-V 中国技术论坛 上海、北京、深圳 3场线下活动邀您出席!
- 免费测评|抢鲜体验树莓派Pico!
- 大联大有奖直播:科技之眼-思特威图像传感器的新视界
- 有奖直播:如何使用英飞凌IGBT7设计高性能伺服驱动
- 工程师快乐,所以行业记者快乐!
- 有奖直播:人机互动介面和机器视觉应用上的最佳助手--瑞萨电子 RZ/G, RZ/A 和 RZ/V SoC系列
- 了解设计完整AC-DC系统的快速低风险方法,轻松答题赢好礼
- 有奖直播 | “PCIM Asia 2024” ROHM 展位线上直播
- 答题赢好礼|TI 工业参考设计精选