蓝桥杯 模板Template Part7:DS18B20温度传感器

九层妖塔 起于垒土

在这里插入图片描述



改编自国信长天蓝桥杯官方蓝皮书例程,按照自己的习惯进行了补充和修改



【蓝桥杯】—{模块}—{DS18B20温度传感器Part_1}
【蓝桥杯】—{模块}—{DS18B20温度传感器Part_2}


一、基本模板

1、头文件

//-------------------------------------DS18B20温度采集函数---------------------------//
sbit DQ = P1^4;  //单总线接口
extern uint ui_temperature;  //保存温度数据
uint rd_temperature(void);  //DS18B20温度采集函数  

2、改单总线延时函数

官方提供的驱动如下:

//单总线延时函数
void Delay_OneWire(unsigned int t)  //STC89C52RC
{
	while(t--);
}

改为:

//单总线延时函数
void Delay_OneWire(unsigned int t)  
{
	t=t*12;
	while(t--);
}

3、写温度采集函数rd_temperature()

//-------------------------------------DS18B20温度采集函数---------------------------//
uint rd_temperature(void)
{
	uchar low=0,high=0;
    uint Temp = 0 ;
    
	init_ds18b20();        //初始化
	Write_DS18B20(0XCC);   //跳过ROM
	Write_DS18B20(0X44);   //转换温度
		
	init_ds18b20();        //初始化
	Write_DS18B20(0XCC);   //跳过ROM
	Write_DS18B20(0XBE);   //读暂存器
	low  = Read_DS18B20(); //低字节
	high = Read_DS18B20(); //高字节
	
	Temp = (high<<8)+low;
	return Temp;
}

Notes:
 ●读一次温度需要对DS18B20操作两次:转换温度读暂存器
 ●对DS18B20的每次操作包括三步:
  ○初始化
  ○ROM命令
  ○功能命令

 ●常用ROM命令:0XCC 跳过ROM
 ●常用功能命令:0X44 转换温度0XBE 读暂存器


4、温度的读取与显示

 在整个系统中,DS18B20一般只是一个功能部分,而且显示器件只有数码管,所以,温度在数码管上的显示一般由按键控制:按下某个按键,(进入某个状态),数码管才显示温度数值。所以温度的读取函数rd_temperature()再按下某个按键后再进行读取。

进入某个状态放在按键控制层 按键处理函数Key_Proc()中,温度的读取ui_temperature = rd_temperature();放在数码管显示层 数码管处理函数SEG_Proc()中。

//-----------------------------------------数码管处理函数---------------//
void SEG_Proc(void)     //数码管处理函数
{
	if(ui_SEG_flag) return;   //刷新频率
	ui_SEG_flag = 1;
	
    if(uc_Key_Value == 4)
	{
	  ui_temperature = rd_temperature();  //读取温度
		
	  sprintf(puc_SEG_Buf,"%02u  %05.2f",(uint)uc_Key_Value,ui_temperature/16.0);
	}

	SEG_Tran(puc_SEG_Buf,puc_SEG_Code);   //数码管段码转换
}

Notes:
 ●ui_temperature/16.0
  DS18B20配置为12位分辨率,温度数据以16位符号扩展的二进制补码 形式存储在暂存器低两位的温度寄存器中。ui_temperature默认为16位二进制数,又因为温度为正,符号位为0,所以读回来的ui_temperature为11位二进制原码。
  /为除法运算符,被除数/除数。除法运算又分为整数除法和浮点数除法。整数除法小数部分被丢弃,即截断。只要被除数和除数有一个为浮点数即为浮点数除法。
  ui_temperature/16.0 等价于 ui_temperature/0.0625 等价于 ui_temperature* 2 − 4 2^{-4} 24
  ui_temperature定义的为无符号整形,ui_temperature的BIT 0 位的权重为1。对比下表可知,ui_temperature每一个位的权重都比实际大了 2 4 2^{4} 24,所以需要ui_temperature/16.0
在这里插入图片描述

 ●$2^{-4}$ = 0.065

 ●sprinft通过格式控制指定小数位数输出,可以实现四舍五入。

数据输出&格式控制

 ●读取温度时数码管会闪烁的原因:rd_temperature()中的初始化,读写函数中的延时每次虽然是us级别的,但是加起来大约在5、6ms左右。
 可以通过控制数码管的刷新频率,如500ms刷新一次,即500ms执行一次SEG_Proc(),也就是500ms读取一次温度来减弱数码管的闪动。

 ●12位分辨率的精度为0.0625,最大转换时间为750ms。写入Write_DS18B20(0X44);开始温度转换后,就由DS18B20的相关硬件部分去执行温度转换,转换完成后存放在暂存器的低两位字节中;若不进行初始化直接读取时序,如果DS18B20正在温度转换过程中则返回0来响应,若转换完成则返回1。主机可以对DS18B20进行其他操作,由DS18B20的其他硬件部分响应;主机若对DS18B20进行其他操作,必须由初始化开始。
 在执行第二个初始化时,转换温度的命令已经写入DS18B20,虽然温度还未转换完成,但是单总线已经空闲,可以继续执行下边几乎不耗时的读暂存器命令。所以在上电之初,会出现短暂的85初始值。

5、温度传感器DS18B20上电初始值为85的消除方法

方法1:在数码管处理函数中:

if( (ui_temperature/16.0) == 85.0)
	sprintf(puc_SEG_Buf,"        "); 
else
   sprintf(puc_SEG_Buf,"C     %02.0f",(float)ui_temperature/16.0);

方法2:在死循环之前:

uchar puc_SEG_Code[8]= {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};

void main(void)
{
  Init();
  Timer1Init();
  UartInit();

  temperature = rd_temperature()/16.0;
  while(temperature == 85.0)
  {
    temperature = rd_temperature()/16.0;
  }
  
  //最后开中断
  ET1 = 1;
  EA = 1;
	
 while(1)
 {
 ……
 ……

方法3:在死循环之前直接先读取一次温度,之后直接软件延时750ms,虽然简单,却是最没有bug的方法。

ui_temperature = rd_temperature();
Delay750ms();	
ui_temperature = rd_temperature();

浮点数的比较



二、备用拓展模板

1、分辨率的更改

选项12位分辨率11位分辨率10位分辨率9位分辨率
小数部分位数4位3位2位1位
分辨率1/16 = 0.06251/8 = 0.1251/4 = 0.251/2 = 0.5
最大转换时间750ms375ms187.5ms93.75ms
配置寄存器0x7f0x5f0x3f0x1f
void DS18B20_Set_Reso(uchar Reso)
{
	
	//12位分辨率 0111 1111  7f
	//11位分辨率            5f
	//10位分辨率            3f
    //9位分辨率             1f
    init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0X4E);   //写暂存器 
	
	Write_DS18B20(0x00);   //写TH
	Write_DS18B20(0x00);   //写TL
	Write_DS18B20(Reso);   //配置寄存器
}

  
  
  
  
彩 蛋

  • 3
    点赞
  • 0
    评论
  • 4
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

打赏
文章很值,打赏犒劳作者一下
相关推荐
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页

打赏

#法外狂徒张三

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者