您的位置:首页 > 编程语言

A-D和D-A和温度传感器DS18B20+C51代码具体实现

2017-12-29 21:01 309 查看

一、A/D,D/A

A/D,D/A概念

A/D:把模拟量转化为数字量;

D/A:把数字量转化为模拟量。

A/D转换指标

转换时间:完成一次A/D转化主要的时间t.1/t为转化速率

分辨率: 衡量A/D转换器能分辨出输入模拟量最小变化程度的技术指标。取决于A/D转换器的位数。

量化误差:由于有限位数字量对模拟量进行量化而引起的误差,量化误差理论上规定单位分辨率的 正负1/2LSB。

转换精度:实际A/D转换器和理论转换器在量化值上的差值。

逐次逼近寄存器型(SAR) ADC

Vin 为输入采样电压,VDAC为设为VREF的一半,VREF为基准电压。当Vin>VDAC,out = 1,MSB =1; Vin<VDAC,out = 0,MSB = 0。N为转换结果存在寄存器中。



例子



A/D转换流程

控制ADC开始转换-》得知转换结果-》输入转换结果

XPT2046使用。

二、单总线系统的典型应用-DS18B20的温度测量系统

DS1820温度传感器

采集方式:现场温度的测量直接通过“单总线”以数字方式传输,不用单片机进行A/D转换。



第一和第二字节存放转换好的温度,低8位在前面,高八位在后。

TH和TL,用户写入的上下限报警值

配置是一个配置寄存器

第6-8字节都为1,未使用

CRC是前面八字节的CRC码

配置寄存器

TM为0,不可更改

R1和R0用来设置分辨率,分辨率越大,转换速率越慢。



数据处理



以补码形式存在。前五位为符号位。要判断是否为负数,要取反+1。

工作时序

三个时序,初始化、写、读时序。



命令



三、代码解析和温度采集流程

DS18B20温度传感器采集流程。写入温度转换命令->写入温度读取命令->读取温度

模块设计

uchar Ds18b20Init()。初始化

void Ds18b20WriteByte(uchar dat)。向DS18B20写入1字节命令

uchar Ds18b20ReadByte()。向DSB20读取1字节数据

void Ds18b20ChangTemp()。写入温度转换命令

void Ds18b20ReadTempCom()。写入读取温度命令

int Ds18b20ReadTemp()。读取温度数据(核心)

datapros(int temp) 。输出最终温度值

初始化uchar Ds18b20Init(),先拉低电480~960us ,然后释放总线,等待DS应答(<=5ms),输出低电平.

uchar Ds18b20Init()
{
uchar i;
DSPORT = 0;          //拉低480us~960us
i = 70;
while(i--);         //延时
DSPORT = 1;         //释放总线
i = 0;
while(DSPORT)       //等待应答
{
Delay1ms(1);
i++;
if(i>5)//>5ms 初始化失败,返回0
{
return 0;
}

}
return 1;//初始化成功
}


向DS写数据(命令)void Ds18b20WriteByte(uchar dat),拉低电平,从低位写入,延长70us左右。数据右移1位。总线拉高1us.

void Ds18b20WriteByte(uchar dat)
{
uint i, j;
for(j=0; j<8; j++)  //八位依次写入。
{
DSPORT = 0;      //拉低总线
i++;
DSPORT = dat & 0x01;
i=6;
while(i--); //延时70us
DSPORT = 1; //释放总线
dat >>= 1; //总线至少拉高1us
}
}


读取DS数据uchar Ds18b20ReadByte(),拉低电平

uchar Ds18b20ReadByte()
{
uchar byte, bi;
uint i, j;
for(j=8; j>0; j--)
{
DSPORT = 0;//拉低电平
i++;
DSPORT = 1;//释放总线
i++;
i++;            //延时6us等待数据稳定
bi = DSPORT;     //读取数据
byte = (byte >> 1) | (bi << 7); //先读取低位再读取高位,bi向左移七位,byte向右移1位,或        操作
i = 4;      //延时48us左右后继续读取下一位
while(i--);
}
return byte; //返回数据
}


写入温度转换命令void Ds18b20ChangTemp()。 先初始化,延时1ms,写入0xcc指令。跳过ROM 操作命令,因为只用到了一份DS12B20。写入温度转换指令0x44.

void  Ds18b20ChangTemp()
{
Ds18b20Init();
Delay1ms(1);
Ds18b20WriteByte(0xcc);
Ds18b20WriteByte(0x44);
}


写入读取温度命令void Ds18b20ReadTempCom()。先初始化,延时1ms,写入0xcc指令。。跳过ROM操作命令。写入读取温度指令0xBE.

void  Ds18b20ReadTempCom()
{

Ds18b20Init();          //初始化
Delay1ms(1);            //延时1ms
Ds18b20WriteByte(0xcc);  //写入跳过ROM操作命令
Ds18b20WriteByte(0xbe);  //写入温度读取指令
}


温度采集的主函数。写入转换温度命令->写入读取温度命令->读取温度(先读取低八位,后读取高八位)。

int Ds18b20ReadTemp()
{
int temp = 0; //存取温度
uchar tmh, tml; //tml存低八位,tmh高八位
Ds18b20ChangTemp(); //转换温度
Ds18b20ReadTempCom();//写入读取温度命令
tml = Ds18b20ReadByte();//读取低8位
tmh = Ds18b20ReadByte(); //读取高八位
temp = tmh;
temp <<= 8; //左移八位
temp |= tml;
return temp;
}


最终温度数据输出。温度小于0,取反+,1。因为前5位为符号位,所以要右移4位,因为设置精度0.01所以乘以100.+0.5是四舍五入

void datapros(int temp)
{
float tp;
if(temp< 0)    //小于0
{
temp=~temp;
temp=temp+1;
tp=temp;
temp=tp*0.0625*100+0.5; //右移四位,设置精度为0.01,四舍五入
}
else
{
tp=temp;
temp=tp*0.0625*100+0.5;  ¡
}
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: