电工优优今天要和大家分享的单片机相关信息,接下来我将从51单片机学习:DS18B20温度传感器实验这个方面来介绍。
实验名称:DS18B20温度传感器实验接线说明:实验现象:下载程序后,插上DS18B20温度传感器,数码管显示检测的温度值注意事项:注意温度传感器的方向,在接口处我们已经用丝印画了一个凸起,所以只需要将温度传感器对应插入即可***************************************************************************************/#include "public.h"#include "smg.h"#include "ds18b20.h"
/******************************************************************************** 函 数 名 : main* 函数功能 : 主函数* 输 入 : 无* 输 出 : 无*******************************************************************************/void main(){u8 i=0;int temp_value;u8 temp_buf[5];
ds18b20_init();//初始化DS18B20
while(1){i++;if(i%50==0)//间隔一段时间读取温度值,间隔时间要大于温度传感器转换温度时间temp_value=ds18b20_read_temperture()*10;//保留温度值小数后一位if(temp_value<0)//负温度{temp_value=-temp_value;temp_buf[0]=0x40;//显示负号}elsetemp_buf[0]=0x00;//不显示temp_buf[1]=gsmg_code[temp_value/1000];//百位temp_buf[2]=gsmg_code[temp_value%1000/100];//十位temp_buf[3]=gsmg_code[temp_value%1000%100/10]|0x80;//个位+小数点temp_buf[4]=gsmg_code[temp_value%1000%100%10];//小数点后一位smg_display(temp_buf,4);}}
#include "ds18b20.h"#include "intrins.h"
/******************************************************************************** 函 数 名 : ds18b20_reset* 函数功能 : 复位DS18B20* 输 入 : 无* 输 出 : 无*******************************************************************************/void ds18b20_reset(void){DS18B20_PORT=0; //拉低DQdelay_10us(75); //拉低750usDS18B20_PORT=1; //DQ=1delay_10us(2); //20US}
/******************************************************************************** 函 数 名 : ds18b20_check* 函数功能 : 检测DS18B20是否存在* 输 入 : 无* 输 出 : 1:未检测到DS18B20的存在,0:存在*******************************************************************************/u8 ds18b20_check(void){u8 time_temp=0;
while(DS18B20_PORT&&time_temp<20) //等待DQ为低电平{time_temp++;delay_10us(1);}if(time_temp>=20)return 1; //如果超时则强制返回1else time_temp=0;while((!DS18B20_PORT)&&time_temp<20) //等待DQ为高电平{time_temp++;delay_10us(1);}if(time_temp>=20)return 1; //如果超时则强制返回1return 0;}
/******************************************************************************** 函 数 名 : ds18b20_read_bit* 函数功能 : 从DS18B20读取一个位* 输 入 : 无* 输 出 : 1/0*******************************************************************************/u8 ds18b20_read_bit(void){u8 dat=0;DS18B20_PORT=0;_nop_();_nop_();DS18B20_PORT=1;_nop_();_nop_(); //该段时间不能过长,必须在15us内读取数据if(DS18B20_PORT)dat=1; //如果总线上为1则数据dat为1,否则为0else dat=0;delay_10us(5);return dat;}
/******************************************************************************** 函 数 名 : ds18b20_read_byte* 函数功能 : 从DS18B20读取一个字节* 输 入 : 无* 输 出 : 一个字节数据*******************************************************************************/u8 ds18b20_read_byte(void){u8 i=0;u8 dat=0;u8 temp=0;
for(i=0;i<8;i++)//循环8次,每次读取一位,且先读低位再读高位{temp=ds18b20_read_bit();dat=(temp<<7)|(dat>>1);}return dat;}
/******************************************************************************** 函 数 名 : ds18b20_write_byte* 函数功能 : 写一个字节到DS18B20* 输 入 : dat:要写入的字节* 输 出 : 无*******************************************************************************/void ds18b20_write_byte(u8 dat){u8 i=0;u8 temp=0;
for(i=0;i<8;i++)//循环8次,每次写一位,且先写低位再写高位{temp=dat&0x01;//选择低位准备写入dat>>=1;//将次高位移到低位if(temp){DS18B20_PORT=0;_nop_();_nop_();DS18B20_PORT=1;delay_10us(6);}else{DS18B20_PORT=0;delay_10us(6);DS18B20_PORT=1;_nop_();_nop_();}}}
/******************************************************************************** 函 数 名 : ds18b20_start* 函数功能 : 开始温度转换* 输 入 : 无* 输 出 : 无*******************************************************************************/void ds18b20_start(void){ds18b20_reset();//复位ds18b20_check();//检查DS18B20ds18b20_write_byte(0xcc);//SKIP ROMds18b20_write_byte(0x44);//转换命令}
/******************************************************************************** 函 数 名 : ds18b20_init* 函数功能 : 初始化DS18B20的IO口 DQ 同时检测DS的存在* 输 入 : 无* 输 出 : 1:不存在,0:存在*******************************************************************************/u8 ds18b20_init(void){ds18b20_reset();return ds18b20_check();}
/******************************************************************************** 函 数 名 : ds18b20_read_temperture* 函数功能 : 从ds18b20得到温度值* 输 入 : 无* 输 出 : 温度数据*******************************************************************************/float ds18b20_read_temperture(void){float temp;u8 dath=0;u8 datl=0;u16 value=0;
ds18b20_start();//开始转换ds18b20_reset();//复位ds18b20_check();ds18b20_write_byte(0xcc);//SKIP ROMds18b20_write_byte(0xbe);//读存储器
datl=ds18b20_read_byte();//低字节dath=ds18b20_read_byte();//高字节value=(dath<<8)+datl;//合并为16位数据
if((value&0xf800)==0xf800)//判断符号位,负温度{value=(~value)+1; //数据取反再加1temp=value*(-0.0625);//乘以精度}else //正温度{temp=value*0.0625;}return temp;}
#include "smg.h"
//共阴极数码管显示0~F的段码数据u8 gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
/******************************************************************************** 函 数 名 : smg_display* 函数功能 : 动态数码管显示* 输 入 : dat:要显示的数据pos:从左开始第几个位置开始显示,范围1-8* 输 出 : 无*******************************************************************************/void smg_display(u8 dat[],u8 pos){u8 i=0;u8 pos_temp=pos-1;
for(i=pos_temp;i<8;i++){switch(i)//位选{case 0: LSC=1;LSB=1;LSA=1;break;case 1: LSC=1;LSB=1;LSA=0;break;case 2: LSC=1;LSB=0;LSA=1;break;case 3: LSC=1;LSB=0;LSA=0;break;case 4: LSC=0;LSB=1;LSA=1;break;case 5: LSC=0;LSB=1;LSA=0;break;case 6: LSC=0;LSB=0;LSA=1;break;case 7: LSC=0;LSB=0;LSA=0;break;}SMG_A_DP_PORT=dat[i-pos_temp];//传送段选数据delay_10us(100);//延时一段时间,等待显示稳定SMG_A_DP_PORT=0x00;//消音}}
#include "public.h"
/******************************************************************************** 函 数 名 : delay_10us* 函数功能 : 延时函数,ten_us=1时,大约延时10us* 输 入 : ten_us* 输 出 : 无*******************************************************************************/void delay_10us(u16 ten_us){while(ten_us--);}
/******************************************************************************** 函 数 名 : delay_ms* 函数功能 : ms延时函数,ms=1时,大约延时1ms* 输 入 : ms:ms延时时间* 输 出 : 无*******************************************************************************/void delay_ms(u16 ms){u16 i,j;for(i=ms;i>0;i--)for(j=110;j>0;j--);}