单片机应用实例一个液晶显示的数字式电脑温度计
51单片机的液晶显示温度计程序

51单片机的液晶显示温度计程序51单片机的液晶显示温度计程序#include<reg51.h>#include <intrins.h>sbit RST = P2^0;sbit CLK = P2^1;sbit DQ = P2^2;sbit TSOR = P2^3;sbit ALERT =P2^4;sbit RS = P2^7;sbit RW = P2^6;sbit EN = P2^5;/*------------------------------------------全局变量-------------------------------------------------------*/static unsigned char temp1,temp2; //温度值的整数部分、小数部分static unsigned char pos,posset; //数字电位器电位值、设定值static unsigned char min,sec; //分钟、秒static unsigned char count; //Timer0中断计数static unsigned char minset; //设定的分钟数static unsigned char status1,status2; //状态标志bit stop,timeover; //定时停止、结束static char line0[] =" 00:00 ";static char line1[] =" . CW";/*-------------------------------------------------------------------------------------------------------------*/void InitInterupt();void KeyboardDelay();/*-------------------------------------------LCD驱动函数------------------------------------------------*/void DelayL();void DelayS();void WriteCommand(unsigned char c);void WriteData(unsigned char c);void ShowChar(unsigned char pos,unsigned char c); void ShowString(unsigned char line,char *ptr);void InitLcd();/*----------------------------------------------键盘-程序--------------------------------------------------*/unsigned char GetKey();/*---------------------------------------------数字温度计驱动-------------------------------------------*/void ChangePos(bit sel,unsigned char pos1,unsigned char pos2);/*------------------------------------------温度传感器驱动----------------------------------------------*/void Delay15();void Delay60();void Delay100ms();void Write0TS();void Write1TS();bit ReadTS();void ResetTS();void WriteByteTS(unsigned char byte); unsigned char ReadByteTS();void InitTS();void GetTempTS();/*-------------------------------------------------主程序---------------------------------------------------*/void main (void) {char code str1[] =" Hello World! ";char code str2[] =" 2002-10-20 "; unsigned char i; SP=0x50;ALERT=0; //报警灯灭TSOR=1; //1-wire总线释放DelayL();InitLcd(); //初始化LCDDelayL();ShowString(0,str1); //启动画面ShowString(1,str2);for(i=0;i<15;i++)Delay100ms();InitInterupt(); //初始化中断设置minset=10; //缺省定时10分钟posset=0; //缺省电位器值0min=minset; //初始化数据pos=posset;sec=0;count=0;P1=0xF0;status1=0;status2=0;stop=1;timeover=0; ChangePos(0,255-pos,255-pos); //设置电位器InitTS(); //初始化温度计while(1) //循环显示温度值{GetTempTS();line1[0]=0x20;i=temp1;if(i>39) //超过40摄氏度,告警灯亮ALERT=1;if(i>99) //超过100摄氏度,显示温度的百位{line1[0]=0x31;i-=100;}line1[1]=i/10+0x30; //显示温度的十位line1[2]=i%10+0x30; //显示个位line1[4]=temp2+0x30; //显示小数位if(timeover) //若定时结束,则电位器缓慢复0{for(;pos>0;pos--){ChangePos(0,255-pos,255-pos);_nop_();_nop_();}timeover=0;posset=0;}if(pos>posset) //若按键修改电位器位置{for(;pos>posset;pos--) //则缓变到设定值{ChangePos(0,255-pos,255-pos);_nop_();_nop_();}ChangePos(0,255-pos,255-pos);}else if(pos<posset){for(;pos<posset;pos++){ChangePos(0,255-pos,255-pos);_nop_();_nop_();}ChangePos(0,255-pos,255-pos);}i=pos;line1[9]=0x20; //显示电位器等级值if(i>99){line1[9]=i/100+0x30;i=i%100;}line1[10]=i/10+0x30;line1[11]=i%10+0x30;ShowString(1,line1);line0[5]=min/10+0x30; //显示时间line0[6]=min%10+0x30;line0[8]=sec/10+0x30;line0[9]=sec%10+0x30;ShowString(0,line0);Delay100ms();}}void InitInterupt(){TMOD=0x21; //初始化中断设置TL1=0xFD;TH1=0xFD;PX0=1;EA=1;ES=1;PCON=0;TR1=1;SCON=0x50;TL0=0x00; //定时0.05mTH0=0x4C;ET0=1; EX0=1;IT0=1;}void KeyboardDelay() //按键中断延时{unsigned char i,j;i=0x40;j=0xFF;while(i--)while(j--);}/*--------------------------------------------中断处理-----------------------------------------------------*/Int0_process() interrupt 0 using 0{unsigned char key;unsigned char keycode[]= "TP";unsigned char step[3]={1,2,5};EA=0;key=GetKey(); //获得按键值switch(key){case 0:stop=!stop;min=minset;sec=0;break;case 1:case 2:case 3:if(stop){minset+=step[key-1];if(minset>60)minset=0;min=minset;}break;case 5:case 6:case 7:if(stop){minset-=step[key-5]; if(minset>60) minset=0;min=minset;}break;case 9:case 10:case 11:posset+=step[key-9];break;case 13:case 14:case 15:posset-=step[key-13];break;default:break;}TR0=!stop;KeyboardDelay();P1=0xF0;EA=1;}Timer0_process() interrupt 1 using 0{EA=0;TR0=0;TL0=0x00;TH0=0x4C;count++;if(count==20) //如果到累计定时到达1s {if(sec==0) //定时处理{if(min==0) //总定时到,则置结束标志timeover=1;else{min--;sec=59;}}elsesec--;count=0;}TR0=1;EA=1;}/*--------------------------------------LCD驱动子程序--------------------------------------------------*/void DelayL(){unsigned char i,j;i=0xF0;j=0xFF;while(i--)while(j--);}void DelayS(){unsigned char i;i=0x1F;while(i--);}void WriteCommand(unsigned char c) {DelayS();EN=0;RS=0;RW=0;_nop_();EN=1;P0=c;EN=0;}void WriteData(unsigned char c){DelayS();EN=0;RS=1;RW=0;_nop_();EN=1;P0=c;EN=0;RS=0;}void ShowChar(unsigned char pos,unsigned char c) {unsigned char p;if(pos>=0x10)p=pos+0xB0;elsep=pos+0x80;WriteCommand(p);WriteData(c);}void ShowString(unsigned char line,char *ptr){unsigned char l,i;l=line<<4;for(i=0;i<16;i++)ShowChar(l++,*(ptr+i));} void InitLcd(){DelayL();WriteCommand(0x38);WriteCommand(0x38);WriteCommand(0x06);WriteCommand(0x0C);WriteCommand(0x01);WriteCommand(0x80);}/*---------------------------------------------键盘子程序-------------------------------------------------*/ unsigned char GetKey(){unsigned k,t,i,j;k=P1;k=k&0xF0;i=0;while((k&0x10)&&i<4) {i++;k=k>>1;}k=0x01;j=0;while(j<4){P1=0xFF^k;_nop_();t=P1;t=t^0xFF;t=t&0xF0;if(t)break;j++;k=k<<1;}k=j*4+i;return k;}/*-----------------------------------------数字温度计驱动子程序--------------------------------------*/void ChangePos(bit sel,unsigned char pos1,unsigned char pos2){ unsigned char i;RST=0;DQ=0;CLK=0;RST=1;DQ=sel;_nop_();CLK=1;_nop_();CLK=0;for(i=0;i<8;i++) {if(pos1&0x80)DQ=1;elseDQ=0;_nop_();CLK=1;_nop_();CLK=0;pos1=pos1<<1; }for(i=0;i<8;i++) {if(pos2&0x80)DQ=1;elseDQ=0;_nop_();CLK=1;_nop_();CLK=0;pos2=pos2<<1;}RST=0;}/*------------------------------------------温度传感器子程序-------------------------------------------*/void Delay100ms() //延时100ms {unsigned char i,j,k;for(i=0;i<8;i++)for(j=0;j<25;j++)for(k=0;k<250;k++);}void Delay15() //延时15us{unsigned char i;for(i=0;i<8;i++);}void Delay60() //延时60us{unsigned char i;for(i=0;i<30;i++);}void Write0TS() //写bit 0 {TSOR=1;TSOR=0;Delay15();Delay15();Delay15();Delay15();TSOR=1;_nop_();_nop_();}void Write1TS() //写bit 1 {TSOR=1;TSOR=0;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();TSOR=1;_nop_(); _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();Delay15();Delay15();Delay15(); }bit ReadTS() {bit b;TSOR=1;TSOR=0; _nop_();_nop_();_nop_();_nop_();TSOR=1;_nop_();_nop_();_nop_();_nop_();_nop_();b=TSOR;Delay15();Delay15();Delay15();_nop_();_nop_();return b;}void ResetTS() //复位{unsigned char i; TSOR=1;TSOR=0;for(i=0;i<8;i++)Delay60();TSOR=1;while(TSOR);for(i=0;i<8;i++)Delay60();}void WriteByteTS(unsigned char byte) //写一个字节(byte){unsigned char i;for(i=0;i<8;i++){if(byte&0x01)Write1TS();elseWrite0TS();byte=byte>>1;}}unsigned char ReadByteTS() //读一个字节(byte){unsigned char i,j;bit b;j=0;for(i=0;i<8;i++){b=ReadTS();if(b)j+=1;j=_cror_(j,1);}return j;}void InitTS() //初始化温度转换{ResetTS();WriteByteTS(0xCC);WriteByteTS(0x4E);WriteByteTS(0x64);WriteByteTS(0x8A);WriteByteTS(0x1F);}void GetTempTS() //获取温度{ResetTS();WriteByteTS(0xCC);WriteByteTS(0x44);Delay100ms();ResetTS();WriteByteTS(0xCC);WriteByteTS(0xBE);temp2=ReadByteTS();temp1=ReadByteTS();ReadByteTS();ReadByteTS();ReadByteTS();ReadByteTS();ReadByteTS();ReadByteTS();ReadByteTS();temp1=temp1<<4;temp1+=(temp2&0xF0)>>4;temp2=(temp2&0x0F)?5:0;}液晶显示温度计程序。
基于单片机的温度计设计程序(液晶)

