历史上的今天
今天是:2024年11月28日(星期四)
2019年11月28日 | 使用AVR来驱动MAXIN的DS18B20
2019-11-28 来源:51hei
我最近正在研究使用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
史海拾趣
|
对于中国人来说,姗姗来迟的3G时代究竟是如何的欣欣向荣,现在我们还只能忐忑不安地憧憬着。但是,在这山雨欲来的时刻,3G的IP承载网对于运营商来说,都已经是“风满楼”的状态,几乎触手可及了。 不管是中 ...… 查看全部问答> |
|
请问各位大侠,本人有一个很棘手的问题请教。我在wince下用openssl命令想要生成一个ca.crt文件,命令如下: \"X509 -req -in \\\"\\\\wince_192.168.6.200_own.csr\\\" -out \\\"\\\\wince_192.168.6.200_ca.crt\\\" -signkey \\\"\\\\wince_192.1 ...… 查看全部问答> |
|
今天遇到一个奇怪的问题:用QuartusII仿真的时候,波形图总是不会出现时钟,就只有电平而已,但是程序确定无误是设定了时钟类型的,仿真的时候也设定了,但就是仿真不了!到底是什么问题呢??… 查看全部问答> |
|
昨晚我花了不少时间,做了一系列关于开销的测试。 我们可以得出一个我们很关心的结论: 那就是,相比于平常的直接调用变量和函数。 采用指针,乃至通过结构体引用,相比而言,多出来的 时间开销并不是十分大,大多数情况下,不足以成为影响效率 ...… 查看全部问答> |




