用单片机显示温度的汇编程序
- 格式:docx
- 大小:28.72 KB
- 文档页数:3
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;}液晶显示温度计程序。
1绪论1.1选题背景随着人们生活水平的不断提高,单片机控制无疑是人们追求的目标之一,它所给人带来的方便也是不可否定的,其中数字温度计就是一个典型的例子,但人们对它的要求越来越高,要为现代人工作、科研、生活提供更好的更方便的设施就需要从单片机技术入手,一切向着数字化控制,智能化控制方向发展。
温度测量在物理实验、医疗卫生、食品生产等领域,尤其在热学试验(如:物体的比热容、汽化热、热功当量、压强温度系数等教学实验)中,有特别重要的意义。
现在所使用的温度计通常都是精度为1℃和0.1℃的水银、煤油或酒精温度计。
这些温度计的刻度间隔通常都很密,不容易准确分辨,读数困难,而且他们的热容量还比较大,达到热平衡所需的时间较长,因此很难读准,并且使用非常不方便。
本设计所介绍的数字温度计与传统的温度计相比,具有读数方便,测温范围广,测温准确等优点,其输出温度采用数字显示,主要用于对测温比较准确的场所,或科研实验室使用。
因此本课题就尝试通过编程与芯片的结合来解决传统数字温度计的弊端,设计出新型数字温度计。
1.2课题现状分析及研究意义温度传感器的发展现状:温度传感器使用范围广,数量多,居各种传感器之首,其发展大致经历了以下3个阶段:①传统的分立式温度传感器(含敏感元件)——热电偶传感器,主要是能够进行非电量和电量之间转换。
②模拟集成温度传感器/控制器。
集成传感器是采用硅半导体集成工艺制成的,因此亦称硅传感器或单片集成温度传感器。
③智能温度传感器。
它是微电子技术、计算机技术和自动测试技术(ATE_)的结晶。
智能温度传感器内部包含温度传感器、A/D传感器、信号处理器、存储器(或寄存器)和接口电路。
本课题的研究可以应用领域生产、生活等很多领域。
对于家用电器从洗衣机、微波炉到音响等等到处都可以用到温度控制器来方便大家的日常生活。
开发此产品后也可方便应用安装在小至家庭大到工厂车间,小至一个芯片大到一个机械设备。
例如在家庭客厅卧室等必要地方显示室温,可防止家里食物是否变质及早采取措施。
开题报告电气工程及其自动化基于单片机的带温度显示的数字钟设计(c51语言编程)一、课题研究意义及现状1980年因特尔公司推出了MCS-51单片机,近30年来,其衍生系列不断出现,从Atmel加入FLASH ROM,到philips加入各种外设,再到后来的Cygnal推出C8051F,使得以8051为核心的单片机在各个发展阶段的低端产品应用中始终扮演着一个重要的角色,其地位不断升高,资源越来越丰富,历经30年仍在生机勃勃地发展,甚至在SoC时代仍占有重要的一席之地。
单片机具有体积小、功能强、低功耗、可靠性高、价格低廉等一系列优点,不仅已成为工业测控领域智能仪表、机电一体化、实时控制、国防工业普遍采用的智能化控制工具,而且已渗入到人们工作和和生活的各个角落,有力地推动了各行业的技术改造和产品的更新换代,应用前景广阔。
C语言已经成为当前举世公认的高效简洁而又贴近硬件的编程语言之一。
将C语言向单片机8051上移植十余20世纪80年代的中后期,经过几十年的努力,C语言已成为专业化单片机上的实用高级语言。
C语言是一种编译型程序设计语言,它兼顾了多种高级语言的特点,并具备汇编语言的功能。
此外,C语言程序具有完善的模块程序结构,从而为软件开发中采用模块化程序设计方法提供了有力的保障。
与汇编语言相比,C51在功能、结构、可读性、可维护性上有明显的优势,因而易学易用。
另外C51可以缩短开发周期,降低成本,可靠性,可移植性好。
因此,使用C语言进行程序设计已成为软件开发的一个主流,用C语言进行8051单片机程序设计是单片机开发与应用的必然趋势。
随着人们生活水平的提高,对物质需求也越来越高,人们已不再满足于钟表原先简单的报时功能,希望出现一些新的功能,诸如环境温度显示、日历的显示、重要日期倒计时、显示跑表功能等,用以带来更大的方便。
而所有这些,又都是以数字化的电子时钟为基础的,不仅应用了数字电路技术,而且还加入了需要模拟电路技术和单片机技术。
单片机汇编语言设计实例详解引言:单片机是嵌入式系统中常见的控制器,它具有体积小、功耗低、成本低等特点,被广泛应用于家电、汽车、工业控制等领域。
而汇编语言作为单片机的底层语言,直接操作硬件资源,具有高效性和灵活性。
本文将以一个实例,详细讲解如何使用单片机汇编语言进行设计。
实例背景:假设我们要设计一个温度检测系统,要求实时监测环境温度,并在温度超过某个阈值时触发报警。
硬件准备:1. 单片机:我们选择一款常用的8051单片机作为例子。
2. 温度传感器:我们选择一款数字温度传感器,它可以通过串行通信与单片机进行数据交互。
3. 显示屏:为了方便实时显示温度信息,我们选用一款数码管显示屏。
软件准备:1. Keil C51:这是一款常用的单片机开发软件,支持汇编语言的编写和调试。
2. 串口调试助手:用于测试串口通信功能。
设计步骤:1. 硬件连接:将单片机与温度传感器、显示屏连接起来。
注意接线的正确性和稳定性。
2. 编写初始化程序:使用汇编语言编写单片机的初始化程序,包括端口初始化、中断向量表设置、定时器初始化等。
3. 串口通信设置:通过串口与温度传感器进行数据交互,需要设置串口通信的波特率、数据位数、停止位等参数。
4. 温度检测程序:编写汇编语言程序,实时读取温度传感器的数据,并将数据送至显示屏进行显示。
5. 温度报警程序:在温度超过设定阈值时,触发报警程序,可以通过蜂鸣器等外设发出警报信号。
6. 调试与测试:使用Keil C51进行程序调试,通过串口调试助手测试串口通信和温度显示、报警功能。
设计思路:1. 初始化程序设计:先设置端口的输入输出方向,再设置中断向量表,最后初始化定时器。
这样可以确保程序的稳定性和可靠性。
2. 串口通信设置:根据温度传感器的通信协议,设置串口的波特率、数据位数、停止位等参数。
注意要与传感器的通信规范保持一致。
3. 温度检测程序设计:通过串口读取温度传感器的数据,并进行相应的处理。
#include <reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned int#define delayNOP() {_nop_();_nop_();_nop_();_nop_();}sbit DQ=P2^2;sbit dula=P2^6; //定义锁存器锁存端sbit wela=P2^7;sbit rs=P3^5; //定义1602液晶RS端sbit lcden=P3^4;//定义1602液晶LCDEN端sbit s1=P3^0; //定义按键--功能键sbit s2=P3^1; //定义按键--增加键sbit s3=P3^2; //定义按键--减小键sbit s4=P3^6;//闹钟查看键sbit rd=P3^7;sbit beep=P2^3; //定义蜂鸣器端uchar code Temp_Disp_Title[]={" Current Temp : "};uchar Current_Temp_Display_Buffer[]={" TEMP: "};uchar code Alarm_Temp[]={"ALARM TEMP Hi Lo"};uchar Alarm_HI_LO_STR[]={"Hi: Lo: "};uchar temp_data[2]={0x00,0x00};uchar temp_alarm[2]={0x00,0x00};uchar display[5]={0x00,0x00,0x00,0x00,0x00};uchar display1[3]={0x00,0x00,0x00};uchar code df_Table[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};uchar CurrentT=0; //当前读取的温度整数部分uchar Temp_Value[]={0x00,0x00}; //从DS18B20读取的温度值uchar Display_Digit[]={0,0,0,0}; //待显示的各温度数位bit DS18B20_IS_OK=1;//传感器正常标志//-------------------------------------//延时1//-------------------------------------void delay1(uint x){uchar i;while(x--) for(i=0;i<200;i++);}//-------------------------------------//延时2//-------------------------------------void Delay(uint x){while(x--);}//------------------------------------//忙检查//------------------------------------void write_com(uchar com)//液晶写命令函数{rs=0;lcden=0;P0=com;delay1(5);lcden=1;delay1(5);lcden=0;}void Write_LCD_Data(uchar date)//液晶写数据函数{rs=1;lcden=0;P0=date;delay1(5);lcden=1;delay1(5);lcden=0;}//-----------------------------//设置LCD显示位置//---------------------------------void Set_Disp_Pos(uchar Pos){write_com(Pos|0x80);}//-----------------------------//LCD初始化//---------------------------------void Initialize_LCD(){uchar num;rd=0; //软件将矩阵按键第4列一端置低用以分解出独立按键dula=0;//关闭两锁存器锁存端,防止操作液晶时数码管会出乱码wela=0;lcden=0;write_com(0x38);//初始化1602液晶write_com(0x0c);write_com(0x06);write_com(0x01);write_com(0x80);//设置显示初始坐标for(num=0;num<14;num++)//显示年月日星期{Write_LCD_Data(Temp_Disp_Title[num]);delay1(5);}}//-------------------------------------//函数功能:初始化DS18B20//出口参数:status---DS18B20是否复位成功的标志//-------------------------------------uchar Init_DS18B20(){uchar status; //储存DS18B20是否存在的标志,status=0,表示存在;status=1,表示不存在DQ=1;Delay(8); //先将数据线拉高//略微延时约6微秒DQ=0;Delay(90); //再将数据线从高拉低,要求保持480~960us//略微延时约600微秒以向DS18B20发出一持续480~960us的低电平复位脉冲DQ=1;Delay(8); //释放数据线(将数据线拉高)//延时约30us(释放总线后需等待15~60us让DS18B20输出存在脉冲)status=DQ;Delay(100); //让单片机检测是否输出了存在脉冲(DQ=0表示存在)//延时足够长时间,等待存在脉冲输出完毕DQ=1; // 将数据线拉高return status; //返回检测成功标志}//-------------------------------------//函数功能:读一字节//出口参数:dat---读出的数据//-------------------------------------uchar ReadOneByte(){uchar i,dat=0;DQ=1;_nop_(); // 先将数据线拉高//等待一个机器周期for (i=0;i<8;i++){DQ=0; //单片机从DS18B20读书据时,将数据线从高拉低即启动读时序dat>>=1;_nop_(); //等待一个机器周期DQ=1; //将数据线"人为"拉高,为单片机检测DS18B20的输出电平作准备_nop_();_nop_(); //延时约6us,使主机在15us内采样if (DQ) dat|=0x80; //如果读到的数据是1,则将1存入dat,如果是0则保持原值不变Delay(30); //延时3us,两个读时序之间必须有大于1us的恢复期DQ=1; // 将数据线拉高,为读下一位数据做准备}return dat;}//-------------------------------------//函数功能:写一字节//入口参数:dat---待写入的数据//-------------------------------------void WriteOneByte(uchar dat){uchar i;for (i=0;i<8;i++){DQ=0; //将数据线从高拉低时即启动写时序DQ=dat & 0x01; //利用与运算取出要写的某位二进制数据,//并将其送到数据线上等待DS18B20采样Delay(5); //延时约30us,DS18B20在拉低后的约15~60us期间从数据线上采样DQ=1; //释放数据线dat>>=1; //将dat中的各二进制位数据右移1位}}//-------------------------------------//函数功能:读取温度值//出入口参数:无//-------------------------------------void Read_Temperature(){if(Init_DS18B20() == 1) //DS18B20故障DS18B20_IS_OK=0;else{WriteOneByte(0xCC); // 跳过读序号列号的操作WriteOneByte(0x44); // 启动温度转换Init_DS18B20(); //将DS18B20初始化WriteOneByte(0xCC); //跳过读序号列号的操作WriteOneByte(0xBE); //读取温度寄存器,前两个分别是温度的低位和高位Temp_Value[0]=ReadOneByte(); //温度低8位Temp_Value[1]=ReadOneByte(); //温度高8位DS18B20_IS_OK=1;}}//-------------------------------------//函数功能:在LCD上显示当前温度//入口参数://-------------------------------------void Display_Temperature(){uchar i;//延时值与负数标识uchar t=150,ng=0;//高5位全为1(0xF8)则为负数,为负数时取反加1,并设置负数标示if ((Temp_Value[1] & 0xF8)==0xF8){Temp_Value[1]=~Temp_Value[1];Temp_Value[0]=~Temp_Value[0]+1;if(Temp_Value[0]==0x00) Temp_Value[1]++; //加1后如果低字节为00表示有进位,进位位再加到高字节上ng=1; //负数标示置1}Display_Digit[0]=df_Table[Temp_Value[0] & 0x0F]; //查表得到温度小数部分//获取温度整数部分(高字节的低3位与低字节中的高4位,无符号)CurrentT=((Temp_V alue[0] & 0xF0)>>4)|((Temp_Value[1] & 0x07)<<4);//将整数部分分解为3位待显示数字Display_Digit[3]=CurrentT/100; //百位digit[CurrentT/100];Display_Digit[2]=CurrentT%100/10; //十位Display_Digit[1]=CurrentT%10; //个位//刷新LCD显示缓冲Current_Temp_Display_Buffer[11]=Display_Digit[0]+'0';//先将'0'转换成整数48,然后与前面数字相加,得到相应数字的ASCII字符Current_Temp_Display_Buffer[10]='.';Current_Temp_Display_Buffer[9]=Display_Digit[1]+'0'; //个位Current_Temp_Display_Buffer[8]=Display_Digit[2]+'0'; //十位Current_Temp_Display_Buffer[7]=Display_Digit[3]+'0'; //百位//高位为0时不显示if(Display_Digit[3]==0) Current_Temp_Display_Buffer[7]=' ';//高位为0且次高位为0时,次高位不显示if(Display_Digit[2]==0 && Display_Digit[3]==0)Current_Temp_Display_Buffer[8]=' ';//负数符号显示在恰当位置if(ng){if (Current_Temp_Display_Buffer[8]==' ')Current_Temp_Display_Buffer[8]='-';else if(Current_Temp_Display_Buffer[7]==' ')Current_Temp_Display_Buffer[7]='-';elseCurrent_Temp_Display_Buffer[6]='-';}//在第一行显示标题Set_Disp_Pos(0x00);for(i=0;i<16;i++){Write_LCD_Data(Temp_Disp_Title[i]);}Set_Disp_Pos(0x40); //在第二行显示当前温度for(i=0;i<16;i++){Write_LCD_Data(Current_Temp_Display_Buffer[i]);}//显示温度符号// Set_Disp_Pos(0x4D);Write_LCD_Data(0x00);Set_Disp_Pos(0x4D);Write_LCD_Data(0xdf);Set_Disp_Pos(0x4E); Write_LCD_Data('C');}//-------------------------------------//函数功能:主函数//入口参数://-------------------------------------void main(){Initialize_LCD();Read_Temperature();Delay(50000);Delay(50000);while (1){Read_Temperature();if (DS18B20_IS_OK) Display_Temperature();delay1(100);}。
单片机驱动TFT彩屏的程序设计一种完整的复杂的单片机驱动TFT彩屏的程序设计。
同步显示有星期;温度;时间;遥控指示;以及强大的定时功能…废话不多说,自已向下看吧…显示效果图:彩屏部分数据:(网上有资料,陶宝网上有买)以下是汇编程序:(本程序可直接复制使用,但请指明出处。
)本程序本人用时2. 5个月制作(当然是工作闲余的时候),本程序是本人为学习汇编而编写(为做到“入森而不迷”)。
其已经做过实物测试,除时间不是十分精确外,其它都没有问题(因为问题已经解决了~~)。
遥控码数请参照程序中的以下两个子程序:子程序1:遥控按键处理(码数这里面,很容易找的)子程序2:遥控外部中断处理程序(遥控器不同码数长度也不一样,这里要注意);制作:王永宾;QQ:794576441;Email:*******************;---------------------------------------复制以下------------------------ ---------------------------------;TFT彩屏程序(STC89C52);制作:王永宾;QQ:794576441;Email:*******************LCDRS EQU P2.0LCDRW EQU P2.1LCDRST EQU P2.4;------------------SU00 EQU 30H ;时间字符的地址2440(0-9)SU01 EQU 31HSU10 EQU 32HSU11 EQU 33HSU20 EQU 34HSU21 EQU 35HSU30 EQU 36HSU31 EQU 37HSU40 EQU 38HSU41 EQU 39HSU50 EQU 3AHSU51 EQU 3BHSU60 EQU 3CHSU61 EQU 3DHSU70 EQU 3EHSU71 EQU 3FHSU80 EQU 40HSU81 EQU 41HSU90 EQU 42HSU91 EQU 43H;--------时间寄存器定义----------RR0 EQU 44HRR1 EQU 45HRR2 EQU 46HRR3 EQU 47HRR4 EQU 48HRR5 EQU 49HRR6 EQU 4AHRR7 EQU 4BHSUZR0 EQU 4DH ;星期?字符的地址(日-六)SUZR1 EQU 4EHSUZ10 EQU 4FHSUZ11 EQU 50HSUZ20 EQU 51HSUZ30 EQU 53HSUZ31 EQU 54HSUZ40 EQU 55HSUZ41 EQU 56HSUZ50 EQU 57HSUZ51 EQU 58HSUZ60 EQU 59HSUZ61 EQU 5AHWD1 EQU 5BHWD2 EQU 5CHWD3 EQU 5DHWD4 EQU 5EH;-------星期?寄存器定义------------ RR8 EQU 4CH;定时字符的地址1616(六-日)GUAN0 EQU 60HGUAN1 EQU 61HSL10 EQU 62HSL11 EQU 63HSL20 EQU 64HSL21 EQU 65HSL30 EQU 66HSL31 EQU 67HSL40 EQU 68HSL41 EQU 69HSL50 EQU 6AHSL51 EQU 6BHSL60 EQU 6CHSL61 EQU 6DHSL70 EQU 6EHSL71 EQU 6FH;--------定时寄存器定义---第一组-------RA EQU 70H ;组RAL0 EQU 71H ;时间RAL2 EQU 73HRAL3 EQU 74HRAR0 EQU 75HRAR1 EQU 76HRAR2 EQU 77HRAR3 EQU 78HRA1 EQU 79H ;星期?RA2 EQU 7AHRA3 EQU 7BHRA4 EQU 7CHRA5 EQU 7DHRA6 EQU 7EHRA7 EQU 7FH;TFT彩屏程序(STC89C52);制作:王永宾;QQ:794576441;Email:*******************;===================================;===============开始00\==========ORG 0000HLJMP MAIN0ORG 03HLJMP ITT00 ;外部中断ORG 0BHRETI ;计时中断如果溢出直接ORG 1BHLJMP TI1 ;走时中断;============主程序开始=================; ORG 20HMAIN0:LCALL KAIJI ;开机初始化LCALL CSH0QINGPINGHAI0:JB P3.7,$MOV 24H,#00H ;R4 MOV 25H,#03FH ;R4 MOV 26H,#00HMOV 27H,#03FHMOV R3,#00HMOV R4,#00HLCALL QINGPING QINGPINGHAI1:JNB P3.7,QINGPINGRED0 JNB P3.6,QINGPINGEND AJMP QINGPINGHAI1QINGPINGRED0:JB P3.7,$MOV 24H,#0E0H ;R4 MOV 25H,#0FFH ;R4 MOV 26H,#0E0HMOV 27H,#0FFHMOV R3,#00HMOV R4,#0E0HLCALL QINGPING QINGPINGRED1:JNB P3.7,QINGPINGLV0 JNB P3.6,QINGPINGEND AJMP QINGPINGRED1QINGPINGLV0:JB P3.7,$MOV R1,#00HMOV R2,#03HMOV R3,#10HMOV R4,#0B0HLCALL XML ;写命令LCALL XSJ ;写数据MOV R1,#00HMOV R2,#22HLCALL XML ;写命令MOV 24H,#0C3H ;底MOV 25H,#3FH ;字MOV 26H,#0C3H ;底MOV 27H,#3FH ;字MOV R3,#00HMOV R4,#0C3H ;底LCALL QINGPING QINGPINGLV1:JNB P3.7,QINGPINGHAI0JNB P3.6,QINGPINGENDAJMP QINGPINGLV1;========================= QINGPINGEND:MOV R1,#00HMOV R2,#22HLCALL XML ;写命令LCALL GUDING ;固定字符LCALL WINDU ;温度LCALL YAOKONG ;遥控LJMP XSUMAIN:LCALL DINGSHISHU ;定时数LCALL DINGSHIZU ;定时组LCALL XPX ;星期几LCALL SHIJIAN ;时间LCALL WENDUCHULILCALL WINDU ;温度LCALL TIR0SETB P2.5 ;-----完全相等---关闹CLR P2.6 ;-----完全相等---关闹MAIN1:CLR P2.7LCALL SHIJIAN ;时间LCALL JP0 ;键盘LCALL POWER ;遥控处理;----------------------MOV A,2CHCJNE A,RR3,MAIN2 ;RR3为分计LJMP MAIN3 ;定义十秒锺扫一次温度MAIN2:MOV 2CH,RR3LCALL WENDUCHULI ;温度处理LCALL WINDU ;温度MAIN3:MOV A,RR0 ;分有变动就扫描定时CJNE A,RR4,MAIN4 ;RR4为分LJMP MAIN1MAIN4:MOV RR0,RR4LCALL BIJIAO ;定时比较LJMP MAIN1;=============温度处理====================== WENDUCHULI:LCALL WENDUXS ;读写子程序MOV A,21HMOV R0,#20HXCHD A,@R0ANL A,#0FHMOV 21H,A ;21H小数处理MOV A,20HSWAP A ;20整数处理MOV 20H,AJB 07H,WENDUCHULI1;是负数转MOV WD4,26H ;清除负数标示LCALL WENDUCHULI0 ;写整数个位MOV WD2,ALCALL WENDUCHULI0 ;写整数十位MOV WD1,AMOV A,21H ;写小数位MOV B,#02DIV ABMOV B,AADD A,BADD A,#30HMOV WD3,A ;写小数位RETWENDUCHULI1:;负数处理.....MOV WD4,27H ;负数标示MOV A,20H ;20整数处理CPL A ;取反ANL A,#7FH ;清负数位INC A ;加一MOV 20H,A ;20整数处理MOV A,21H ;21H小数处理CPL A ;取反ANL A,#0FH ;清除高位INC A ;加一MOV 21H,A ;21H小数处理LCALL WENDUCHULI0 ;写整数个位MOV WD2,ALCALL WENDUCHULI0 ;写整数十位MOV WD1,AMOV A,21H ;写小数位MOV B,#02DIV ABMOV B,AADD A,BADD A,#30HMOV WD3,A ;写小数位RET;------------整数写子程序-------- WENDUCHULI0:MOV A,20H ;整数写子程序MOV B,#10DIV ABMOV 20H,AMOV A,BADD A,BADD A,#30H ;整数写子程序RET;======写数据========= WENDUXS:LCALL WENDURSTJB 70H,WENDUXS1 ;检复位成功了转RETWENDUXS1:MOV A,#0CCH ;跳过ROMLCALL WENDUXS_BMOV A,#44HLCALL WENDUXS_B ;RAM温度转换MOV R4,#50D1: ;等待750uS转换完成MOV R5,#13DJNZ R5,$DJNZ R6,D1;======读数据==============LCALL WENDURSTJB 70H,WENDUDS1 ;检复位成功了转RETWENDUDS1:MOV A,#0CCH ;跳过ROMLCALL WENDUXS_BMOV A,#0BEH ;读RAMLCALL WENDUXS_BLCALL WENDUDX_B ;调读子程序RET;-----读数子程序-----------WENDUDX_B:MOV R0,#20HMOV R4,#02WENDUDX_B0:MOV R5,#08HWENDUDX_B1:CLR CSETB P3.3NOPNOPNOPNOPCLR P3.3NOPNOPNOPNOPNOPNOPSETB P3.3MOV R6,#18DJNZ R6,$ ;13uSMOV C,P3.3MOV R6,#46DJNZ R6,$RRC ADJNZ R5,WENDUDX_B1MOV @R0,AINC R0DJNZ R4,WENDUDX_B0RET;====写数据子程序======WENDUXS_B:MOV R5,#08HCLR CWENDUXS_B0:CLR P3.3MOV R6,#12DJNZ R6,$RRC AMOV P3.3,CMOV R6,#49DJNZ R6,$SETB P3.3NOPNOPDJNZ R5,WENDUXS_B0SETB P3.3RET;===========18B20初始化子程序=============== WENDURST:SETB P3.3NOPNOPCLR P3.3MOV R5,#255WENDURST1: ;复位低电时间510uSNOPNOPDJNZ R5,WENDURST1;复位低电时间510uSSETB P3.3MOV R5,#60 ;等待检测存在脉冲15uSDJNZ R5,$ ;等待检测存在脉冲15uSJNB P3.3,WENDURSTOK ;有存在脉冲转CLR 70H ;无存在脉冲清除标号RETWENDURSTOK:MOV R5,#180 ;测存在脉冲240uSDJNZ R5,$SETB 70H ;有存在脉冲打上标号SETB P3.3RET;============遥控按键处理========================== POWER:MOV A,5FHCJNE A,#0B7H,POWER1LCALL YAOKONG1MOV 5FH,#00HRETPOWER1:MOV A,5FHCJNE A,#0A7H,POWER2LCALL YAOKONG2MOV 5FH,#00HRETPOWER2:MOV A,5FHCJNE A,#97H,POWER3LCALL YAOKONG3MOV 5FH,#00HRETPOWER3:MOV A,5FHCJNE A,#0FH,POWER4LCALL YAOKONG4MOV 5FH,#00HRETPOWER4:MOV A,5FHCJNE A,#0C7H,POWER5 LCALL YAOKONG5 MOV 5FH,#00HRETPOWER5:MOV A,5FHCJNE A,#4FH,POWER6 LCALL YAOKONG6 MOV 5FH,#00HRETPOWER6:MOV A,5FHCJNE A,#0E7H,POWER7 LCALL YAOKONG7 MOV 5FH,#00HRETPOWER7:MOV A,5FHCJNE A,#27H,POWER8 LCALL YAOKONG8 MOV 5FH,#00HRETPOWER8:MOV A,5FHCJNE A,#0D7H,POWER9 LCALL YAOKONG9 MOV 5FH,#00HRETPOWER9:MOV A,5FHCJNE A,#47H,POWER0 LCALL YAOKONG0 MOV 5FH,#00H POWER0:RET;====================================== ;=========定时比较==================== BIJIAO:BJ0:MOV A,RR8CJNE A,#4DH,BJ1 ;今天星期一吗?MOV R1,#1EHMOV R0,#10HLCALL BJ00RETBJ1:CJNE A,#4FH,BJ2MOV R1,#18HMOV R0,#10HLCALL BJ00RETBJ2:CJNE A,#51H,BJ3MOV R1,#19HMOV R0,#10HLCALL BJ00RETBJ3:CJNE A,#53H,BJ4MOV R1,#1AHMOV R0,#10HLCALL BJ00RETBJ4:CJNE A,#55H,BJ5MOV R1,#1BHMOV R0,#10HLCALL BJ00RETBJ5:CJNE A,#57H,BJ6MOV R1,#1CHMOV R0,#10HLCALL BJ00RETBJ6:CJNE A,#59H,BJ7MOV R1,#1DHMOV R0,#10HLCALL BJ00RETBJ7:LJMP BIJIAO;=========================BJ00: ;是的MOV R5,#08HBJ001:MOVX A,@R1CJNE A,#60H,BJ01 ;第一组的星期一\开了吗? BJ003:MOV A,R1ADD A,#10HMOV R1,AMOV A,R0ADD A,#10HMOV R0,ADJNZ R5,BJ001RETBJ01:LCALL BJBRAL ;调比较程序INC R0INC R0INC R0INC R0LCALL BJBRAR ;调比较程序DEC R0DEC R0DEC R0DEC R0LJMP BJ003;----------子程序-------------BJBRAL:PUSH 00HMOVX A,@R0CJNE A,RR7,BJRALRET ;RAL0=RR7?,不等返回INC R0MOVX A,@R0CJNE A,RR6,BJRALRET ;RAL1=RR6?,不等返回INC R0MOVX A,@R0CJNE A,RR5,BJRALRET ;RAL2=RR5?,不等返回INC R0MOVX A,@R0CJNE A,RR4,BJRALRET ;RAL3=RR4?,不等返回CLR P2.5 ;-----完全相等---开闹SETB P2.6 ;-----完全相等---开闹LJMP BJRALRETBJBRAR:PUSH 00HMOVX A,@R0CJNE A,RR7,BJRALRET ;RAL0=RR7?,不等返回INC R0MOVX A,@R0CJNE A,RR6,BJRALRET ;RAL1=RR6?,不等返回INC R0MOVX A,@R0CJNE A,RR5,BJRALRET ;RAL2=RR5?,不等返回INC R0MOVX A,@R0CJNE A,RR4,BJRALRET ;RAL3=RR4?,不等返回SETB P2.5 ;-----完全相等---关闹CLR P2.6 ;-----完全相等---关闹BJRALRET:POP 00HRET;======================================== ;=======键盘========================JP0:SETB P3.4SETB P3.5SETB P3.6SETB P3.7JP:JNB P3.4,JP1 ;TEST第一次检查JNB P3.5,JP2 ;ALTEST第一次检查JNB P3.6,SNOOZERET ;返回MAINJP1: ;TEST第二次检查LCALL SHIJIAN ;显示时间LCALL XPX ;显示星期几JNB P3.4,JP1LJMP TESETJP2: ;ALTEST第二次检查LCALL SHIJIAN ;显示时间LCALL XPX ;显示星期几JNB P3.5,JP2LJMP ALSETSNOOZE: ;ALTEST第二次检查LCALL SHIJIAN ;显示时间LCALL XPX ;显示星期几JNB P3.5,SNOOZESETB P2.5CLR P2.6RET;-------TEST处理地址--------------- TESET: ;TEST处理地址LCALL SHIJIAN ;显示时间JNB P3.4,TESETTESET1:MOV R3,#70H ;选定LCALL SHIJIAN ;显示时间LCALL XPX ;显示星期几JNB P3.5,XQ0 ;转星期?JNB P3.6,HR0 ;转时JNB P3.7,MIN0 ;转分JNB P3.4,TESETO ;转返回LJMP TESET1 ;重复检查XQ0: ;星期?二次检查LCALL SHIJIAN ;显示时间LCALL XPX ;显示星期几JNB P3.5,XQ0LJMP XQHR0: ;时二次检查LCALL SHIJIAN ;显示时间LCALL XPX ;显示星期几JNB P3.6,HRLJMP TESET1MIN0: ;分二次检查LCALL SHIJIAN ;显示时间LCALL XPX ;显示星期几JNB P3.7,MINLJMP TESET1TESETO: ;返回二次检查MOV R3,#00HLCALL SHIJIAN ;显示时间LCALL XPX ;显示星期几JNB P3.4,TESETOLJMP RESXQ: ;星期?处理程序INC RR8INC RR8LCALL XQCJMLJMP TESET1HR: ;时处理程序INC RR6INC RR6LCALL HRCJMLJMP TESET1MIN: ;分处理程序INC RR4INC RR4LCALL MINCJMLJMP TESET1RES:MOV R3,#00H ;取消选定RET ;返回MAIN;------ALTEST处理地址--------------- ALSET: ;ALTEST处理地址LCALL SHIJIANLCALL XPXJNB P3.5,ALSETALSET1:MOV R3,#00HLCALL SHIJIANLCALL XPXMOV R3,#70HMOV 05H,#70HLCALL XRXSLCALL DINGSHISHULCALL DINGSHIZUJNB P3.5,ALSETOJNB P3.4,ALSETRRLL00JNB P3.6,XQZURRLLLJMP ALSET1XQZURRLL:LJMP XQZURRLL00 ALSETO: ;返回二次检查MOV R3,#00HMOV 05H,#00HLCALL SHIJIAN ;显示时间LCALL XPX ;显示星期几JNB P3.5,ALSETO ;返回LJMP ALRESALRES:LCALL DINGSHIZULCALL DINGSHISHU ;定时数RET ;返回MAIN;--------------------------------------ALSETRRLL00: ;返回二次检查LCALL SS50mSJNB P3.4,ALSETRRLL00MOV R3,#00HLCALL DINGSHISHUMOV 05H,#00HLCALL DINGSHIZU ALSETRRLL01:JNB P3.7,ALSETADD00JNB P3.4,ALSETRRLL10MOV R3,#70HLCALL DINGSHISHU12LJMP ALSETRRLL01ALSETADD00:LCALL SS50mSJNB P3.7,ALSETADD01LJMP ALSETRRLL01 ALSETADD01:LCALL DINGSHISHU12INC RAL1INC RAL1MOV A,#34HCJNE A,RAL0,ALSETADD02MOV A,#38HCJNE A,RAL1,ALSETRRLL01 MOV RAL1,#30HMOV RAL0,#30HLJMP ALSETRRLL01ALSETADD02:MOV A,#44HCJNE A,RAL1,ALSETRRLL01 MOV RAL1,#30HINC RAL0INC RAL0LJMP ALSETRRLL01;------------------------------------------- ALSETRRLL10: ;返回二次检查LCALL SS50mSJNB P3.4,ALSETRRLL10MOV R3,#00HLCALL DINGSHISHU ALSETRRLL11:JNB P3.7,ALSETADD10JNB P3.4,ALSETRRLL20MOV R3,#70HLCALL DINGSHISHU34LJMP ALSETRRLL11ALSETADD10:LCALL SS50mSJNB P3.7,ALSETADD11LJMP ALSETRRLL11 ALSETADD11:LCALL DINGSHISHU34INC RAL3INC RAL3MOV A,#44HCJNE A,RAL3,ALSETRRLL11 MOV RAL3,#30HINC RAL2 ;分INC RAL2MOV A,#3CHCJNE A,RAL2,ALSETRRLL11 MOV RAL2,#30HLJMP ALSETRRLL11;------------------------------------- ALSETRRLL20: ;返回二次检查LCALL SS50mSJNB P3.4,ALSETRRLL20MOV R3,#00HLCALL DINGSHISHU ALSETRRLL21:JNB P3.7,ALSETADD20JNB P3.4,ALSETRRLL30MOV R3,#70HLCALL DINGSHISHU56LJMP ALSETRRLL21ALSETADD20:LCALL SS50mSJNB P3.7,ALSETADD21LJMP ALSETRRLL21 ALSETADD21:LCALL DINGSHISHU56INC RAR1INC RAR1MOV A,#34HCJNE A,RAR0,ALSETADD22MOV A,#38HCJNE A,RAR1,ALSETRRLL21 MOV RAR1,#30HMOV RAR0,#30HLJMP ALSETRRLL21ALSETADD22:MOV A,#44HCJNE A,RAR1,ALSETRRLL21MOV RAR1,#30HINC RAR0INC RAR0LJMP ALSETRRLL21;-----------------------------------------ALSETRRLL30: ;返回二次检查LCALL SS50mSJNB P3.4,ALSETRRLL30MOV R3,#00HLCALL DINGSHISHUALSETRRLL31:JNB P3.7,ALSETADD30JNB P3.4,ALSETRRLL40MOV R3,#70HLCALL DINGSHISHU78LJMP ALSETRRLL31ALSETRRLL40:MOV R3,#00HLCALL BCXH;=================保存数值=========== LJMP ALSET1ALSETADD30:LCALL SS50mSJNB P3.7,ALSETADD31LJMP ALSETRRLL31ALSETADD31:LCALL DINGSHISHU78INC RAR3INC RAR3MOV A,#44HCJNE A,RAR3,ALSETRRLL31MOV RAR3,#30HINC RAR2 ;分INC RAR2MOV A,#3CHCJNE A,RAR2,ALSETRRLL31MOV RAR2,#30HLJMP ALSETRRLL31;-----------------?组---------------XQZURRLL00:LCALL SS50mSJNB P3.6,XQZURRLL00;如果为0(不放键)等待MOV R3,#00HLCALL DINGSHISHUMOV 05H,#00HLCALL DINGSHIZU;清除全部颜色选定XQZURRLL01:MOV R3,#00HMOV 05H,#00HLCALL XRXSLCALL DINGSHIZULCALL DINGSHISHUXQZURRLL011:JNB P3.7,XQZUADD00;按加键加JNB P3.6,XQZURRLL10 ;按RRLL换下一个或返回MOV 05H,#70H ;选定要调的颜色LCALL DINGSHIZU1 ;选定要调的颜色LJMP XQZURRLL011XQZUADD00:JNB P3.7,XQZUADD00 ;加键有用吗?XQZUADD01: ;有用加一次LCALL DINGSHIZU1INC RAINC RAMOV A,#70HCJNE A,RA,XQZURRLL01MOV RA,#62HLJMP XQZURRLL01;---------------------- 一-------------XQZURRLL10:LCALL SS50mSJNB P3.6,XQZURRLL10;如果为0(不放键)等待MOV 05H,#00HLCALL DINGSHIZU;清除全部颜色选定XQZURRLL11:JNB P3.7,XQZUADD10;按加键加JNB P3.6,XQZURRLL20 ;按RRLL换下一个或返回;================= MOV 05H,#70H ;选定要调的颜色LCALL DINGSHIZU2 ;选定要调的颜色LJMP XQZURRLL11 ;循环XQZUADD10:JNB P3.7,XQZUADD10 ;加键有用吗?XQZUADD11: ;有用加一次LCALL DINGSHIZU2MOV A,#62HCJNE A,RA1,FG10MOV RA1,#60HLJMP XQZURRLL11FG10:MOV RA1,#62HLJMP XQZURRLL11;--------------- 二XQZURRLL20:LCALL SS50mSJNB P3.6,XQZURRLL20;如果为0(不放键)等待MOV 05H,#00HLCALL DINGSHIZU;清除全部颜色选定XQZURRLL21:JNB P3.7,XQZUADD20;按加键加JNB P3.6,XQZURRLL30 ;按RRLL换下一个或返回;==MOV 05H,#70H ;选定要调的颜色LCALL DINGSHIZU3 ;选定要调的颜色LJMP XQZURRLL21 ;循环;--------XQZUADD20:JNB P3.7,XQZUADD20 ;加键有用吗?XQZUADD21: ;有用加一次LCALL DINGSHIZU3MOV A,#64HCJNE A,RA2,XQZURRLL210MOV RA2,#60HLJMP XQZURRLL21XQZURRLL210:MOV RA2,#64HLJMP XQZURRLL21;--------------- 三XQZURRLL30:LCALL SS50mSJNB P3.6,XQZURRLL30;如果为0(不放键)等待MOV 05H,#00HLCALL DINGSHIZU;清除全部颜色选定XQZURRLL31:JNB P3.7,XQZUADD30;按加键加JNB P3.6,XQZURRLL40 ;按RRLL换下一个或返回;== MOV 05H,#70H ;选定要调的颜色LCALL DINGSHIZU4 ;选定要调的颜色LJMP XQZURRLL31 ;循环XQZUADD30:JNB P3.7,XQZUADD30 ;加键有用吗?XQZUADD31: ;有用加一次LCALL DINGSHIZU4MOV A,#66HCJNE A,RA3,XQZURRLL310MOV RA3,#60HLJMP XQZURRLL31XQZURRLL310:MOV RA3,#66HLJMP XQZURRLL31;--------------- 四XQZURRLL40:LCALL SS50mSJNB P3.6,XQZURRLL40;如果为0(不放键)等待MOV 05H,#00HLCALL DINGSHIZU;清除全部颜色选定XQZURRLL41:JNB P3.7,XQZUADD40;按加键加JNB P3.6,XQZURRLL50 ;按RRLL换下一个或返回;== MOV 05H,#70H ;选定要调的颜色LCALL DINGSHIZU5 ;选定要调的颜色LJMP XQZURRLL41 ;循环XQZUADD40:JNB P3.7,XQZUADD40 ;加键有用吗?XQZUADD41: ;有用加一次LCALL DINGSHIZU5MOV A,#68HCJNE A,RA4,XQZURRLL410MOV RA4,#60HLJMP XQZURRLL41XQZURRLL410:MOV RA4,#68HLJMP XQZURRLL41;--------------- 五XQZURRLL50:LCALL SS50mSJNB P3.6,XQZURRLL50;如果为0(不放键)等待MOV 05H,#00HLCALL DINGSHIZU;清除全部颜色选定XQZURRLL51:JNB P3.7,XQZUADD50;按加键加JNB P3.6,XQZURRLL60 ;按RRLL换下一个或返回;== MOV 05H,#70H ;选定要调的颜色LCALL DINGSHIZU6 ;选定要调的颜色LJMP XQZURRLL51 ;循环XQZUADD50:JNB P3.7,XQZUADD50 ;加键有用吗?XQZUADD51: ;有用加一次LCALL DINGSHIZU6MOV A,#6AHCJNE A,RA5,XQZURRLL510MOV RA5,#60HLJMP XQZURRLL51XQZURRLL510:MOV RA5,#6AHLJMP XQZURRLL51;--------------- 六XQZURRLL60:LCALL SS50mSJNB P3.6,XQZURRLL60;如果为0(不放键)等待MOV 05H,#00HLCALL DINGSHIZU;清除全部颜色选定XQZURRLL61:JNB P3.7,XQZUADD60;按加键加JNB P3.6,XQZURRLL70 ;按RRLL换下一个或返回;== MOV 05H,#70H ;选定要调的颜色LCALL DINGSHIZU7 ;选定要调的颜色LJMP XQZURRLL61 ;循环XQZUADD60:JNB P3.7,XQZUADD60 ;加键有用吗?XQZUADD61: ;有用加一次LCALL DINGSHIZU7MOV A,#6CHCJNE A,RA6,XQZURRLL610MOV RA6,#60HLJMP XQZURRLL61XQZURRLL610:MOV RA6,#6CHLJMP XQZURRLL61;--------------- 日XQZURRLL70:LCALL SS50mSJNB P3.6,XQZURRLL70;如果为0(不放键)等待MOV 05H,#00HLCALL DINGSHIZU;清除全部颜色选定XQZURRLL71:JNB P3.7,XQZUADD70;按加键加JNB P3.6,XQZURRLL80 ;按RRLL换下一个或返回;== MOV 05H,#70H ;选定要调的颜色LCALL DINGSHIZU8 ;选定要调的颜色LJMP XQZURRLL71 ;循环XQZURRLL80:LCALL BCXHLJMP ALSET1XQZUADD70:JNB P3.7,XQZUADD70 ;加键有用吗?XQZUADD71: ;有用加一次LCALL DINGSHIZU8MOV A,#6EHCJNE A,RA7,XQZURRLL710MOV RA7,#60HLJMP XQZURRLL71XQZURRLL710:MOV RA7,#6EHLJMP XQZURRLL71;++++++++++++写入显示++++++++++++XRXS:MOV A,#62HCJNE A,RA,XRXS1MOV DPTR,#10HLCALL XRXSBRETXRXS1:MOV A,#64HCJNE A,RA,XRXS2MOV DPTR,#20HLCALL XRXSBRETXRXS2:MOV A,#66HCJNE A,RA,XRXS3MOV DPTR,#30HLCALL XRXSBRETXRXS3:MOV A,#68H CJNE A,RA,XRXS4 MOV DPTR,#40H LCALL XRXSB RETXRXS4:MOV A,#6AH CJNE A,RA,XRXS5 MOV DPTR,#50H LCALL XRXSB RETXRXS5:MOV A,#6CH CJNE A,RA,XRXS6 MOV DPTR,#60H LCALL XRXSB RETXRXS6:MOV A,#6EH CJNE A,RA,XRXS7 MOV DPTR,#70H LCALL XRXSB RETXRXS7:RET;--------------- XRXSB:MOV R0,#71H MOV R6,#0FH XRXSB1:MOVX A,@DPTR MOV @R0,AINC DPTRINC R0DJNZ R6,XRXSB1RET;++++++++保存显示++++++++++++++++ BCXH:MOV A,#62HCJNE A,RA,BCXH1MOV DPTR,#10HLCALL BCXHBRETBCXH1:MOV A,#64HCJNE A,RA,BCXH2MOV DPTR,#20HLCALL BCXHBRETBCXH2:MOV A,#66HCJNE A,RA,BCXH3MOV DPTR,#30HLCALL BCXHBRETBCXH3:MOV A,#68HCJNE A,RA,BCXH4MOV DPTR,#40HLCALL BCXHBRETBCXH4:MOV A,#6AHCJNE A,RA,BCXH5MOV DPTR,#50HLCALL BCXHBRETBCXH5:MOV A,#6CHCJNE A,RA,BCXH6MOV DPTR,#60HLCALL BCXHBRETBCXH6:MOV A,#6EHCJNE A,RA,BCXH7MOV DPTR,#70HLCALL BCXHBRETBCXH7:RET;------------BCXHB:MOV R0,#71HMOV R6,#0FHBCXHB1:MOV A,@R0MOVX @DPTR,AINC R0INC DPTRDJNZ R6,BCXHB1RET;------------TEST累加处理程序-------------- MINCJM:MOV A,#44HCJNE A,RR4,REDMOV RR4,#30HINC RR5 ;分INC RR5MOV A,#3CHCJNE A,RR5,REDRETHRCJM: ;时MOV A,#34HCJNE A,RR7,HRCJM2 MOV A,#38HCJNE A,RR6,HRCJM3 MOV RR6,#30HMOV RR7,#30H HRCJM3:RETHRCJM2:MOV A,#44HCJNE A,RR6,HRCJM3 MOV RR6,#30HINC RR7INC RR7RETXQCJM: ;星期MOV A,#5BHCJNE A,RR8,REDMOV RR8,#4DH RED:MOV R3,#00HRET;-----------中断子程序------ TI1:PUSH 0E0HMOV TL1,#0CHMOV TH1,#04HINC RR1CJNE A,RR1,RESETB P2.7MOV RR1,#00HINC RR2 ;秒1 INC RR2MOV A,#44HCJNE A,RR2,REMOV RR2,#30HINC RR3 ;秒2 INC RR3MOV A,#3CHCJNE A,RR3,REMOV RR3,#30HINC RR4 ;分1 INC RR4MOV A,#44HCJNE A,RR4,REMOV RR4,#30HINC RR5 ;分2 INC RR5MOV A,#3CHCJNE A,RR5,REMOV RR5,#30HINC RR6 ;时1 INC RR6MOV A,#34HCJNE A,RR7,HR2MOV A,#38HCJNE A,RR6,REMOV RR6,#30HMOV RR7,#30HINC RR8INC RR8MOV A,#5BHCJNE A,RR8,REXQXMOV RR8,#4DHLJMP REXQXHR2:MOV A,#44HCJNE A,RR6,REMOV RR6,#30HINC RR7INC RR7RE:POP 0E0HRETIREXQX:LCALL XPX ;星期几POP 0E0HRETI;============遥控外部中断处理程序=================== ITT00: ;外部中断处理程序PUSH 0E0HSETB RS1SETB RS0MOV R6,#0CHITT001:LCALL SS700uSJB P3.2,ITTREDJNZ R6,ITT001MOV TL0,#00H ;计时中断装入MOV TH0,#00HJNB P3.2,$ITT002:MOV R6,#05HITT003:LCALL SS700uSJNB P3.2,ITTREDJNZ R6,ITT003JB P3.2,$MOV R5,TH0MOV TL0,#00H ;计时中断装入MOV A,R5CLR CSUBB A,#32JC ITTREMOV A,R5SUBB A,#38JNC ITTREMOV R7,#04HITT8:MOV R6,#08HITT:LCALL SS700uSJNB P3.2,ITTREJB P3.2,$MOV R5,TH0MOV TL0,#00H ;计时中断装入MOV TH0,#00HMOV A,R5CLR CSUBB A,#06JC XE0XE1:MOV A,R0SETB CRLC AMOV R0,ALJMP ITT1XE0:MOV A,R0CLR CRLC AMOV R0,AITT1:CLR CDJNZ R6,ITTMOV 5FH,R0DJNZ R7,ITT8ITTRE:CLR RS1CLR RS0POP 0E0HRETI;===========地址定义=========================== XSU:;--------时间的地址写入--------MOV DPTR,#LCD24400MOV SU00,DPH ;数字2440-0的MOV SU01,DPLMOV DPTR,#LCD24401MOV SU10,DPH ;数字2440-1的MOV SU11,DPLMOV DPTR,#LCD24402MOV SU20,DPH ;数字2440-2的MOV SU21,DPLMOV DPTR,#LCD24403MOV SU30,DPH ;数字2440-3的MOV SU31,DPLMOV DPTR,#LCD24404MOV SU40,DPH ;数字2440-4的MOV SU41,DPLMOV DPTR,#LCD24405MOV SU50,DPH ;数字2440-5的MOV SU51,DPLMOV DPTR,#LCD24406MOV SU60,DPH ;数字2440-6的MOV SU61,DPLMOV DPTR,#LCD24407MOV SU70,DPHMOV SU71,DPL ;数字2440-7的MOV SU80,DPHMOV SU81,DPL ;数字2440-8的MOV DPTR,#LCD24409MOV SU90,DPH ;数字2440-9的MOV SU91,DPL;----------星期?的地址写入--------------MOV DPTR,#LCD3232RMOV SUZR0,DPH ;星期日的MOV SUZR1,DPLMOV DPTR,#LCD32321MOV SUZ10,DPH ;星期一的MOV SUZ11,DPLMOV DPTR,#LCD32322MOV SUZ20,DPH ;星期二的MOV SUZ21,DPLMOV DPTR,#LCD32323MOV SUZ30,DPH ;星期三的MOV SUZ31,DPLMOV DPTR,#LCD32324MOV SUZ40,DPH ;星期四的MOV SUZ41,DPLMOV DPTR,#LCD32325MOV SUZ50,DPH ;星期五的MOV SUZ51,DPLMOV DPTR,#LCD32326MOV SUZ60,DPH ;星期六的MOV SUZ61,DPL;----------定时星期?的地址写入-------------- MOV DPTR,#LCD1616GMOV GUAN0,DPH ;数字1616-关MOV GUAN1,DPLMOV DPTR,#LCD16161MOV SL10,DPH ;数字1616-一的MOV SL11,DPLMOV DPTR,#LCD16162MOV SL20,DPH ;数字1616-二的MOV SL21,DPLMOV SL30,DPH ;数字1616-三的MOV SL31,DPLMOV DPTR,#LCD16164MOV SL40,DPH ;数字1616-四的MOV SL41,DPLMOV DPTR,#LCD16165MOV SL50,DPH ;数字1616-五的MOV SL51,DPLMOV DPTR,#LCD16166MOV SL60,DPH ;数字1616-六的MOV SL61,DPLMOV DPTR,#LCD1616RMOV SL70,DPH ;数字1616-日的MOV SL71,DPL;=========定义寄出存器地址指定========== ;----------时间的-------------MOV R6,#6MOV R0,#46HCCRR:MOV @R0,#30HINC R0DJNZ R6,CCRR;---------温度的-------------MOV WD1,#30HMOV WD2,#30HMOV WD3,#30HMOV WD4,#3FH;-----------星期?的---------------MOV RR8,#4DH;----------定时的--一组-----------STC:MOV 8EH,#00HMOV DPTR,#10HMOV A,#30HMOV R6,#08MOV R5,#08STC1:MOVX @DPTR,AINC DPTRDJNZ R6,STC1MOV R6,#08MOV A,#60HSTC2:MOVX @DPTR,AINC DPTRDJNZ R6,STC2MOV R6,#08MOV A,#30HDJNZ R5,STC1MOV RAL0,#30H ;左MOV RAL1,#30H ;MOV RAL2,#30H ;MOV RAL3,#30H ;MOV RAR0,#30H ;右MOV RAR1,#30H ;MOV RAR2,#30H ;MOV RAR3,#30H ;MOV RA,#62H ; ;组MOV RA1,#62H ; 一MOV RA2,#64H ; 二MOV RA3,#66H ; 三MOV RA4,#68H ; 四MOV RA5,#6AH ; 五MOV RA6,#6CH ; 六MOV RA7,#6EH ; 日LJMP MAIN;===========中断设定============TIR0:SETB EASETB ET1SETB PT1SETB ET0 ;打开计时中断SETB EX0 ;打开外部中断SETB IT0 ;外部为边沿触发方式SETB TR0 ;开启计时中断MOV TMOD,#19HMOV TL1,#0CHMOV TH1,#04HMOV TL0,#00H ;计时中断装入MOV TH0,#00HSETB TR1RET;==============扫描桌面=========================;======================================================;==============活动字符================================;-------星期--------MOV R1,#00H ;写命高位令数MOV R3,#00H ;写高位数据数MOV R0,#04H ;命令与数据的总数50 51 52 53 20 21 22(22要分开)XPX:MOV DPTR,#LCDK32325 ;要写的数据与命令组LCALL LCDK ;写命令,与数据MOV R0,RR8MOV DPH,@R0INC R0MOV DPL,@R0LCALL LCDL3232RET;---------------------------;----------温度显示--------------------;-------温度左第1位--------WINDU:MOV DPTR,#LCDK24400 ;要写的数据与命令组LCALL LCDK ;写命令,与数据MOV R0,WD1MOV DPH,@R0INC R0MOV DPL,@R0LCALL LCDL2440;-------温度左第2位--------MOV DPTR,#LCDK24401 ;要写的数据与命令组LCALL LCDK ;写命令,与数据MOV R0,WD2MOV DPH,@R0INC R0MOV DPL,@R0LCALL LCDL2440;-------温度左第3位--------MOV DPTR,#LCDK24402 ;要写的数据与命令组LCALL LCDK ;写命令,与数据MOV R0,WD3MOV DPH,@R0INC R0MOV DPL,@R0LCALL LCDL2440;-------温度正负--------MOV DPTR,#LCDK24403 ;要写的数据与命令组LCALL LCDK ;写命令,与数据MOV R4,WD4LCALL WENDULCDLHRET;------------------------------;-----------时间显示-----------------;-----时间--左第1位,时位--------SHIJIAN:LCALL SS5mSMOV DPTR,#LCDK32480 ;要写的数据与命令组LCALL LCDK ;写命令,与数据MOV R0,RR7MOV DPH,@R0INC R0MOV DPL,@R0LCALL LCDL2440;-----时间--左第2位,时位--------MOV DPTR,#LCDK32481 ;要写的数据与命令组LCALL LCDK ;写命令,与数据MOV R0,RR6MOV DPH,@R0INC R0MOV DPL,@R0LCALL LCDL2440;-----时间--左第3位,分位--------MOV DPTR,#LCDK32482 ;要写的数据与命令组LCALL LCDK ;写命令,与数据MOV R0,RR5MOV DPH,@R0INC R0MOV DPL,@R0LCALL LCDL2440;-----时间--左第4位,分位--------MOV DPTR,#LCDK32483 ;要写的数据与命令组LCALL LCDK ;写命令,与数据MOV R0,RR4MOV DPH,@R0INC R0MOV DPL,@R0LCALL LCDL2440;------时间--左第5位,秒位--------MOV DPTR,#LCDK2440L ;要写的数据与命令组LCALL LCDK ;写命令,与数据MOV R0,RR3MOV DPH,@R0INC R0MOV DPL,@R0LCALL LCDL2440;------时间--左第6位,秒位--------MOV DPTR,#LCDK2440R ;要写的数据与命令组LCALL LCDK ;写命令,与数据MOV R0,RR2MOV DPH,@R0INC R0MOV DPL,@R0LCALL LCDL2440RET;----------------------------------------;---------------遥控彩块-显示------------------;---------遥控彩块--左1位-------------------------- YAOKONG:MOV 2FH,#00HMOV 2EH,#00HLCALL YAOKONG1LCALL YAOKONG2LCALL YAOKONG3LCALL YAOKONG4LCALL YAOKONG5LCALL YAOKONG6LCALL YAOKONG7LCALL YAOKONG8LCALL YAOKONG9LCALL YAOKONG0RET;-------------------YAOKONG1:MOV DPTR,#LCDK24241 ;要写的数据与命令组JNB 7FH,YAOKONG10CLR 7FHSETB P1.0LCALL LCDK ;写命令,与数据LCALL LCDLL ;写红的LCDLLRETYAOKONG10:SETB 7FH。
;单片机DS18B20温度计C语言程序; 有程序#include<reg51.h>#include<intrins.h>#include <math.H> //要用到取绝对值函数abs()//通过DS18B20测试当前环境温度, 并通过数码管显示当前温度值, 目前显示范围: -55~ +125度sbit wela = P2^7; //数码管位选sbit dula = P2^6; //数码管段选sbit ds = P2^2;int tempValue;//0-F数码管的编码(共阳极)unsigned char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};//0-9数码管的编码(共阳极), 带小数点unsigned char code tableWidthDot[]={0x40, 0x79, 0x24, 0x30,0x19, 0x12, 0x02,0x78, 0x00, 0x10};//延时函数, 对于11.0592MHz时钟, 例i=10,则大概延时10ms.void delay(unsigned int i){unsigned int j;while(i--){for(j = 0; j < 125; j++);}}//初始化DS18B20//让DS18B20一段相对长时间低电平, 然后一段相对非常短时间高电平, 即可启动 void dsInit(){//对于11.0592MHz时钟, unsigned int型的i, 作一个i++操作的时间大于?us unsigned int i;ds = 0;i = 100; //拉低约800us, 符合协议要求的480us以上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--;}//向DS18B20读取一位数据//读一位, 让DS18B20一小周期低电平, 然后两小周期高电平,//之后DS18B20则会输出持续一段时间的一位数据bit readBit(){unsigned int i;bit b;ds = 0;i++; //延时约8us, 符合协议要求至少保持1usds = 1;i++; i++; //延时约16us, 符合协议要求的至少延时15us以上b = ds;i = 8;while(i>0) i--; //延时约64us, 符合读时隙不低于60us要求return b;}//读取一字节数据, 通过调用readBit()来实现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;}//向DS18B20写入一字节数据void writeByte(unsigned char dat){unsigned int i;unsigned char j;bit b;for(j = 0; j < 8; j++){b = dat & 0x01;dat >>= 1;//写"1", 将DQ拉低15us后, 在15us~60us内将DQ拉高, 即完成写1if(b){ds = 0;i++; i++; //拉低约16us, 符号要求15~60us内ds = 1;i = 8; while(i>0) i--; //延时约64us, 符合写时隙不低于60us要求}else //写"0", 将DQ拉低60us~120usds = 0;i = 8; while(i>0) i--; //拉低约64us, 符号要求ds = 1;i++; i++; //整个写0时隙过程已经超过60us, 这里就不用像写1那样, 再延时64us 了}}//向DS18B20发送温度转换命令void sendChangeCmd(){dsInit(); //初始化DS18B20, 无论什么命令, 首先都要发起初始化dsWait(); //等待DS18B20应答delay(1); //延时1ms, 因为DS18B20会拉低DQ 60~240us作为应答信号writeByte(0xcc); //写入跳过序列号命令字Skip RomwriteByte(0x44); //写入温度转换命令字Convert T}//向DS18B20发送读取数据命令void sendReadCmd(){dsInit();dsWait();delay(1);writeByte(0xcc); //写入跳过序列号命令字Skip RomwriteByte(0xbe); //写入读取数据令字Read Scratchpad}//获取当前温度值int getTmpValue(){unsigned int tmpvalue;int value; //存放温度数值float t;unsigned char low, high;sendReadCmd();//连续读取两个字节数据low = readByte();high = readByte();//将高低两个字节合成一个整形变量//计算机中对于负数是利用补码来表示的//若是负值, 读取出来的数值是用补码表示的, 可直接赋值给int型的valuetmpvalue = high;tmpvalue <<= 8;tmpvalue |= low;value = tmpvalue;//使用DS18B20的默认分辨率12位, 精确度为0.0625度, 即读回数据的最低位代表0.0625度t = value * 0.0625;//将它放大100倍, 使显示时可显示小数点后两位, 并对小数点后第三进行4舍5入//如t=11.0625, 进行计数后, 得到value = 1106, 即11.06 度//如t=-11.0625, 进行计数后, 得到value = -1106, 即-11.06 度value = t * 100 + (value > 0 ? 0.5 : -0.5); //大于0加0.5, 小于0减0.5return value;}unsigned char const timeCount = 3; //动态扫描的时间间隔//显示当前温度值, 精确到小数点后一位//若先位选再段选, 由于IO口默认输出高电平, 所以当先位选会使数码管出现乱码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;if(v < 0){//关位选, 去除对上一位的影响P0 = 0xff;wela = 0;//段选P0 = 0x40; //显示"-"号dula = 1; //打开锁存, 给它一个下降沿量dula = 0;//位选P0 = 0xfe;wela = 1; //打开锁存, 给它一个下降沿量wela = 0;delay(timeCount);}for(count = 0; count != 5; count++){//关位选, 去除对上一位的影响P0 = 0xff;wela = 1; //打开锁存, 给它一个下降沿量wela = 0;//段选if(count != 2){P0 = table[datas[count]]; //显示数字}else{P0 = tableWidthDot[datas[count]]; //显示带小数点数字}dula = 0;//位选P0 = _crol_(0xfd, count); //选择第(count + 1) 个数码管wela = 1; //打开锁存, 给它一个下降沿量wela = 0;delay(timeCount);}}void main(){unsigned char i;while(1){//启动温度转换sendChangeCmd();//显示5次for(i = 0; i < 40; i++){display(tempValue);}tempValue = getTmpValue();}以下是我编的程序,可用#include <reg52.h>#include <intrins.h>//-----------------------------------------------------------sbit DQ=P1^5;//-----------------------------------------------------------unsigned char number[10]={0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F};//数字0~9unsigned char wei[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //数码管位循环unsigned char Flag;unsigned char Templ,Temph;unsigned int temp;//-----------------------------------------------------------//函数声明//-----------------------------------------------------------void delay(unsigned char i); //延时程序//----------------------------------void Int18b20(void); //18b20初始化void Write18b20(unsigned char dat); //向18b20写一字节unsigned char Read18b20(void); //从18b20读一字节void Start18b20(void); //开始转换温度void Get18b20(void); //读出温度void chinT(void); //数据转换//----------------------------------void display(void); //显示程序//-----------------------------------------------------------//函数功能:延时//-----------------------------------------------------------/*************精确延时函数*****************/void delay(unsigned char i){while(--i);}/*此延时函数针对的是12Mhz的晶振delay(0); //延时518us 误差:518-2*256=6delay(1); //延时7us (原帖写"5us"是错的)delay(10); //延时25us 误差:25-20=5delay(20); //延时45us 误差:45-40=5delay(100); //延时205us 误差:205-200=5delay(200); //延时405us 误差:405-400=5*///-----------------------------------------------------------//DS18b20的相关程序//-----------------------------------------------------------//初始化//-----------------------------------------------------------void Int18b20(void){DQ=1;_nop_();_nop_();DQ=0; //拉低delay(100); //延时205usdelay(200); //延时405us //等待400~960微秒,最短为480us DQ=1;delay(1); //延时7usdelay(20); //延时45us //等待15~60微秒(等待回复)if(DQ==1) //判断初始化的情况是否成功{Flag=0; //复位失败}else{Flag=1;while(!DQ); //等待回复完成}delay(200); //延时405us //等待完成初始化}//-----------------------------------------------------------//写一字节//-----------------------------------------------------------void Write18b20(unsigned char dat){unsigned char i;for(i=0;i<8;i++){DQ=1;_nop_();DQ=0;delay(1); //延时7us //拉低后延时小于15usif(dat&0x01){DQ=1;}else{DQ=0;}dat=dat>>1;delay(20); //延时45usdelay(10); //延时25us //延时大于60usDQ=1;delay(1); //延时7us //延时大于1us}}//-----------------------------------------------------------//读一字节//-----------------------------------------------------------unsigned char Read18b20(void){unsigned char i,dat=0;for(i=0;i<8;i++){DQ=1;_nop_();DQ=0;delay(1); //延时7usdat=dat>>1;DQ=1;delay(1); //延时7us //确保在15us后60us前读数据if(DQ){dat|=0x80;}delay(20); //延时45us //确保读时续大于60us}return dat;}//-----------------------------------------------------------//开始转换温度//-----------------------------------------------------------void Start18b20(void){Int18b20();Write18b20(0xcc); //跳过ROM指令Write18b20(0x44); //温度转换指令}//-----------------------------------------------------------//读出温度//-----------------------------------------------------------void Get18b20(void){Int18b20();Write18b20(0xcc); //跳过ROM指令Write18b20(0xbe); //读暂存器指令Templ=Read18b20();Temph=Read18b20();}//-----------------------------------------------------------//数据转换//-----------------------------------------------------------void chinT(void){float Tt;temp=Temph; //先把高八位有效数据赋于temptemp=(temp<<8); //将数据从temp低八位移到高八位temp=temp|Templ; //将两字节合成一个整型变量Tt=temp*0.0625; //得到真实十进制温度值(因为DS18B20可以精确到0.0625度) temp=Tt*10+0.5; //放大十倍(将小数点后一位变成个位,个位变成十位,十位变成百位,并四舍五入)}//-----------------------------------------------------------//显示程序//-----------------------------------------------------------void display(void){unsigned int i;unsigned char A1,A2,A3;A1=temp/100; //百位(温度的十位)A2=temp%100/10; //十位(温度的个位)A3=temp%10; //个位(温度的小数点后一位)for(i=0;i<20;i++){P0=0x00;P2=0x00;P0=number[A1];P2=wei[0];delay(220);P0=0x00;P2=0x00;P0=number[A2];P2=wei[1];delay(220);P0=0x00;P2=0x00;P0=number[A3];P2=wei[2];delay(220);P0=0x00;P2=0x00;P0=0x80;P2=wei[1];delay(220);}}//-----------------------------------------------------------//----------------------------------------------------------- void main(void){while(1){Int18b20();if(Flag){Start18b20(); //开始转换温度Get18b20(); //得到温度chinT(); //数据转换display(); //显示}else P3=0x01;}}。
单片机温控程序设计一个单片机温控程序涉及多个方面,包括传感器的接口、温度采集、控制算法、显示等。
以下是一个简要的单片机温控程序的设计示例,具体实现可能依赖于使用的单片机型号、传感器型号等。
1. 硬件设计a. 传感器接口选择合适的温度传感器,比如常用的DS18B20数字温度传感器。
连接传感器的引脚到单片机的GPIO口。
c// DS18B20传感器连接// VCC -> 单片机电源// GND -> 单片机地// DQ -> 单片机GPIO口b. 输出控制选择用于控制的输出设备,如继电器、加热器、风扇等。
连接输出设备的引脚到单片机的GPIO口。
c// 控制设备连接// 继电器、加热器、风扇等的控制引脚连接到单片机GPIO口c. 显示设备如果需要显示当前温度或其他信息,可以选择合适的显示设备,如数码管、LCD等。
c// 显示设备连接// 数码管、LCD等的引脚连接到单片机GPIO口2. 软件设计a. 温度采集使用单片机的GPIO口读取温度传感器的数据,获取当前环境温度。
c// 读取DS18B20传感器温度数据float readTemperature(){// 实现读取DS18B20数据的代码// 返回浮点数温度值}b. 控制算法根据采集到的温度数据,实现控制算法。
比如,当温度过高时打开风扇或者关闭加热器。
c// 温控算法void temperatureControl(float currentTemperature){float targetTemperature =25.0;// 目标温度float hysteresis =1.0;// 温度死区if(currentTemperature >targetTemperature +hysteresis){// 温度过高,执行降温操作,比如打开风扇turnOnFan();}else if(currentTemperature <targetTemperature -hysteresis){// 温度过低,执行升温操作,比如关闭风扇、打开加热器turnOffFan();turnOnHeater();}else{// 温度在目标范围内,保持当前状态turnOffFan();turnOffHeater();}}c. 控制设备根据控制算法的结果,控制相应的输出设备。
用单片机显示温度的汇编程序一、引言在现代科技发展的背景下,温度的测量和显示变得越来越重要。
而单片机作为一种集成电路,具有高效、可靠、灵活等特点,被广泛应用于温度测量和显示领域。
本文将以汇编语言为主,介绍如何使用单片机实现温度的测量和显示。
二、硬件准备我们需要准备相应的硬件设备。
主要包括:单片机、温度传感器、数码管等。
其中,单片机是核心控制器,温度传感器用于测量温度,数码管用于显示温度数值。
三、软件准备在开始编写汇编程序之前,我们需要安装相应的开发工具和编译器。
常用的开发工具有Keil、IAR等,编译器可以选择C51等。
四、编写汇编程序1. 初始化在汇编程序中,首先需要进行初始化操作。
具体步骤如下:(1)设置端口:将数码管所在的端口设置为输出模式,用于控制数码管的显示。
(2)初始化温度传感器:根据具体型号和通信协议,进行相应的初始化设置。
2. 温度测量在初始化完成后,可以开始进行温度的测量。
具体步骤如下:(1)启动温度传感器:发送启动命令,使传感器开始工作。
(2)等待温度传感器完成测量:根据传感器的特性,等待一定的时间,使传感器完成温度的测量。
(3)读取温度值:将传感器测量到的温度值读取到寄存器中。
3. 温度显示在获取到温度值后,可以开始进行温度的显示。
具体步骤如下:(1)将温度值转换为数码管所需的显示格式:根据实际需要,将温度值进行转换,转换为数码管可以显示的格式。
(2)将转换后的数值依次发送到数码管:根据数码管的接口协议,将转换后的数值依次发送到数码管,使其显示温度数值。
五、调试与测试在编写完成汇编程序后,需要进行调试和测试,以确保程序运行正常。
可以通过连接单片机和电脑进行调试,观察温度数值是否正确显示在数码管上。
六、总结本文以汇编语言为主,介绍了使用单片机显示温度的方法。
通过编写汇编程序,实现了温度的测量和显示功能,将温度数值准确地显示在数码管上。
这种方法在温度测量和显示领域具有广泛的应用前景,可以满足各种温度监测和控制的需求。
//DS18B20的读写程序,数据脚P3.3 ////温度传感器18B20汇编程序,采用器件默认的12位转化////最大转化时间750微秒,显示温度-55到+125度,显示精度////为0.1度,显示采用4位LED共阳显示测温值////P0口为段码输入,P24~P27为位选///***************************************************/#include "reg51.h"#include "intrins.h" //_nop_();延时函数用#define Disdata P0 //段码输出口#define discan P2 //扫描口#define uchar unsigned char#define uint unsigned intsbit DQ=P3^3; //温度输入口sbit DIN=P0^7; //LED小数点控制uint h;uchar flag;//**************温度小数部分用查表法***********//uchar code ditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};//uchar code dis_7[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};//共阳LED段码表"0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "不亮" "-" uchar code scan_con[4]={0x7f,0xbf,0xdf,0xef}; //列扫描控制字uchar data temp_data[2]={0x00,0x00}; //读出温度暂放uchar data display[5]={0x00,0x00,0x00,0x00,0x00}; //显示单元数据,共4个数据和一个运算暂用///////***********11微秒延时函数**********///void delay(uint t){for(;t>0;t--);}///***********显示扫描函数**********/scan(){char k;for(k=0;k<4;k++) //四位LED扫描控制{Disdata=0xff;Disdata=dis_7[display[k]];if(k==1){DIN=0;}discan=scan_con[k];delay(90);discan=0xff;}}/////***********18B20复位函数**********/ow_reset(void){char presence=1;while(presence){while(presence){DQ=1;_nop_();_nop_();DQ=0; //delay(50); // 550usDQ=1; //delay(6); // 66uspresence=DQ; // presence=0继续下一步}delay(45); //延时500uspresence = ~DQ;}DQ=1;}/////**********18B20写命令函数*********///向1-WIRE 总线上写一个字节void write_byte(uchar val){uchar i;for (i=8; i>0; i--) //{DQ=1;_nop_();_nop_();DQ = 0;_nop_();_nop_();_nop_();_nop_();_nop_();//5us DQ = val&0x01; //最低位移出delay(6); //66usval=val/2; //右移一位}DQ = 1;delay(1);}///*********18B20读1个字节函数********///从总线上读取一个字节uchar read_byte(void){uchar i;uchar value = 0;for (i=8;i>0;i--){DQ=1;_nop_();_nop_();value>>=1;DQ = 0; //_nop_();_nop_();_nop_();_nop_(); //4usDQ = 1;_nop_();_nop_();_nop_();_nop_(); //4us if(DQ)value|=0x80;delay(6); //66us}DQ=1;return(value);}///***********读出温度函数**********///read_temp(){ow_reset(); //总线复位write_byte(0xCC); // 发Skip ROM命令write_byte(0xBE); // 发读命令temp_data[0]=read_byte(); //温度低8位temp_data[1]=read_byte(); //温度高8位ow_reset();write_byte(0xCC); // Skip ROMwrite_byte(0x44); // 发转换命令}///***********温度数据处理函数**********/ void work_temp(){uchar n=0;uchar doth,dotl;uchar flag3=1,flag2=1; //数字显示修正标记if((temp_data[1]&0xf8)!=0x00){temp_data[1]=~(temp_data[1]);temp_data[0]=~(temp_data[0])+1;n=1;flag=1;}//负温度求补码if(temp_data[0]>255){temp_data[1]++;}display[4]=temp_data[0]&0x0f;display[0]=ditab[display[4]];doth=display[0]/10;dotl=display[0]%10;display[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x07)<<4); display[3]=display[4]/100;display[2]=display[4]/10%10;display[1]=display[4]%10;if(!display[3]){display[3]=0x0a;flag3=0;if(!display[2]){display[2]=0x0a;flag2=0;}}//最高位为0时都不显示if(n){display[3]=0x0b;//负温度时最高位显示"-"flag3=0;}}/////**************主函数****************/main(){Disdata=0xff; //初始化端口discan=0xff;for(h=0;h<4;h++){display[h]=8;}//开机显示8888ow_reset(); // 开机先转换一次write_byte(0xCC); // Skip ROMwrite_byte(0x44); // 发转换命令for(h=0;h<500;h++){scan();} //开机显示"8888"2秒while(1){read_temp(); //读出18B20温度数据work_temp(); //处理温度数据scan(); //显示温度值2秒}}////*********************结束**************************//。
TEMP_ZH EQU 24H ;实测温度值存放单元TEMPL EQU 25HTEMPH EQU 26HTEMP_TH EQU 27H ;高温报警值存放单元TEMP_TL EQU 28H ;低温报警值存放单元TEMPHC EQU 29H ;正、负温度值标记TEMPLC EQU 2AHTEMPFC EQU 2BHK1 EQU P1.4 ;查询按键K2 EQU P1.5 ;设置/调整键K3 EQU P1.6 ;调整键K4 EQU P1.7 ;确定键BEEP EQU P3.7 ;蜂鸣器RELAY EQU P1.3 ;指示灯LCD_X EQU 2FH ;LCD 字符显示位置LCD_RS EQU P2.0 ;LCD 寄存器选择信号 LCD_RW EQU P2.1 ;LCD 读写信号LCD_EN EQU P2.2 ;LCD 允许信号FLAG1 EQU 20H.0 ;DS18B20是否存在标志 KEY_UD EQU 20H.1 ;设定按键的增、减标志 DQ EQU P3.3 ;DS18B20数据信号ORG 0000HLJMP MAINORG 0030HMAIN: MOV SP,#60HMOV A,#00HMOV R0,#20H ;将20H~2FH 单元清零MOV R1,#10HCLEAR: MOV @R0,AINC R0DJNZ R1,CLEARLCALL SET_LCDLCALL RE_18B20START: LCALL RST ;调用18B20复位子程序JNB FLAG1,START1 ;DS1820不存在LCALL MENU_OK ;DS1820存在,调用显示正确信息子程序MOV TEMP_TH,#055H ;设置TH初值85度MOV TEMP_TL,#019H ;设置TL初值25度LCALL RE_18B20A ;调用暂存器操作子程序LCALL WRITE_E2 ;写入DS18B20LCALL TEMP_BJ ;显示温度标记JMP START2START1: LCALL MENU_ERROR ;调用显示出错信息子程序 LCALL TEMP_BJ ;显示温度标记SJMP $START2: LCALL RST ;调用DS18B20复位子程序JNB FLAG1,START1 ;DS18B20不存在MOV A,#0CCH ;跳过ROM匹配命令LCALL WRITEMOV A,#44H ;温度转换命令LCALL WRITELCALL RSTMOV A,#0CCH ;跳过ROM匹配LCALL WRITEMOV A,#0BEH ;读温度命令LCALL WRITELCALL READ ;调用DS18B20数据读取操作子程序LCALL CONVTEMP ;调用温度数据BCD 码处理子程序LCALL DISPBCD ;调用温度数据显示子程序LCALL CONV ;调用LCD显示处理子程序LCALL TEMP_COMP ;调用实测温度值与设定温度值比较子程序LCALL PROC_KEY ;调用键扫描子程序SJMP START2 ;循环;*************************** 键扫描子程序*****************************PROC_KEY:JB K1,PROC_K1LCALL BEEP_BLJNB K1,$MOV DPTR,#M_ALAX1MOV A,#1LCALL LCD_PRINTLCALL LOOK_ALARMJB K3,$LCALL BEEP_BLJMP PROC_K2PROC_K1: JB K2,PROC_ENDLCALL BEEP_BLJNB K2,$MOV DPTR,#RST_A1MOV A,#1LCALL LCD_PRINTLCALL SET_ALARMLCALL RE_18B20 ;将设定的TH,TL值写入DS18B20LCALL WRITE_E2PROC_K2: LCALL MENU_OKLCALL TEMP_BJPROC_END:RET;*************************** 设定温度报警值TH、TL ***************************SET_ALARM:LCALL LOOK_ALARMAS0: JB K1,AS00LCALL BEEP_BLJNB K1,$CPL 20H.1 ;UP/DOWN 标记AS00: JB 20H.1,ASZ01 ;20H.1=1,增加JMP ASJ01 ;20H.1=0,减小ASZ01: JB K2,ASZ02 ;TH值调整(增加)LCALL BEEP_BLINC TEMP_THMOV A,TEMP_THCJNE A,#120,ASZ011MOV TEMP_TH,#0ASZ011: LCALL LOOK_ALARMLCALL DELAYJMP ASZ01ASZ02: JB K3,ASZ03 ;TL值调整(增加) LCALL BEEP_BLINC TEMP_TLMOV A,TEMP_TLCJNE A,#99,ASZ021MOV TEMP_TL,#00HASZ021: LCALL LOOK_ALARMMOV R5,#10LCALL DELAYJMP ASZ02ASZ03: JB K4,AS0 ;确定调整LCALL BEEP_BLJNB K4,$RETASJ01: JB K2,ASJ02 ;TH值调整(减少) LCALL BEEP_BLDEC TEMP_THMOV A,TEMP_THCJNE A,#0FFH,ASJ011ASJ011: LCALL LOOK_ALARMMOV R5,#10LCALL DELAYJMP AS0ASJ02: JB K3,ASJ03 ;TL值调整(减少)LCALL BEEP_BLDEC TEMP_TLMOV A,TEMP_TLCJNE A,#0FFH,ASJ021JMP ASJ022ASJ021: LCALL LOOK_ALARM ;MOV R5,#10LCALL DELAYJMP AS0ASJ022: CPL 20H.1JMP ASZ01ASJ03: JMP ASZ03RETRST_A1: DB " SET ALERT CODE " ,0;*********************** 实测温度值与设定温度值比较子程序**********************TEMP_COMP:MOV A,TEMP_THSUBB A,TEMP_ZH ;减数>被减数,则JC CHULI1 ;借位标志位C=1,转 MOV A,TEMPFCCJNE A,#0BH,COMPSJMP CHULI2COMP: MOV A,TEMP_ZHSUBB A,TEMP_TL ;减数>被减数,则JC CHULI2 ;借位标志位C=1,转MOV DPTR,#BJ5LCALL TEMP_BJ3CLR RELAY ;点亮指示灯RETCHULI1: MOV DPTR,#BJ3LCALL TEMP_BJ3SETB RELAY ;熄灭指示灯LCALL BEEP_BL ;蜂鸣器响RETCHULI2: MOV DPTR,#BJ4LCALL TEMP_BJ3SETB RELAY ;熄灭指示灯LCALL BEEP_BL ;蜂鸣器响RET;-----------------------------------------TEMP_BJ3: MOV A,#0CEHLCALL WCOMMOV R1,#0MOV R0,#2BBJJ3: MOV A,R1MOVC A,@A+DPTRLCALL WDATAINC R1DJNZ R0,BBJJ3RETBJ3: DB ">H"BJ4: DB "<L"BJ5: DB " !";;**************************** 显示温度标记子程序***************************TEMP_BJ: MOV A,#0CBHLCALL WCOMMOV DPTR,#BJ1 ;指针指到显示消息MOV R1,#0MOV R0,#2BBJJ1: MOV A,R1MOVC A,@A+DPTRLCALL WDATAINC R1DJNZ R0,BBJJ1RETBJ1: DB 00H,"C";******************************** 显示正确信息子程序***************************MENU_OK: MOV DPTR,#M_OK1 ;指针指到显示消息MOV A,#1 ;显示在第一行LCALL LCD_PRINTMOV DPTR,#M_OK2 ;指针指到显示消息MOV A,#2 ;显示在第一行LCALL LCD_PRINTRETM_OK1: DB " DS18B20 OK ",0M_OK2: DB " TEMP: ",0;******************************** 显示出错信息子程序***************************MENU_ERROR:MOV DPTR,#M_ERROR1 ;指针指到显示消息MOV A,#1 ;显示在第一行LCALL LCD_PRINTMOV DPTR,#M_ERROR2 ;指针指到显示消息1MOV A,#2 ;显示在第一行LCALL LCD_PRINTRETM_ERROR1: DB " DS18B20 ERROR ",0M_ERROR2: DB " TEMP: ---- ",0;****************************DS18B20复位子程序*****************************RST: SETB DQNOPCLR DQMOV R0,#6BH ;主机发出延时复位低脉冲MOV R1,#04HTSR1: DJNZ R0,$MOV R0,#6BHDJNZ R1,TSR1SETB DQ ;拉高数据线NOPNOPNOPMOV R0,#32HTSR2: JNB DQ,TSR3 ;等待DS18B20回应DJNZ R0,TSR2JMP TSR4 ; 延时TSR3: SETB FLAG1 ; 置1标志位,表示DS1820存在JMP TSR5TSR4: CLR FLAG1 ; 清0标志位,表示DS1820不存在 JMP TSR7TSR5: MOV R0,#06BHTSR6: DJNZ R0,$ ; 时序要求延时一段时间TSR7: SETB DQRET;************************ DS18B20暂存器操作子程序***************************RE_18B20:JB FLAG1,RE_18B20ARETRE_18B20A:LCALL RSTMOV A,#0CCH ;跳过ROM匹配LCALL WRITEWR_SCRAPD:MOV A,#4EH ;写暂器LCALL WRITEMOV A,TEMP_TH ;TH(报警上限)LCALL WRITEMOV A,TEMP_TL ;TL(报警下限)LCALL WRITEMOV A,#7FH ;12位精度LCALL WRITERET;************************ 复制暂存器子程序*******************************WRITE_E2:LCALL RSTMOV A,#0CCH ;跳过ROM匹配LCALL WRITEMOV A,#48H ;把暂存器里的温度报警值拷贝到EEROMLCALL WRITERET;*********************** 重读EEROM子程序********************************READ_E2:LCALL RSTMOV A,#0CCH ;跳过ROM匹配LCALL WRITEMOV A,#0B8H ;把EEROM里的温度报警值拷贝回暂存器LCALL WRITERET;************************ 将自定义字符写入LCD的CGRAM中*********************STORE_DATA:MOV A,#40HLCALL WCOMMOV R2,#08HMOV DPTR,#D_DATAMOV R3,#00HS_DATA: MOV A,R3MOVC A,@A+DPTRLCALL WDATA ;写入数据INC R3DJNZ R2,S_DATARETD_DATA: DB 0CH,12H,12H,0CH,00H,00H,00H,00H;*********************** DS18B20数据写入操作子程序************************WRITE: MOV R2,#8 ;一共8位数据CLR CWR1: CLR DQ ;开始写入DS18B20总线要处于复位(低)状态MOV R3,#07DJNZ R3,$ ;总线复位保持16微妙以上RRC A ;把一个字节DATA 分成8个BIT 环移给CMOV DQ,C ;写入一位MOV R3,#3CHDJNZ R3,$ ;等待100微妙SETB DQ ;重新释放总线NOPDJNZ R2,WR1 ;写入下一位SETB DQRET;********************** DS18B20数据读取操作子程序**************************READ: MOV R4,#4 ;将温度低位、高位、TH、TL从DS18B20中读出MOV R1,#TEMPL ;存入25H、26H、27H、28H单元RE00: MOV R2,#8RE01: CLR CYSETB DQNOPNOPCLR DQ ;读前总线保持为低NOPNOPNOPSETB DQ ;开始读总线释放MOV R3,#09 ;延时18微妙DJNZ R3,$MOV C,DQ ;从DS18B20总线读得一位MOV R3,#3CHDJNZ R3,$ ;等待100微妙RRC A ;把读得的位值环移给ADJNZ R2,RE01 ;读下一位MOV @R1,AINC R1DJNZ R4,RE00RET;************************ 温度值BCD 码处理子程序*************************CONVTEMP: MOV A,TEMPH ;判温度是否零下ANL A,#08HJZ TEMPC1 ;温度零上转CLR CMOV A,TEMPL ;二进制数求补(双字节)CPL A ;取反加1ADD A,#01HMOV TEMPL,AMOV A,TEMPHCPL AADDC A,#00HMOV TEMPH,AMOV TEMPHC,#0BH ;负温度标志MOV TEMPFC,#0BHSJMP TEMPC11TEMPC1: MOV TEMPHC,#0AH ;正温度标志MOV TEMPFC,#0AHTEMPC11: MOV A,TEMPHCSWAP AMOV TEMPHC,AMOV A,TEMPLANL A,#0FH ;乘0.0625MOV DPTR,#TEMPDOTTABMOVC A,@A+DPTRMOV TEMPLC,A ;TEMPLC LOW=小数部分 BCDMOV A,TEMPL ;整数部分ANL A,#0F0H ;取出高四位SWAP AMOV TEMPL,AMOV A,TEMPH ;取出低四位ANL A,#0FHSWAP AORL A,TEMPL ;重新组合MOV TEMP_ZH,ALCALL HEX2BCD1MOV TEMPL,AANL A,#0F0HSWAP AORL A,TEMPHC ;TEMPHC LOW = 十位数BCDMOV TEMPHC,AMOV A,TEMPLANL A,#0FHSWAP A ;TEMPLC HI = 个位数BCDORL A,TEMPLCMOV TEMPLC,AMOV A,R4JZ TEMPC12ANL A,#0FHSWAP AMOV R4,AMOV A,TEMPHC ;TEMPHC HI = 百位数BCDANL A,#0FHORL A,R4MOV TEMPHC,ATEMPC12: RET;************************ 二-十进制转换子程序*****************************HEX2BCD1: MOV B,#064HDIV ABMOV R4,AMOV A,#0AHXCH A,BDIV ABSWAP AORL A,BRETTEMPDOTTAB: DB 00H,00H,01H,01H,02H,03H,03H,04H ; 小数部分码表DB 05H,05H,06H,06H,07H,08H,08H,09H;********************** 查询温度报警值子程序***************************LOOK_ALARM: MOV DPTR,#M_ALAX2 ;指针指到显示信息区MOV A,#2 ;显示在第二行LCALL LCD_PRINTMOV A,#0C6HLCALL TEMP_BJ1MOV A,TEMP_TH ;加载TH数据MOV LCD_X,#3 ;设置显示位置LCALL SHOW_DIG2H ;显示数据MOV A,#0CEHLCALL TEMP_BJ1MOV A,TEMP_TL ;加载TL数据MOV LCD_X,#12 ;设置显示位置LCALL SHOW_DIG2L ;显示数据RETM_ALAX1: DB " LOOK ALERT CODE",0M_ALAX2: DB "TH: TL: ",0TEMP_BJ1: LCALL WCOMMOV DPTR,#BJ2 ;指针指到显示信息区 MOV R1,#0MOV R0,#2BBJJ2: MOV A,R1MOVC A,@A+DPTRLCALL WDATADJNZ R0,BBJJ2RETBJ2: DB 00H,"C";************************** LCD显示子程序**********************************SHOW_DIG2H: MOV B,#100DIV ABADD A,#30HPUSH BMOV B,LCD_XLCALL LCDP2POP BMOV A,#0AHXCH A,BDIV ABADD A,#30HINC LCD_XPUSH BMOV B,LCD_XLCALL LCDP2INC LCD_XMOV A,BMOV B,LCD_XADD A,#30HLCALL LCDP2RETSHOW_DIG2L: MOV B,#100DIV ABMOV A,#0AHXCH A,BDIV ABADD A,#30HPUSH BMOV B,LCD_XLCALL LCDP2POP BINC LCD_XMOV A,BMOV B,LCD_XADD A,#30HLCALL LCDP2RET;************************ 显示区BCD 码温度值刷新子程序**********************DISPBCD: MOV A,TEMPLCANL A,#0FHMOV 70H,A ;小数位MOV A,TEMPLCSWAP AANL A,#0FHMOV 71H,A ;个位MOV A,TEMPHCANL A,#0FHMOV 72H,A ;十位MOV A,TEMPHCSWAP AANL A,#0FHMOV 73H,A ;百位DISPBCD2: RET;*************************** LCD 显示数据处理子程序*************************CONV: MOV A,73H ;加载百位数据MOV LCD_X,#6 ;设置位置CJNE A,#1,CONV1JMP CONV2CONV1: CJNE A,#0BH,CONV11MOV A,#"-" ;"-"号显示JMP CONV111CONV11: MOV A,#" " ;"+"号不显示CONV111: MOV B,LCD_XLCALL LCDP2JMP CONV3CONV2: LCALL SHOW_DIG2 ;显示数据CONV3: INC LCD_XMOV A,72H ;十位LCALL SHOW_DIG2INC LCD_XMOV A,71H ;个位LCALL SHOW_DIG2INC LCD_XMOV A,#'.'MOV B,LCD_XLCALL LCDP2MOV A,70H ;加载小数点位INC LCD_X ;设置显示位置LCALL SHOW_DIG2 ;显示数据RET;*************************** 第二行显示数字子程序*************************SHOW_DIG2:ADD A,#30HMOV B,LCD_XLCALL LCDP2RET;*************************** 第二行显示数字子程序*************************LCDP2: PUSH ACCMOV A,B ;设置显示地址ADD A,#0C0H ;设置LCD的第二行地址LCALL WCOM ;写入命令POP ACC ;由堆栈取出ALCALL WDATA ;写入数据RET;*************************** 对LCD 做初始化设置及测试*************************SET_LCD: CLR LCD_ENLCALL INIT_LCD ;初始化 LCDLCALL STORE_DATA ;将自定义字符存入LCD的CGRAM RET;****************************** LCD初始化***********************************INIT_LCD: MOV A,#38H ;2行显示,字形5*7点阵LCALL WCOMLCALL DELAY1MOV A,#38HLCALL WCOMLCALL DELAY1MOV A,#38HLCALL WCOMLCALL DELAY1MOV A,#0CH ;开显示,显示光标,光标不闪烁 LCALL WCOMLCALL DELAY1MOV A,#01H ;清除 LCD 显示屏LCALL WCOMLCALL DELAY1RET;***************************** 清除LCD的第一行字符**************************CLR_LINE1:MOV A,#80H ;设置 LCD 的第一行地址LCALL WCOMMOV R0,#24 ;设置计数值C1: MOV A,#' ' ;载入空格符至LCDLCALL WDATA ;输出字符至LCDDJNZ R0,C1 ;计数结束RET;************************* LCD的第一行或第二行显示字符**********************LCD_PRINT:CJNE A,#1,LINE2 ;判断是否为第一行LINE1: MOV A,#80H ;设置 LCD 的第一行地址LCALL WCOM ;写入命令LCALL CLR_LINE ;清除该行字符数据MOV A,#80H ;设置 LCD 的第一行地址LCALL WCOM ;写入命令JMP FILLLINE2: MOV A,#0C0H ;设置 LCD 的第二行地址LCALL WCOM ;写入命令LCALL CLR_LINE ;清除该行字符数据MOV A,#0C0H ;设置 LCD 的第二行地址LCALL WCOMFILL: CLR A ;填入字符MOVC A,@A+DPTR ;由消息区取出字符CJNE A,#0,LC1 ;判断是否为结束码RETLC1: LCALL WDATA ;写入数据INC DPTR ;指针加1JMP FILL ;继续填入字符RET;*************************** 清除1行LCD 的字符****************************CLR_LINE: MOV R0,#24CL1: MOV A,#' 'LCALL WDATADJNZ R0,CL1RETDE: MOV R7,#250DJNZ R7,$RET;**************************** LCD 间接控制方式命令写入*************************WCOM: MOV P0,A ;写入命令CLR LCD_RS ;RS=L,RW=L,D0-D7=指令码,E=高脉冲 CLR LCD_RWSETB LCD_ENLCALL DELAY1CLR LCD_ENRET;**************************** LCD 间接控制方式数据写入*************************WDATA: MOV P0,A ;写入数据SETB LCD_RSCLR LCD_RWSETB LCD_ENLCALL DELCALL DERET;************************** 在LCD的第一行显示字符**************************LCDP1: PUSH ACCMOV A,B ;设置显示地址ADD A,#80H ;设置LCD的第一行地址LCALL WCOM ;写入命令POP ACC ;由堆栈取出ALCALL WDATA ;写入数据RET;****************************** 声光报警子程序*******************************BEEP_BL: MOV R6,#100BL2: LCALL DEX1CPL BEEPCPL RELAYDJNZ R6,BL2MOV R5,#10RETDEX1: MOV R7,#180DE2: NOPDJNZ R7,DE2RET;****************************** 延时子程序*******************************DELAY: MOV R6,#50DL1: MOV R7,#100DJNZ R7,$DJNZ R6,DL1DJNZ R5,DELAYRETDELAY1: MOV R6,#25 ;延时5毫秒DL2: MOV R7,#100DJNZ R7,$DJNZ R6,DL2RETEND。
单片机原理与应用实验报告——温度测量显示及设定实验目的:掌握单片机温度测量的原理和方法,了解温度传感器的工作原理,学会通过单片机控制显示屏显示温度,并可以通过按键设定温度。
实验器材:1.单片机(如STC89C52)2.温度传感器(如DS18B20)3.电阻、电容等基本元件4.1602液晶显示屏5.按键开关6.杜邦线、面包板等实验原理:1.单片机温度测量原理:单片机温度测量原理主要是通过温度传感器将温度转化为电压信号,然后单片机通过模拟口接收信号并进行数字转换得到温度数值。
2.温度传感器工作原理:温度传感器内部有一个温度敏感元件,它能根据温度的变化产生相应的电压信号,然后通过数字转换将电压信号转化为数值。
3.单片机与1602显示屏的连接:将1602显示屏的数据线接到单片机的IO口,通过控制IO口输出不同的信号来控制1602的显示。
实验步骤:1.连接电路:将单片机、温度传感器、1602显示屏等元件连接在一起,确保电路正确连接。
2.编写程序:编写单片机程序,根据单片机型号和编程软件的不同,具体编写方式可能会有所不同,但主要目的是通过单片机读取温度传感器的值,并将其转化为温度,最后通过1602显示屏显示温度。
3.调试程序:4.实验数据:在实验过程中需要记录下实验数据,包括温度传感器的电压值、转化的温度值等。
5.结果分析:根据实验数据和实验结果进行分析,对实验结果进行分析和总结。
实验总结:通过本次实验,我掌握了单片机温度测量的原理和方法,了解了温度传感器的工作原理,并成功通过单片机控制1602显示屏显示温度。
通过实验,我体会到了实验设计和实验过程中的困难和挑战,但我也学到了很多知识和技能,提高了实验能力和动手能力。
在今后的学习和工作中,我会继续努力,不断学习和探索,提高自己的实验能力和创新能力。
DS18B20获取温度程序流程图DS18B20的读字节,写字节,获取温度的程序流程图如图所示。
DS18B20初始化程序流程图DS18B20读字节程序流程图DS18B20写字节程序流程图DS18B20获取温度程序流程图图3-4 DS18B20程序流程图显示程序设计显示电路是由四位一体的数码管来实现的。
由于单片机的I/O 口有限,所以数码管采用动态扫描的方式来进行显示。
程序流程图如图所示。
图显示程序流程图按键程序设计按键是用来设定上下限报警温度的。
具体的程序流程图如图所示。
N图按键程序流程图附1 源程序代码/********************************************************************* 程序名; 基于DS18B20的测温系统* 功能:实时测量温度,超过上下限报警,报警温度可手动调整。
K1是用来* 进入上下限调节模式的,当按一下K1进入上限调节模式,再按一下进入下限* 调节模式。
在正常模式下,按一下K2进入查看上限温度模式,显示1s左右自动* 退出;按一下K3进入查看下限温度模式,显示1s左右自动退出;按一下K4消除* 按键音,再按一下启动按键音。
在调节上下限温度模式下,K2是实现加1功能,* K1是实现减1功能,K3是用来设定上下限温度正负的。
* 编程者:ZPZ* 编程时间:2009/10/2*********************************************************************/#include<AT89X52.h> //将AT89X52.h头文件包含到主程序#include<intrins.h> //将intrins.h头文件包含到主程序(调用其中的_nop_()空操作函数延时)#define uint unsigned int //变量类型宏定义,用uint表示无符号整形(16位)#define uchar unsigned char //变量类型宏定义,用uchar表示无符号字符型(8位)uchar max=0x00,min=0x00; //max是上限报警温度,min是下限报警温度bit s=0; //s是调整上下限温度时温度闪烁的标志位,s=0不显示200ms,s=1显示1s左右bit s1=0; //s1标志位用于上下限查看时的显示void display1(uint z); //声明display1()函数#include"ds18b20.h" //将ds18b20.h头文件包含到主程序#include"keyscan.h" //将keyscan.h头文件包含到主程序#include"display.h" //将display.h头文件包含到主程序/***********************主函数************************/void main(){beer=1; //关闭蜂鸣器led=1; //关闭LED灯timer1_init(0); //初始化定时器1(未启动定时器1)get_temperature(1); //首次启动DS18B20获取温度(DS18B20上点后自动将EEPROM中的上下限温度复制到TH和TL寄存器)while(1) //主循环{keyscan(); //按键扫描函数get_temperature(0); //获取温度函数keyscan(); //按键扫描函数display(temp,temp_d*0.625);//显示函数alarm(); //报警函数keyscan(); //按键扫描函数}}/********************************************************************* 程序名; __ds18b20_h__* 功能:DS18B20的c51编程头文件* 编程者:ZPZ* 编程时间:2009/10/2* 说明:用到的全局变量是:无符号字符型变量temp(测得的温度整数部分),temp_d* (测得的温度小数部分),标志位f(测量温度的标志位‘0’表示“正温度”‘1’表* 示“负温度”),标志位f_max(上限温度的标志位‘0’表示“正温度”、‘1’表* 示“负温度”),标志位f_min(下限温度的标志位‘0’表示“正温度”、‘1’表* 示“负温度”),标志位w(报警标志位‘1’启动报警‘0’关闭报警)。
基于51单片机数字温度计的设计与实现数字温度计是一种能够测量环境温度并显示数值的设备。
基于51单片机的数字温度计设计与实现是指利用51单片机作为核心,结合温度传感器和其他辅助电路,实现一个能够测量温度并通过数码管显示温度数值的系统。
本文将从硬件设计和软件实现两个方面介绍基于51单片机数字温度计的具体设计与实现过程。
一、硬件设计1. 温度传感器选取在设计数字温度计时,首先需要选取合适的温度传感器。
市面上常用的温度传感器有热敏电阻、功率型温度传感器(如PT100)、数字温度传感器(如DS18B20)等。
根据设计需求和成本考虑,我们选择使用DS18B20数字温度传感器。
2. 电路设计基于51单片机的数字温度计的电路设计主要包括单片机与温度传感器的连接、数码管显示电路和电源电路。
(1)单片机与温度传感器的连接在电路中将51单片机与DS18B20数字温度传感器相连接,可采用一线总线的方式。
通过引脚的连接,实现单片机对温度传感器的读取控制。
(2)数码管显示电路为了能够显示温度数值,我们需要设计一个数码管显示电路。
根据温度传感器测得的温度值,通过数字转换和数码管驱动,将温度数值显示在数码管上。
(3)电源电路电源电路采用稳压电源设计,保证整个系统的稳定供电。
根据实际需求选择合适的电源电压,并添加滤波电容和稳压芯片,以稳定电源输出。
3. PCB设计根据电路设计的原理图,进行PCB设计。
根据电路元件的布局和连线的走向,绘制PCB板的线路、元件和连接之间。
二、软件实现1. 单片机的编程语言选择对于基于51单片机的数字温度计的软件实现,我们可以选择汇编语言或者C语言进行编程。
汇编语言的效率高,但编写难度大;C语言的可读性好,开发效率高。
根据实际情况,我们选择使用C语言进行编程。
2. 温度传感器数据获取利用单片机的IO口与温度传感器相连,通过一线总线协议进行数据的读取。
根据温度传感器的通信规则,编写相应的代码实现数据的读取。
数字温度汇编程序数字温度汇编程序是一种用于将温度数据转换为数字形式的计算机程序。
它可以将从传感器或其他温度测量设备获取的模拟信号转换为数字信号,以便计算机可以对其进行处理和分析。
本文将详细介绍数字温度汇编程序的原理、功能和实现方法。
一、原理数字温度汇编程序的核心原理是将模拟温度信号转换为数字形式。
这个过程通常涉及到模数转换(ADC)技术。
传感器测量到的温度信号是模拟信号,需要经过ADC转换为数字信号,才能被计算机处理。
ADC将连续的模拟信号转换为离散的数字信号,通过对模拟信号进行采样和量化来实现。
二、功能1. 温度测量:数字温度汇编程序可以准确测量温度,并将其转换为数字形式。
通过传感器获取温度信号,程序可以将其转换为计算机可以理解和处理的数字信号。
2. 数据处理:数字温度汇编程序可以对测量到的温度数据进行处理和分析。
它可以实现温度数据的存储、计算、统计和显示等功能。
通过对温度数据的处理,可以得出温度的变化趋势、平均值、最大值、最小值等信息。
3. 报警功能:数字温度汇编程序可以设置温度报警功能。
当温度超过或低于设定的阈值时,程序可以触发报警,通知用户或其他系统进行相应的处理。
4. 数据通信:数字温度汇编程序可以通过串口、网络或其他通信方式将温度数据传输给其他设备或系统。
这样,其他设备或系统可以实时监测和接收温度数据,进行进一步的处理和分析。
三、实现方法1. 硬件准备:实现数字温度汇编程序需要一些基本的硬件设备,包括温度传感器、模数转换器、微控制器或单片机等。
温度传感器用于测量温度,模数转换器用于将模拟信号转换为数字信号,微控制器或单片机用于控制和处理温度数据。
2. 程序编写:使用汇编语言编写数字温度汇编程序。
程序需要包括温度测量、数据处理、报警和数据通信等功能的实现。
编写程序时需要考虑温度传感器的特性和模数转换器的工作原理,以确保数据的准确性和稳定性。
3. 硬件连接:将温度传感器和模数转换器连接到微控制器或单片机上。
用单片机显示温度的汇编程序
汇编语言是一种底层的机器语言,可以直接对硬件进行控制。
使
用汇编语言编写单片机程序可以实现更加高效的代码和更低的资源消耗。
下面将介绍一种使用汇编语言编写单片机显示温度的程序。
首先需要明确使用的单片机型号和温度传感器类型。
在这里我们
假设使用的单片机型号为STC89C52和模拟温度传感器LM35。
接下来我们将列出主要的程序框架,然后逐步进行详细的解释。
1.引入头文件:包含必要的寄存器定义和宏定义。
2.定义端口:为了简化程序,我们可以定义将数码管连接的端口
为P0口。
3.定义变量:我们需要定义一些变量,包括温度变量和显示变量,用于存储和操作温度值和显示数据。
4.初始化:在程序开始时,需要对单片机进行一些初始化操作,
包括设置端口引脚方向和清空显示变量等。
5.读取温度:通过与温度传感器的通信读取当前的温度值,并将
其保存到温度变量中。
6.温度转换:由于LM35输出的是模拟电压值,我们需要将其转换
为摄氏温度值。
具体的转换公式可根据LM35的数据手册获取。
7.显示温度:将温度值转换为数码管可以显示的格式,并输出到
P0口。
8.延时:为了使温度值在数码管上显示一段时间,需要添加适当
的延时函数。
9.重复以上步骤:使用循环语句,不断地读取温度、转换和显示,以实现持续的显示温度值。
以上是一个基本的单片机显示温度的汇编程序框架。
具体的实现
可能与单片机型号和温度传感器有关,可以根据具体的硬件和需求进
行相应的修改。
编写汇编程序需要熟悉硬件和寄存器的操作,对汇编
语言有一定的了解。
在编写程序时,需要注意保持代码的清晰和规范,使用注释进行必要的解释,提高程序的可读性和可维护性。
单片机温度显示的汇编程序属于物联网和嵌入式系统的应用,常见于各种温度检测和控制的场景。
除了显示温度,该程序还可以进行一些其他的操作,例如报警,记录历史温度等。
通过学习和理解这个简单的例子,可以进一步了解汇编语言的应用和单片机的编程原理,为进一步深入学习嵌入式系统打下坚实的基础。