/*-----------------------------------------------名称:18B20温度测量报警内容:在LCD1602第一行可以显示当前温度,第二行显示设定的温度区间,超过此温度区间,蜂鸣器报警。
温度区间可以通过用户按键设置------------------------------------------------*/#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义#include<math.h>#include<INTRINS.H>#define uchar unsigned char#define uint unsigned int/******************************************************************//* 定义端口*//******************************************************************/sbit led1=P1^0;// 温度超出范围指示灯sbit led2=P1^1;sbit buzzer=P1^3;//蜂鸣器引脚sbit DQ=P1^4;//ds18b20 端口sbit RS = P2^4;//1602数据/命令选择端(H:数据寄存器L:指令寄存器)sbit RW = P2^5;//1602读/写选择端sbit E = P2^6;//1602使能信号端sbit key1=P3^4;//用户按键sbit key2=P3^5;sbit key3=P3^6;sbit key4=P3^7;/******************************************************************//* 全局变量*//******************************************************************/int temp;//测得温度char temp_max=40,temp_min=10;//设定的温度char TempH,TempL;uchar flag_get,num=0;uchar code tab[]={'0','1','2','3','4','5','6','7','8','9'};//液晶显示uchar tab1[]="min:010 max:040";//液晶第二行显示内容uchar str[8];/******************************************************************//* 延时函数*//******************************************************************/void delay1(uint i)//短延时函数{while(i--);}void delay(uint z) //长延时函数{uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}/******************************************************************/ /* DS18B20 初始化*/ /******************************************************************/ void Init_DS18B20(void){uchar x=0;DQ = 0; //单片机将DQ拉低delay1(480); //精确延时大于480usDQ = 1; //拉高总线,等待delay1(10);x=DQ; //稍做延时后如果x=0则初始化成功x=1则初始化失败delay1(5);}/******************************************************************/ /* DS18B20读一个字节*/ /******************************************************************/ uchar ReadOneChar(void) // DS18B20读一个字节{uchar i=0;uchar dat = 0;for (i=8;i>0;i--){DQ = 0; // 给脉冲信号dat>>=1;DQ = 1; // 给脉冲信号,主机在读时隙期间必须释放总线if(DQ)dat|=0x80;delay1(5);}return(dat);}/******************************************************************//* DS18B20写一个字节*//******************************************************************/void WriteOneChar(uchar dat) //DS18B20写一个字节{uchar i=0;for (i=8; i>0; i--){DQ = 0;DQ = dat&0x01;//取最低位delay1(5);DQ = 1;dat>>=1;//左移}delay1(5);}/******************************************************************//* DS18B20读取温度*//******************************************************************/uint ReadTemperature(void) //DS18B20读取温度{uchar a=0;uint b=0;uint t=0;Init_DS18B20();//DS18B20初始化WriteOneChar(0xCC); // 跳过读序号列号的操作WriteOneChar(0x44); // 启动温度转换delay1(200); //延时以求信号的稳定Init_DS18B20(); //DS18B20再次初始化WriteOneChar(0xCC); //跳过读序号列号的操作WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器)前两个就是温度a=ReadOneChar(); //低位b=ReadOneChar(); //高位b<<=8; //b左移8位t=a+b; //把a与b结合,放在16位的t中return(t);}/******************************************************************//* LCD1602写命令操作*//******************************************************************/void WriteCommand(uchar com){delay(5);//操作前短暂延时,保证信号稳定E=0;RS=0;RW=0;P0=com;E=1;delay(5);E=0;}/******************************************************************/ /* LCD1602写数据操作*/ /******************************************************************/ void WriteData(uchar dat){delay(5); //操作前短暂延时,保证信号稳定E=0;RS=1;RW=0;P0=dat;E=1;delay(5);E=0;}/******************************************************************/ /* LCD1602初始化程序*/ /******************************************************************/ void InitLcd(){uchar i;delay(15);WriteCommand(0x38); //display modeWriteCommand(0x38); //display modeWriteCommand(0x38); //display modeWriteCommand(0x06); //显示光标移动位置WriteCommand(0x0c); //显示开及光标设置WriteCommand(0x01); //显示清屏WriteCommand(0x80+0x40);//将光标移到第二行for(i=0;i<16;i++)//显示初始化内容{WriteData(tab1[i]);delay(10);}}/******************************************************************/ /* 蜂鸣器报警程序*/ /******************************************************************/ void alarm(){if(TempH>=temp_max)//当温度高于设置的最高温报警{ buzzer=0;delay(50);buzzer=1;delay(50);led1=0;led2=1;}else if(TempH<temp_min)//当温度低于设置的最低温报警{buzzer=0;delay(50);buzzer=1;delay(50);led1=1;led2=0;}else//报警解除{buzzer=1;led1=1;led2=1;}}/******************************************************************/ /* 显示测得的温度*/ /******************************************************************/ void handle_T(){uchar i;str[0]=0x20;//显示为空str[1]=tab[TempH/100]; //百位温度str[2]=tab[(TempH%100)/10]; //十位温度str[3]=tab[(TempH%100)%10]; //个位温度,带小数点str[5]=tab[TempL];str[4]='.';str[6]=0xdf;str[7]='C';if(flag_get==1) //定时读取当前温度{flag_get=0; //清标志位temp=ReadTemperature();//读取温度值if(temp&0x8000){str[0]=0xb0;//负号标志temp=~temp; // 取反加1temp +=1;}TempH=temp>>4; //由权重表知移4位就是整数位TempL=temp&0x0F;TempL=TempL*6/10;//小数近似处理alarm(); //判断是否需要报警}WriteCommand(0x80+0x04);//光标指向第一行第一个字符for(i=0;i<8;i++)// 显示{WriteData(str[i]);delay(10);}}void display_range(uchar add,int t){uchar i;if(t<0){str[0]=0xb0;//负号标志}elsestr[0]=tab[abs(t)/100]; //百位温度str[1]=tab[(abs(t)%100)/10]; //十位温度str[2]=tab[(abs(t)%100)%10]; //个位温度WriteCommand(0x80+0x40+add);for(i=0;i<3;i++){WriteData(str[i]);delay(5);}}/******************************************************************/ /* 独立键盘扫描函数并显示设定的温度*/ /******************************************************************/ void keyscan(){uchar flag1=0,flag2=0;//有按键按下标记P3=0xff;//拉高P3口,以读取P3口的值if(key4==0)//最高温加{delay(5);//延时消抖if(key4==0){temp_max++;if(temp_max>=85)temp_max=85;}while(!key4);//松手检测flag1=1;}if(key3==0)//最高温减{delay(5);if(key3==0){temp_max--;if(temp_max<=temp_min)temp_max=temp_min;}while(!key3);flag1=1;}if(key2==0)//最低温加{delay(5);//延时消抖if(key2==0){temp_min++;if(temp_min>=temp_max)temp_min=temp_max;}while(!key2);//松手检测flag2=1;}if(key1==0)//最低温减{delay(5);if(key1==0){temp_min--;if(temp_min<=-10)temp_min=-10;}while(!key1);flag2=1;}if(flag1)//如有设置最高温度的键按下,更新设定的温度{flag1=0;// 清标记display_range(0x0d,temp_max);}if(flag2)//如有设置最低温度的键按下,更新设定的温度{flag2=0;// 清标记display_range(0x04,temp_min);}}/****************************************************************/ /* 主函数*/ /******************************************************************/ void main(){TMOD|=0x01;//定时器设置TH0=0xef;//装初始值TL0=0xf0;EA=1;// 开总中断ET0=1;//允许定时器0中断TR0=1;//开定时器0中断InitLcd();//lcd1602初始化flag_get=1;while(1){handle_T();// 处理温度:获得、显示、报警keyscan(); //独立按键扫描}}/******************************************************************/ /* 定时0中断处理程序,用于温度检测间隔,大约1秒测一次温度*/ /******************************************************************/ void timer0(void) interrupt 1 using 1{TH0=0xef;//定时器重装值TL0=0xf0;num++;if (num==50){num=0;flag_get=1;//标志位有效,开始测温}}。
51单片机数字温度计设计与应用

51单片机数字温度计设计与应用数字温度计在现代生活中有着广泛的应用,它能够将环境温度转换为数字信号,提供直观、准确的温度数据。
本文将介绍基于51单片机的数字温度计的设计与应用。
设计思路:1. 硬件设计首先,我们需要选取一个合适的温度传感器,例如DS18B20。
该传感器具有高精度、数字输出、带有内部校准和非易失性存储器等特点,非常适合作为数字温度计的传感器。
其次,我们需要引入一个51单片机,常用的有AT89C51、AT89S52等。
单片机负责控制传感器和显示器,并处理温度数据。
接下来,我们需要一个LED数码管或液晶显示屏作为温度显示器。
数码管简单且易于操作,而液晶显示屏可以提供更多的信息显示。
最后,我们还需添加一些辅助电路,如稳压电路、时钟电路等,以确保正常的运行。
2. 软件设计在单片机的程序设计方面,我们需要考虑以下几个步骤:(1)初始化各个引脚和外部设备,如温度传感器和显示屏。
(2)读取温度传感器输出的数字信号,通过数据线将其与单片机相连。
(3)通过一系列算法将数字信号转换为实际的温度值。
因为DS18B20传感器提供数字输出,所以支持该类算法的编程非常简单。
(4)将计算得到的温度值通过数码管或液晶显示屏进行显示。
如果是数码管,可以通过数码管驱动芯片来实现多位数的显示。
(5)可选的增加报警功能,当温度超过一定阈值时,触发报警。
应用场景:数字温度计可以在许多场景中应用,下面介绍几个常见的应用场景:1. 家庭温度监测在家庭中,我们可以将数字温度计放置在客厅、卧室等常用区域,用于监测室内温度。
通过数字温度计,我们可以实时了解室内的温度状况,根据需要进行调节,提供舒适的生活环境。
2. 温室控制在温室种植中,保持适宜的温度对于植物的生长至关重要。
数字温度计可以帮助种植者实时监测温室内的温度,并及时采取相应的措施,维持温室内的温度在适宜的范围内。
3. 实验室温度监测实验室需要严格控制温度,以确保实验的准确性和稳定性。
基于51单片机的数字温度计

引言:数字温度计是一种基于51单片机的温度测量装置,它通过传感器感知环境的温度,并使用单片机将温度值转换为数字形式,并显示在液晶屏上。
本文将详细介绍数字温度计的设计原理、硬件连接、软件编程以及应用领域。
概述:数字温度计基于51单片机的设计理念,其基本原理是通过传感器将温度转换为电信号,然后通过ADC(模数转换器)将电信号转换为数字信号,最后使用单片机将数字信号转换为温度值。
同时,数字温度计还将温度值显示在液晶屏上,方便用户直观地了解环境温度。
正文内容:1. 硬件连接:1.1 使用温度传感器感知环境温度:常用的温度传感器有NTC热敏电阻和DS18B20数字温度传感器。
通过将传感器连接到51单片机的引脚上,可以实现对环境温度的感知。
1.2 连接ADC进行模数转换:ADC是将模拟信号转换为数字信号的关键部件。
通过将51单片机的引脚连接到ADC芯片的输入端,可以将模拟的温度信号转换为数字信号。
1.3 连接液晶屏显示温度值:通过将51单片机的引脚连接到液晶屏的控制引脚和数据引脚,可以将温度值以数字形式显示在液晶屏上。
2. 软件编程:2.1 初始化引脚和ADC:在软件编程中,需要初始化51单片机的引脚设置和ADC的工作模式。
通过设置引脚为输入或输出,以及设置ADC的参考电压和工作模式,可以确保硬件正常工作。
2.2 温度测量算法:根据传感器的工作原理和电压-温度特性曲线,可以编写相应的算法将ADC测得的电压值转换为温度值。
例如,对于NTC热敏电阻,可以使用Steinhart-Hart公式进行温度计算。
2.3 温度值显示:将温度值以数字形式显示在液晶屏上。
通过设置液晶屏的控制引脚和数据引脚,可以控制液晶屏的显示内容,并将温度值以数字形式显示在屏幕上。
3. 基于51单片机的数字温度计应用:3.1 家庭温度监测:数字温度计可以安装在家庭中的不同区域,实时监测室内温度,并通过数字显示提供直观的温度信息。
这对于家庭的舒适性和节能都有重要意义。
基于51单片机的数字温度计

基于AT89S51的温度计院系:电子和信息工程学院专业:电子信息科学和技术班级:09信本学生姓名:刘辉学号:093621059第一部分 设计要求:采用AT89C51单片机和LCD 液晶显示器设计一个数字温度计,当外界温度变化时,显示屏上的温度值也随着变化。
数字温度计的测温范围为-55°C 到125°C 之间。
第二部分 硬件原理框图:硬件部分主要分为晶振振荡电路、复位电路、LCD 液晶显示电路、DS18B20温度传感器采集电路、电源电路等部分组成。
第三部分 硬件原理图:硬件模块原理图:AT89C51单片机晶振振荡电路 复位电路 L CD 液晶显示电路温度传感器采集电路电 源 电 路一、晶振振荡电路该电路是由两个电容和一个晶振组成,晶振产生基本的时钟信号它给单片机提供时钟信号。
二、复位电路复位的主要作用是把特殊功能寄存器的数据刷新为默认数据,单片机在运算过程中由于干扰等外界原因造成寄存器中数据混乱不能使其正常继续执行程序或产生的结果不正确时均需要复位,以使程序重新开始运行。
三、LCD液晶显示电路经过温度传感器,将采集到的温度信息传给单片机,单片机处理后又将信息发给P0口,P0口和LCD的数据口相连接,液晶屏上会显示采集到的温度值。
四、温度传感器采集电路单线数字温度传感器DS18B20测量温度范围为-55°C~+125°C,-10~+85°C范围内,精度为±0.5°C。
DS1822的精度较差为± 2°C 。
DS18B20的管脚排列如下: DQ 为数字信号输入/输出端;GND 为电源地;VDD 为外接供电电源输入端(在寄生电源接线方式时接地)。
根据DS18B20的通讯协议,主机控制DS18B20完成温度转换必须经过三个步骤:每一次读写之前都要对DS18B20进行复位,复位成功后发送一条ROM 指令,最后发送RAM 指令,这样才能对DS18B20进行预定的操作。
51单片机数字温度计的设计与实现

51单片机数字温度计的设计与实现温度计是一种广泛使用的电子测量仪器,它能够通过感知温度的变化来提供精准的温度数值。
本文将介绍如何使用51单片机设计并实现一款数字温度计。
一、硬件设计1. 采集温度传感器温度传感器是用来感知环境温度的关键器件。
常见的温度传感器有DS18B20、LM35等。
在本次设计中,我们选择DS18B20温度传感器。
通过电路连接将温度传感器与51单片机相连,使51单片机能够读取温度传感器的数值。
2. 单片机选型与连接选择适合的51单片机型号,并根据其引脚功能图对单片机进行合理的引脚连接。
确保温度传感器与单片机之间的数据传输通畅,同时保证电源和地线的正确连接。
3. 显示模块选型与连接选择合适的数字显示模块,如数码管、液晶显示屏等。
将显示模块与51单片机相连,使温度数值能够通过显示模块展示出来。
4. 电源供应为电路提供稳定的电源,保证整个系统的正常运行。
选择合适的电源模块,并根据其规格连接电路。
二、软件设计1. 温度传感器读取程序编写程序代码,使用单片机GPIO口将温度传感器与单片机连接,并通过相应的通信协议读取温度数值。
例如,DS18B20采用一线制通信协议,需要使用单总线协议来读取温度数值。
2. 数字显示模块驱动程序编写程序代码,通过单片机的GPIO口控制数字显示模块的数码管或液晶显示屏进行温度数值显示。
根据显示模块的规格,编写合适的驱动程序。
3. 温度转换算法将温度传感器读取到的模拟数值转换为实际温度数值。
以DS18B20为例,它输出的温度数值是一个16位带符号的数,需要进行相应的转换操作才能得到实际的温度数值。
4. 系统控制程序整合以上各部分代码,编写系统控制程序。
该程序通过循环读取温度数值并进行数据处理,然后将处理后的数据送到数字显示模块进行实时显示。
三、实现步骤1. 硬件连接按照前文所述的硬件设计,将温度传感器、51单片机和数字显示模块进行正确的连接。
确保连接无误,并进行必要的电源接入。
51单片机程序(数字温度计)

数字温度计1、LCD.c#include <reg51.h>#include<LCD.h>unsigned char code number_X[]={ //宽x高=8x16,纵向字节倒序0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00, //00x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00, //10x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00, //20x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00, //30x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00, //40x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00, //50x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00, //60x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00, //70x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00, //80x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00, //90x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // .0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00, //-0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //nop 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00, //:0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00};void LCD_WriteCommandE1(unsigned char com) {while(CRADD1 & 0x80);CWADD1 = com;}void LCD_WriteDataE1(unsigned char dat)while(CRADD1 & 0x80);DWADD1 = dat;}void LCD_WriteCommandE2(unsigned char com) {while(CRADD2 & 0x80);CWADD2 = com;}void LCD_WriteDataE2(unsigned char dat){while(CRADD2 & 0x80);DWADD2 = dat;}void LCD_Init(){LCD_WriteCommandE1(0xe2);LCD_WriteCommandE2(0xe2);LCD_WriteCommandE1(0xa4);LCD_WriteCommandE2(0xa4);LCD_WriteCommandE1(0xa9);LCD_WriteCommandE2(0xa9);LCD_WriteCommandE1(0xa0);LCD_WriteCommandE2(0xa0);LCD_WriteCommandE1(0xc0);LCD_WriteCommandE2(0xc0);LCD_WriteCommandE1(0xaf);LCD_WriteCommandE2(0xaf);}void LCD_Clear(void){unsigned char i,j;for(i=0;i<4;i++){LCD_WriteCommandE1(i+0xb8);LCD_WriteCommandE2(i+0xb8);LCD_WriteCommandE1(0x00);LCD_WriteCommandE2(0x00);for(j=0;j<0x50;j++){LCD_WriteDataE1(0x00);LCD_WriteDataE2(0x00);}}void display_cn(unsigned char lin,unsigned int col,unsigned int len,unsigned char *p) {unsigned int seg,i,j;unsigned char a,L,n;switch(lin){case 0: n=0xba;break;case 1: n=0xb8;break;}for(i=0;i<len;i++){for(j=0;j<2;j++){L=col;LCD_WriteCommandE1(n+j);LCD_WriteCommandE2(n+j);for(seg=0;seg<16;seg++){if (L < 61){a = L;LCD_WriteCommandE1(a);LCD_WriteDataE1(*p++);}else{a = L-61;LCD_WriteCommandE2(a);LCD_WriteDataE2(*p++);}L++;}}col=col+16;}}void display_number(unsigned char lin,unsigned int col,unsigned char num){unsigned int seg,i,j;unsigned char a,L,n,k;switch(lin){case 0: n=0xba;break;case 1: n=0xb8;break;}k=num*16;for(j=0;j<2;j++){L=col;LCD_WriteCommandE1(n+j);LCD_WriteCommandE2(n+j);for(seg=0;seg<8;seg++){if (L < 61){a = L;LCD_WriteCommandE1(a);LCD_WriteDataE1(number_X[k++]);}else{a = L-61;LCD_WriteCommandE2(a);LCD_WriteDataE2(number_X[k++]);}L++;}}}void display_unsigned_int(unsigned char lin,unsigned int col,unsigned int dat) {unsigned int seg;unsigned char k[4];k[3]=dat%10;k[2]=((dat/10)%10);k[1]=((dat/100)%10);k[0]=((dat/1000)%10);if(k[0]==0) {k[0]=12;}if((k[0]==12)&&(k[1]==0)){ k[0]=12;k[1]=12;}if((k[0]==12)&&(k[1]==12)&&(k[2]==0)){k[0]=12;k[1]=12;k[2]=12;}for(seg=0;seg<4;seg++){display_number(lin,col,k[seg]);col=col+10;}}void display_signed_int(unsigned char lin,unsigned int col,signed int dat){unsigned int seg;unsigned char k[5],a;k[0]=12;if(dat<0){dat=(~dat)+1;k[0]=11;}k[4]=dat%10;k[3]=((dat/10)%10);k[2]=((dat/100)%10);k[1]=((dat/1000)%10);a=k[0];if(k[1]==0) {k[0]=12;k[1]=a;}if((k[1]==a)&&(k[2]==0)){ k[0]=12;k[1]=12;k[2]=a;}if((k[1]==12)&&(k[2]==a)&&(k[3]==0)){k[0]=12;k[1]=12;k[2]=12;k[3]=a;}for(seg=0;seg<5;seg++){display_number(lin,col,k[seg]);col=col+10;}}void display_unsigned_char(unsigned char lin,unsigned int col,unsigned char dat) {unsigned int seg;unsigned char k[3];k[1]=dat%10;k[0]=((dat/10)%10);for(seg=0;seg<2;seg++){display_number(lin,col,k[seg]);col=col+10;}}2、LCD.h#include <reg51.h>#include <absacc.h>#ifndef __LCD__#define __LCD__#define CWADD1 XBYTE[0x8000]#define DWADD1 XBYTE[0x8001]#define CRADD1 XBYTE[0x8002]#define DRADD1 XBYTE[0x8003]#define CWADD2 XBYTE[0x8004]#define DWADD2 XBYTE[0x8005]#define CRADD2 XBYTE[0x8006]#define DRADD2 XBYTE[0x8007]extern void LCD_Init();extern void display_cn(unsigned char lin,unsigned int col,unsigned int len,unsigned char *p);extern void display_signed_int(unsigned char lin,unsigned int col,signed int dat);extern void display_unsigned_int(unsigned char lin,unsigned int col,unsigned int dat);extern void display_unsigned_char(unsigned char lin,unsigned int col,unsigned char dat);extern void LCD_Clear(void);#endif3、DS18B20.c#include <reg51.h>#include "string.h"#include "intrins.h"#include "DS18B20.h"sbit DQ=P1^0;void delay(unsigned int uSeconds){for(;uSeconds>0;uSeconds--);}unsigned char ow_reset(void){unsigned char xdata presence;DQ = 0;delay(48);DQ = 1;delay(7);presence = DQ;delay(48);return(presence);}unsigned char read_byte(void){unsigned char i;unsigned char value = 0;for (i=8;i>0;i--){value>>=1;DQ = 0; // pull DQ low to start read timeslotDQ = 1; // then rlease DQ_nop_();_nop_();_nop_();_nop_();_nop_(); // read DQ data at 1 to 15us,here delay 6us;if(DQ)value|=0x80;delay(7); // wait for rest of timeslot,72us }return(value);}void write_byte(char val){unsigned char i;for (i=8; i>0; i--) // writes byte, one bit at a time{DQ = 0; // pull DQ low to start timeslotDQ = val&0x01;delay(7); // hold value for remainder of timeslot,here 72us DQ = 1;val=val/2;}delay(5);}float Read_Temperature(void){unsigned char Hdata,Ldata,b;int a;bit flag;float x,y,z;ow_reset();write_byte(0xCC); // Skip ROMwrite_byte(0xBE); // Read Scratch Paddelay(100);Ldata=read_byte(); // Low byte firstHdata=read_byte(); // High byte afterow_reset();write_byte(0xCC); //Skip ROMwrite_byte(0x44); // Start Conversiona=Hdata*256+Ldata;x=(float)(Ldata&0x0f);x=x/16;if(a<0)flag=1;else flag=0;b=a>>4;z=(float)(b);if(flag==1){b=~b+1;z=(float)(b);z=0-z;}y=z+x;return y;}4、DS18B20.h#ifndef __DS18B20__#define __DS18B20__extern float Read_Temperature(void); #endif5、main.c#include <reg51.h>#include<LCD.h>#include<main.h>#include "DS18B20.h"void wait(unsigned int x){unsigned int i;i=0;for(i=0;i<x;i++);}void main(void){float F;signed int a;LCD_Init();LCD_Clear();display_cn(0,20,5,szwdj);display_cn(1,0,3,wdz);while(1){F=Read_Temperature( );a=(signed int)F;display_signed_int(1,40,a);wait(5000);}}6、main.h#ifndef MAIN_H__#define MAIN_H__// 中文字模库16x16点阵code unsigned char szwdj[]={ //纵向字节倒序。
单片机智能体温计课程设计

单片机智能体温计课程设计一、引言体温是人体健康状况的重要指标之一,准确、便捷地测量体温对于疾病的诊断和预防具有重要意义。
传统的体温计在使用上存在一些不便,如测量时间长、读数不直观等。
随着单片机技术的发展,智能体温计应运而生。
本课程设计旨在利用单片机技术,设计一款功能实用、操作简便的智能体温计。
二、设计要求1、测量范围:350℃ 420℃,精度为 01℃。
2、测量时间短,能够快速显示测量结果。
3、具备存储功能,能够记录多次测量数据。
4、具有温度报警功能,当测量温度超过设定的阈值时发出警报。
5、采用直观的显示方式,如液晶显示屏(LCD)。
三、硬件设计1、温度传感器选择数字式温度传感器,如 DS18B20。
它具有体积小、精度高、接口简单等优点,能够直接将温度转换为数字信号输出,方便与单片机进行通信。
2、单片机选用常见的 51 系列单片机,如 STC89C52。
它具有丰富的资源和成熟的开发环境,能够满足本设计的需求。
3、显示模块采用 1602 液晶显示屏,能够清晰地显示测量的温度值、时间等信息。
4、报警模块由蜂鸣器和发光二极管组成。
当测量温度超过设定的阈值时,蜂鸣器发声,发光二极管闪烁,提醒用户。
5、存储模块选用 EEPROM 芯片,如 AT24C02,用于存储测量数据。
四、软件设计1、主程序流程系统初始化,包括单片机端口设置、传感器初始化、显示初始化等。
读取温度传感器的数据,并进行数据处理和转换。
将测量的温度值显示在液晶显示屏上。
判断温度是否超过阈值,若超过则触发报警。
将测量数据存储到 EEPROM 中。
2、温度传感器驱动程序按照 DS18B20 的通信协议,发送指令读取温度数据。
对读取的数据进行校验和处理,得到准确的温度值。
3、显示程序编写驱动 1602 液晶显示屏的程序,实现字符和数字的显示。
4、报警程序当温度超过阈值时,控制蜂鸣器发声和发光二极管闪烁。
5、存储程序按照 EEPROM 的读写协议,将测量数据写入存储芯片。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
液晶显示器分很多种类,按显示方式可分为段式,行点阵式和全点阵式。
段式与数码管类似,行点阵式一般是英文字符,全点阵式可显示任何信息,如汉字、图形、图表等。
这里我们介绍一种八段式四位LCD显示器,该显示器内置驱动器,串行数据传送,使用非常方便。
原理图如下图:广告:>>错误!嵌入对象无效。
下图是长沙太阳人科技开发有限公司生产的4位带串行接口的液晶显示模块SMS0403的外部引线简图:有关该模块的具体参数,请查看该公司网站。
此例中使用的温度传感器为美国DALLAS公司生产的单总线式数字温度传感器。
该传感器本站有其详细的资料可供下载。
此例稍加改动,即可做成温控器。
下载驱动该模块的源程序LCD.PLM例2:saved from url=(0044)/_NTES/~jlsplhd/cxyd7.htm LED显示电脑电子钟本例介绍一种用LED制作的电脑电子钟(电脑万年历)。
其制作完成装潢后的照片如下图:上图中,年、月、日及时间选用的是1.2寸共阳数码管,星期选用的是2.3寸数码管,温度选用的是0.5寸数码管,也可根据个人的爱好选用不同规格的数码管。
原理图如下图所示:上图中,CPU选用的是AT89C2051,时钟芯片选用的是Dallas公司的DS1302,温度传感器选用的是Dallas公司的数字温度传感器DS1820,显示驱动芯片选用的是德州仪器公司的TPIC6B595,也可选用与其兼容的芯片NC595或国产的AMT9595。
整个电子钟用两个键来调节时间和日期。
一个是位选键,一个是数字调节键。
按一下位选键,头两位数字开始闪动,进入设定调节状态,此时按数字调节键,当前闪动位的数字就可改变。
全部参数调节完后,五秒钟内没有任何键按下,则数字停止闪动,退出设定调节状态。
源程序清单如下(无温度显示程序):start:do;$include(reg51.dcl)declare (sclk,io,rst) bit at (0b3h) register; /* p33,p34,p35 */declare (command,data,n,temp1,num) byte;declare a(9) byte;declare ab(6) byte;declare aco(11) byte constant (0fdh,60h,0dah,0f2h,66h,0b6h,0beh,0e0h,0feh,0f6h,00h); declare week(11) byte constant (0edh,028h,0dch,7ch,39h,75h,0f5h,2ch,0fdh,7dh,00h);declare da literally 'p15',clk literally 'p16',ale literally 'p17', mk literally 'p11',sk literally 'p12';clear:procedure;sclk=0;io=0;rst=0;end clear;send1302:procedure(comm);declare (i,comm) byte;do i=0 to 7;comm=scr(comm,1);io=cy;call time(1);sclk=0;call time(1);sclk=1;end;end send1302;wbyt1:procedure(com,dat);/*字节写过程*/declare (com,dat) byte;call clear;rst=1;call send1302(com);call send1302(dat);call clear;end wbyt1;wbyt8:procedure;/*时钟多字节突发模式写过程*/declare j byte;call clear;a(7)=A(6);a(6)=a(0);rst=1;call send1302(command);do j=1 to 8;call send1302(a(j));end;call clear;end wbyt8;RBYT1:PROCEDURE;DECLARE I BYTE;CALL CLEAR;RST=1;call send1302(0c1h);IO=1;DO I=0 TO 7;SCLK=1;SCLK=0;CY=IO;N=SCR(N,1);END;A(8)=N;CALL CLEAR;END RBYT1;send595:procedure;declare k byte;do k=0 to 7;data=scr(data,1);da=cy;clk=1;clk=0;end;end send595;send595_1:procedure;declare k byte;do k=0 to 7;data=scr(data,1);da1=cy;clk1=1;clk1=0;end;end send595_1;rb1:procedure(abc,j);DECLARE (I,j,abc) BYTE;CALL CLEAR;RST=1;call send1302(abc);IO=1;DO I=0 TO 7;SCLK=1;SCLK=0;CY=IO;N=SCR(N,1);END;ab(j)=N;ab(j)=dec(ab(j));CALL CLEAR;end rb1;rbyt6:procedure;call rb1(0f1h,0);call rb1(0f3h,1);call rb1(0f5h,2);call rb1(0f7h,3);call rb1(0f9h,4);call rb1(0fbh,5);call rb1(0fdh,6);end rbyt6;wbyt6:procedure;call wbyt1(8eh,0); /* write enable */call wbyt1(0f0h,ab(0));call wbyt1(0f2h,ab(1));call wbyt1(0f4h,ab(2));call wbyt1(0f6h,ab(3));call wbyt1(0f8h,ab(4));call wbyt1(0fah,ab(5));call wbyt1(0fch,ab(6));call wbyt1(8eh,80h); /* write disable */ end wbyt6;rbyt8:procedure;/*时钟多字节突发模式读过程*/ declare (i,j) byte;call clear;rst=1;call send1302(command);io=1;do j=1 to 8;do i=0 to 7;sclk=1;call time(1);sclk=0;cy=io;n=scr(n,1);end;a(j)=n;end;call clear;a(0)=a(6);a(6)=A(7);a(0)=a(0) and 0fh;if a(0)>6 then a(0)=0;CALL RBYT1;if (a(1)=0 and a(2)=0 and a(3)=0) thendo;do num=0 to 35;call time(250);end;temp1=1;end;if temp1=1 thendo;temp1=0;ab(4)=ab(4)+1;if ab(4)>99h thendo;ab(4)=0;ab(5)=ab(5)+1;if ab(5)>99h then ab(5)=0;end;call wbyt6;end;end rbyt8;display:procedure; /*jieya,yima,fasong*/declare (i,n,m) byte;n=a(0) and 0fh; /* send week */data=week(n);call send595;n=a(4); /* send date */n=n and 0fh;data=aco(n);call send595;n=a(4);n=shr(n,4);data=aco(n);call send595;do i=1 to 3; /* send second,minute,hour */n=a(i);n=n and 0fh;data=aco(n);call send595;n=a(i);n=shr(n,4);data=aco(n);call send595;end;do i=5 to 6; /* send month,year */n=a(i);n=n and 0fh;data=aco(n);call send595;n=a(i);n=shr(n,4);data=aco(n);call send595;end;n=a(8); /* send 19 or 20 */n=n and 0fh;data=aco(n);call send595;n=a(8);n=shr(n,4);data=aco(n);call send595;do m=0 to 5;n=ab(m);n=n and 0fh;data=aco(n);call send595_1;n=ab(m);n=shr(n,4);data=aco(n);call send595_1;end;ale=0;ale=1;end display;beginset:procedure;a(0)=06h;a(1)=58h;a(2)=59h;a(3)=23h;a(4)=30h;a(5)=06h;a(6)=97h;a(7)=00;a(8)=19h; /* set date/time (1997,7,1,8:00:00,week 3) */call wbyt1(8eh,0); /* write enable*/call wbyt1(80h,00h);/* start colock */call wbyt1(0beh,0abh);/*两个二极管与8K电阻串联充电*/command=0beh; /* write colock/date */call wbyt8;call wbyt1(0c0h,a(8));call wbyt1(8eh,80h); /* set write protect bit */end beginset;key:procedure;declare (i,time1,k1,tem) byte;call time(100);k1=7;time1=30;if mk=0 thendo;do while time1>0;week: if k1=0 thendo;do i=0 to 5;/* call hz(a(0)); */end;do i=0 to 3;/* call hz0; */end;end;tem=a(k1);if k1=7 then tem=a(8);a(k1)=0aah;if k1=7 then a(8)=0aah;call display;call time(254);call time (254);a(k1)=tem;if k1=7 then a(8)=tem;call display;call time(254);call time(254);call time(254);time1=time1-1;if mk=0 thendo;call time(100); /*MOD KEY PROCESS*/TIME1=30;IF MK=0 THENDO;k1=k1-1;DO WHILE K1=0FFH;K1=7;END;END;end;IF SK=0 THENDO;CALL TIME(100); /*SET KEY PROCESS*/TIME1=30;IF SK=0 THENDO;tem=tem+1;tem=dec(tem);DO CASE K1;DO WHILE tem=7;/*week*/tem=0;END;DO WHILE tem=60H;/*scond*/ tem=0;END;DO WHILE tem=60H;/*minute*/tem=0;END;DO WHILE tem=24H;/*hour*/tem=0;END;DO WHILE tem=32H;/*date*/tem=1;END;DO WHILE tem=13H;/*month*/tem=1;END;DO while tem=100h; /* YEAR */tem=00;END;DO WHILE TEM>=21H;tem=19H;END;END;A(K1)=tem;if k1=7 then a(8)=tem;END;END;END;END;end key;main$program:mk=1;sk=1;temp1=0;num=0;p32=1;if sk=0 then call beginset;clk=0;da=0;ale=1;loop:do while mk=1 ;if a(0)>6 then a(0)=0;command=0bfh;call rbyt8;call display;do while mk=0;call key;call wbyt1(8eh,0);command=0beh;call wbyt8;call wbyt1(0C0H,A(8));call wbyt1(8eh,80h);end;end;goto loop;end start;例3:saved from url=(0044)/_NTES/~jlsplhd/cxyd5.htm 一个6位LED、4个按键的显示板按键和显示是单片机系统的基本输入输出部件,下面介绍一个由74LS164驱动的6位数码管和4个按键组成的通用仪表面板。