编程实现基于单片机的温度测量及显示系统
- 利用开发板上的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}; 分别对应相应的数码管点亮,即位码。 温度传感器的程序有测温的程序,测得的温度通过数码管显示出来。其中使用了延时和中断子程序。 实现结果: 按下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 <reg52.h>
- #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;
- 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);
- }
- }
-
- void SendByte(unsigned char dat)
- {
- SBUF = dat;
- while(!TI);
- TI = 0;
- }
- void main()
- {
- uchar a;
- InitUART();
- Init_Com();
- do
- {
- tmpchange();
-
- for(a=10;a>0;a--)
- { display(tmp(),(tmp()*9/5)+320);
- // delay(200);
- }
- if(s2==0)
- {
- SendByte(A1*10+A2);
- SendStr(".");
- SendByte(A3);
-
- }
- if(s3==0)
- {
- SendByte(A11*10+A21);
- SendStr(".");
- SendByte(A3);
- }
-
- DelayMs(240);//延时循环发送
- DelayMs(240);
- } while(1);
- }
-
- /*------------------------------------------------
- 发送一个字符串
- ------------------------------------------------*/
- void SendStr(unsigned char *s)
- {
- while(*s!='\0')// \0 表示字符串结束标志,
- //通过检测是否字符串末尾
- {
- SendByte(*s);
- s++;
- }
- }
-
- 液晶显示温度程序
- #include <reg52.H>
- #include <intrins.H>
- #include <math.H>
-
- #define uchar unsigned char
- #define uint unsigned int
- sbit dula = P2^6;
- sbit wela = P2^7;
-
- sbit RS = P3^5;
- sbit LCDEN = P3^4;
-
- void delayUs()
- {
- _nop_();
- }
-
- void delayMs(uint a)
- {
- uint i, j;
- for(i = a; i > 0; i--)
- for(j = 100; j > 0; j--);
- }
-
-
- void writeComm(uchar comm)
- {
- RS = 0;
- P0 = comm;
- LCDEN = 1;
- delayUs();
- LCDEN = 0;
- delayMs(1);
- }
-
- //写数据:RS=1, RW=0;
- void writeData(uchar dat)
- {
- RS = 1;
- P0 = dat;
- LCDEN = 1;
- delayUs();
- LCDEN = 0;
- delayMs(1);
- }
-
-
- void init()
- {
-
- dula = wela = 0;
- writeComm(0x38);
- writeComm(0x0c);
- writeComm(0x06);
- writeComm(0x01);
- }
-
- void writeString(uchar * str, uchar length)
- {
- uchar i;
- for(i = 0; i < length; i++)
- {
- writeData(str[i]);
- }
- }
-
- /**//*****************************DS18B20*******************************/
- sbit ds = P2^2;
- void dsInit()
- {
-
- unsigned int i;
- ds = 0;
- i = 100;
- while(i>0) i--;
- ds = 1;
- i = 4;
- while(i>0) i--;
- }
-
- void dsWait()
- {
- unsigned int i;
- while(ds);
- while(~ds);
- i = 4;
- while(i > 0) i--;
- }
-
-
- bit readBit()
- {
- unsigned int i;
- bit b;
- ds = 0;
- i++;
- ds = 1;
- i++; i++;
- b = ds;
- i = 8;
- while(i>0) i--;
- return b;
- }
-
- unsigned char readByte()
- {
- unsigned int i;
- unsigned char j, dat;
- dat = 0;
- for(i=0; i<8; i++)
- {
- j = readBit();
-
- dat = (j << 7) | (dat >> 1);
- }
- return dat;
- }
-
-
- void writeByte(unsigned char dat)
- {
- unsigned int i;
- unsigned char j;
- bit b;
- for(j = 0; j < 8; j++)
- {
- b = dat & 0x01;
- dat >>= 1;
-
- if(b)
- {
- ds = 0; i++; i++;
- ds = 1;
- i = 8; while(i>0) i--;
- }
- else
- {
- ds = 0;
- i = 8; while(i>0) i--;
- ds = 1;
- i++; i++;
- }
- }
- }
-
-
- void sendChangeCmd()
- {
- dsInit();
- dsWait();
- delayMs(1);
- writeByte(0xcc);
- writeByte(0x44);
- }
-
- void sendReadCmd()
- {
- dsInit();
- dsWait();
- delayMs(1);
- writeByte(0xcc);
- writeByte(0xbe);
- }
-
-
- int getTmpValue()
- {
- unsigned int tmpvalue;
- int value;
- float t;
- unsigned char low, high;
- sendReadCmd();
-
- low = readByte();
- high = readByte();
-
- tmpvalue = high;
- tmpvalue <<= 8;
- tmpvalue |= low;
- value = tmpvalue;
-
- \
- t = value * 0.0625;
- \
- value = t * 100 + (value > 0 ? 0.5 : -0.5); //大于0加0.5, 小于0减0.5
- return value;
- }
-
- void display(int v)
- {
- unsigned char count;
- unsigned char datas[] = {0, 0, 0, 0, 0};
- unsigned int tmp = abs(v);
- datas[0] = tmp / 10000;
- datas[1] = tmp % 10000 / 1000;
- datas[2] = tmp % 1000 / 100;
- datas[3] = tmp % 100 / 10;
- datas[4] = tmp % 10;
- writeComm(0xc0+3);
- if(v < 0)
- {
- writeString("- ", 2);
- }
- else
- {
- writeString("+ ", 2);
- }
- if(datas[0] != 0)
- {
- writeData('0'+datas[0]);
- }
- for(count = 1; count != 5; count++)
- {
- writeData('0'+datas[count]);
- if(count == 2)
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
单片机的温度测量及显示系统.docx
(1.66 MB, 下载次数: 70)
|