历史上的今天
今天是:2025年01月21日(星期二)
2020年01月21日 | 编程实现单片机ds18b20温度测量及显示系统
2020-01-21 来源:51hei
利用开发板上的ds18b20传感器测量当前温度,利用数码管输出当前温度值。
实现结果:

测试结果显示当前摄氏温度25.3度。
实现原理:
(1)独立数码管

数码管分为共阳极和共阴极数码管,


通过控制数码管中的8个二极管,来显示数字。
(2)多位共阴数码管和共阳数码管
本项目使用的是6位共阴数码管。
数码管控制主要通过段锁存和位锁存控制显示要显示的数字如温度。段锁存是指6位共阴极数码管段输出端连接锁存器74HC573的输出端,锁存器的输入端连接单片机接口P0。位锁存是指6位数码管位置输出端连接锁存器74HC573的输出端,锁存器的输入端连接单片机接口P0。段锁存器片选端接单片机接口P2.6,位锁存器片选端接单片机接口P2.7。
连接图如下:

程序分析:温度传感器DS18B20接单片机P2.2,段锁存接P2.6,位锁存接P2.7,unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
显示段码值0~9,Unsigned char code table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};
分别对应相应的数码管点亮,即位码。
温度传感器的程序有测温的程序,测得的温度通过数码管显示出来。其中使用了延时和中断子程序。
用液晶屏1602实现温度显示。





利用按键实现摄氏温度和华氏温度的转换,并显示。
实现结果:
按下S2,显示摄氏温度如下

按下S2,显示华氏温度如下

实现原理:
在之前的温度显示模块加入按键功能程序,利用两种温度转换公式华氏温度=(摄氏温度*9/5)+32实现转换。
相关程序如下:
void display(uint temp,uint hstemp) //显示程序
{
if(s2==0)
{
ser=temp/10;
SBUF=ser;
A1=temp/100;
A2t=temp%100;
A2=A2t/10;
A3=A2t%10;
dula=0;
P0=table[A1]; //显示百位
dula=1;
dula=0;
wela=0;
P0=0x7e;
wela=1;
wela=0;
delay(1);
dula=0;
P0=table1[A2]; //显示十位
dula=1;
dula=0;
wela=0;
P0=0x7d;
wela=1;
wela=0;
delay(1);
P0=table[A3]; //显示个位
dula=1;
dula=0;
P0=0x7b;
wela=1;
wela=0;
delay(1);
}
if(s3==0)
{
ser1=hstemp/10;
SBUF=ser1;
A11=hstemp/100;
A21t=hstemp%100;
A21=A21t/10;
A31=A21t%10;
dula=0;
P0=table[A11]; //显示百位
dula=1;
dula=0;
wela=0;
P0=0x7e;
wela=1;
wela=0;
delay(1);
dula=0;
P0=table1[A21]; //显示十位
dula=1;
dula=0;
wela=0;
P0=0x7d;
wela=1;
wela=0;
delay(1);
P0=table[A31]; //显示个位
dula=1;
dula=0;
P0=0x7b;
wela=1;
wela=0;
delay(1);
}
}
程序分析:s2,s3代表按键分别接在单片机P3.4,p3.5上,当按键按下时单片机相应接口显示低电平,松开显示高电平。当检测到S2按下时,显示摄氏温度。当检测到S3按下时,显示华氏温度。主程序如下:
if(s2==0)
{
SendByte(A1*10+A2);
SendStr(".");
SendByte(A3);
}
if(s3==0)
{
SendByte(A11*10+A21);
SendStr(".");
SendByte(A3);
}
利用串口将当前温度值发送至电脑,电脑端利用串口助手进行接收和显示。
实现原理:
连接好串口或者usb转串口至电脑,下载该程序,打开电源, 打开串口调试程序,将波特率设置为9600,无奇偶校验,晶振11.0592MHz,发送和接收使用的格式相同。
串口通讯程序包括串口初始化,输出字节函数,输出字符串函数,主函数。温度传感器测得的温度数值通过串口通讯程序输出显示在电脑上。
实现结果:
当按下S2按键,电脑显示如下:

发送和接收都是16进制,1B=1*16+11*1=27,2E代表小数点,01=1,所以显示温度27.2摄氏度。
当按下S3按键,电脑显示如下:

发送和接收都是16进制,51=5*16+1*1=81,2E代表小数点,03=3,所以显示温度81.3华氏。
单片机源程序如下:
//安装目录下的EXE文件打开后可在电脑上显示当前温度值
#include #define uchar unsigned char #define uint unsigned int sbit DS=P2^2; //define interface uint temp; // variable of temperature uchar flag1; // sign of the result positive or negative sbit dula=P2^6; sbit wela=P2^7; sbit s2=P3^4; sbit s3=P3^5; uchar A1,A2,A2t,A3,ser,A11,A21,A21t,A31,ser1; unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, 0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; unsigned char code table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd, 0x87,0xff,0xef}; void SendStr(unsigned char *s); /*------------------------------------------------ 串口初始化 ------------------------------------------------*/ void InitUART (void) { SCON = 0x50; // SCON: 模式 1, 8-bit UART, 使能接收 TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit 重装 TH1 = 0xFD; // TH1: 重装值 9600 波特率 晶振 11.0592MHz TR1 = 1; // TR1: timer 1 打开 EA = 1; //打开总中断 //ES = 1; //打开串口中断 } void delay(uint count) //delay { uint i; while(count) { i=200; while(i>0) i--; count--; } } void DelayUs2x(unsigned char t) { while(--t); } /*------------------------------------------------ mS延时函数,含有输入参数 unsigned char t,无返回值 unsigned char 是定义无符号字符变量,其值的范围是 0~255 这里使用晶振12M,精确延时请使用汇编 ------------------------------------------------*/ void DelayMs(unsigned char t) { while(t--) { //大致延时1mS DelayUs2x(245); DelayUs2x(245); } } ///////功能:串口初始化,波特率9600,方式1/////// void Init_Com(void) { TMOD = 0x20; PCON = 0x00; SCON = 0x50; TH1 = 0xFd; TL1 = 0xFd; TR1 = 1; } void dsreset(void) //send reset and initialization command { uint i; DS=0; i=103; while(i>0)i--; DS=1; i=4; while(i>0)i--; } bit tmpreadbit(void) //read a bit { uint i; bit dat; DS=0;i++; //i++ for delay DS=1;i++;i++; dat=DS; i=8;while(i>0)i--; return (dat); } uchar tmpread(void) //read a byte date { uchar i,j,dat; dat=0; for(i=1;i<=8;i++) { j=tmpreadbit(); dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里 } return(dat); } void tmpwritebyte(uchar dat) //write a byte to ds18b20 { uint i; uchar j; bit testb; for(j=1;j<=8;j++) { testb=dat&0x01; dat=dat>>1; if(testb) //write 1 { DS=0; i++;i++; DS=1; i=8;while(i>0)i--; } else { DS=0; //write 0 i=8;while(i>0)i--; DS=1; i++;i++; } } } void tmpchange(void) //DS18B20 begin change { dsreset(); delay(1); tmpwritebyte(0xcc); // address all drivers on bus tmpwritebyte(0x44); // initiates a single temperature conversion } uint tmp() //get the temperature { float tt; uchar a,b; dsreset(); delay(1); tmpwritebyte(0xcc); tmpwritebyte(0xbe); a=tmpread(); b=tmpread(); temp=b; temp<<=8; //two byte compose a int variable temp=temp|a; tt=temp*0.0625; temp=tt*10+0.5; return temp; } void readrom() //read the serial { uchar sn1,sn2; dsreset(); delay(1); tmpwritebyte(0x33); sn1=tmpread(); sn2=tmpread(); } void delay10ms() //delay { uchar a,b; for(a=10;a>0;a--) for(b=60;b>0;b--); } void display(uint temp,uint hstemp) //显示程序 { if(s2==0) { ser=temp/10; SBUF=ser; A1=temp/100; A2t=temp%100; A2=A2t/10; A3=A2t%10; dula=0; P0=table[A1]; //显示百位 dula=1; dula=0; wela=0; P0=0x7e; wela=1; wela=0;
史海拾趣
|
__asm__(\"ldw 0(%0), %%r0\" : : \"r\" (addr)); 就这段代码,是从内核中拿来用的。 20 21#define ARCH_HAS_PREFETCH 22static inline void prefetch(const void *addr) 23{ 24 &nbs ...… 查看全部问答> |
|
PLC 西门子 S7-200 PLC经过PID调节,输出变频器的频率控制容器压力。 现在想在升压的过程中,让压力值按照正弦曲线上升,如何编程?请给个思路。… 查看全部问答> |
|
各位大侠帮忙看看这个问题 http://topic.eeworld.net/u/20090210/18/09cb0f9d-cf2c-49c9-a84e-29d981e9a4e9.html … 查看全部问答> |
|
$(\'swf_a8M\').innerHTML=AC_FL_RunContent(\'width\', \'550\', \'height\', \'400\', \'allowNetworking\', \'internal\', \'allowScriptAccess\', \'never\', \'src\', encodeURI(\'http://player.youku.com/player.php/sid/XMjk4NTk3Mjcy/v.sw ...… 查看全部问答> |




