基于51单片机简易温度显示器汇编程序·
基于51单片机的1602液晶显示温度和时间的C程序
//液晶显示温度#include "AT89X52.H"#define Ddata P0sbit RS=P2^7; //命令数据控制端sbit RW=P2^6; //读写选择端sbit LCDE=P2^5; //液晶使能端sbit DQ=P2^0; //ds18b20与单片机连接口#define uchar unsigned char#define uint unsigned intunsigned char hour=0,min=0,sec=0; //定义初值unsigned int count=0;unsigned char line1[16]={" temp: "}; //16个字符unsigned char line2[16]={" time: 00:00:00"}; //16个字符unsigned char tab[]={'0','1','2','3','4','5','6','7','8','9'}; //数组uchar data disdata[5];uint tvalue; //温度值uchar tflag; //温度正负标志void time();/*************************lcd1602程序**************************/ void delay1ms(unsigned int ms)//延时1毫秒(不够精确的){unsigned int i,j;for(i=0;i<ms;i++)for(j=0;j<110;j++);}void delay5ms()//延时5毫秒(不够精确的){unsigned int i;for (i=0;i<1000;i++);}void delay50us(){register int i;for (i=0;i<20;i++);}void delay(){unsigned char m,n;for(m=255;m>0;m--)for(n=255;n>0;n--);}void wr_com(unsigned char comm) //********写控制字符程序E=1 RS=0RW=0 **********//{LCDE=0; //使能端RS=0; //********RS寄存器选择输入端,当RS=0;当进行写模块操作,指向指令寄存器。
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;}液晶显示温度计程序。
基于51单片机――Ds18B20温度采集,LCD显示汇编程序(附带proteus仿真图)
TEMP_ZH EQU 24H ;实测温度值存放单元TEMPL EQU 25H TEMPH EQU 26HTEMP_TH EQU 27H ;高温报警值存放单元TEMP_TL EQU28H ;TEMPHC EQU 29H ;TEMPLC EQU 2AHTEMPFC EQU 2BHK1 EQU P1.4K2 EQU P1.5 ;K3 EQU P1.6 ;K4 EQU P1.7 ;BEEP EQU P3.7 ;RELAY EQU P1.3 ;LCD_X EQU 2FH ;LCDLCD_RS EQU P2.0 ;LCDLCD_RW EQU P2.1 ;LCDLCD_EN EQU P2.2 ;LCDFLAG1 EQU 20H.0 ;DS18B20 KEY_UD EQU 20H.1 ;DQEQU P3.3低温报警值存放单元正、负温度值标记查询按键设置/调整键调整键确定键蜂鸣器指示灯字符显示位置寄存器选择信号读写信号允许信号是否存在标志设定按键的增、减标志数据信号;;DS18B20ORG 00HLJMP MAINORG 0030H MAIN:MOV SP,#60H MOV A,#00HMOV R0,#20H MOV R1,#10H CLEAR:MOV @R0,A INC R0DJNZ R1,CLEAR LCALL SET_LCD LCALL RE_18B20 START:LCALL RST JNB FLAG1,START1 LCALL MENU_OK信息子程序MOV TEMP_TH,#055H MOV TEMP_TL,#019H LCALL RE_18B20ALCALL WRITE_E2 ;LCALL TEMP_BJ ;JMP START2;将20H~2FH单元清零;调用18B20复位子程序;DS1820不存在;DS1820存在,调用显示正确设置TH初值85度设置TL初值25度调用暂存器操作子程序写入DS18B20显示温度标记;;;START1: LCALL MENU_ERROR;调用显示出错信息子程序LCALL TEMP_BJ ;显示温度标记SJMP $START2: LCALL RST;调用DS18B20复位子程序JNBFLAG1,START1;DS18B20不存在MOV A,#0CCHLCALL WRITEMOV A,#44HLCALL WRITELCALL RSTMOV A,#0CCHLCALL WRITEMOV A,#0BEHLCALL WRITELCALL READ子程序LCALL CONVTEMP程序LCALL DISPBCDLCALL CONVLCALL TEMP_COMP值比较子程序;跳过ROM匹配命令;温度转换命令;跳过ROM匹配;读温度命令;调用DS18B20数据读取操作;调用温度数据BCD码处理子;调用温度数据显示子程序;调用LCD显示处理子程序;调用实测温度值与设定温度LCALLPROC_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值写入DS18B20 LCALL WRITE_E2PROC_K2: LCALL MENU_OKLCALL TEMP_BJPROC_END:RET;******************************************************SET_ALARM:LCALL LOOK_ALARMAS0: JB K1,AS00LCALL BEEP_BLJNB K1,$CPL 20H.1 ;UP/DOWNAS00: JB 20H.1,ASZ01 ;20H.1=1 JMP ASJ01 ;20H.1=0ASZ01: JB K2,ASZ02 ;THLCALL BEEP_BLINC TEMP_THMOV A,TEMP_THCJNE A,#120,ASZ011MOV TEMP_TH,#0ASZ011: LCALL LOOK_ALARM设定温度报警值标记,增加,减小值调整(增加)TH、TLMOV R5,#10LCALL DELAYJMP ASZ01ASZ02: JB K3,ASZ03;TL值调整(增加)LCALL BEEP_BLINC TEMP_TLMOV A,TEMP_TLCJNE A,#99,ASZ021MOV TEMP_TL,#00HASZ021: LCALL LOOK_ALARM MOV R5,#10LCALL DELAYJMP ASZ02ASZ03: JB K4,AS0LCALL BEEP_BLJNB K4,$RETASJ01: JB K2,ASJ02LCALL BEEP_BLDEC TEMP_THMOV A,TEMP_THCJNE A,#0FFH,ASJ011;确定调整;TH值调整(减少)JMP ASJ022ASJ011: 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:MOVA,TEMP_THSUBBA,TEMP_ZH;减数>被减数,则JC CHULI1;借位标志位C=1,转MOV A,TEMPFCCJNEA,#0BH,COMPSJMPCHULI2COMP:MOV A,TEMP_ZHSUBB A,TEMP_TL ;JC CHULI2 ;MOV DPTR,#BJ5LCALL TEMP_BJ3CLR RELAYRETCHULI1: MOV DPTR,#BJ3LCALL TEMP_BJ3SETB RELAY ;LCALL BEEP_BLRETCHULI2: MOV DPTR,#BJ4LCALL TEMP_BJ3SETB RELAY ;减数>被减数,则借位标志位C=1,转;点亮指示灯熄灭指示灯蜂鸣器响熄灭指示灯;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,#0 MOV 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,TSR1程序SETB DQ;拉高数据线NOPNOPNOPMOV R0,#32HTSR2: JNB DQ,TSR3;等待DS18B20回应DJNZ R0,TSR2JMP TSR4 ;延时TSR3: SETB FLAG1 ;置1标志位,表示DS1820存在JMP TSR5 TSR4: CLR FLAG1 ;清0标志位,表示DS1820不存在JMP TSR7 TSR5: 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;把暂存器里的温度报警值拷贝到EEROM LCALL 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_DATAD_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微妙以上RRCA ;把一个字节DATA分成8个BIT环移给CMOV DQ,C;写入一位MOV R3,#3CHDJNZ R3,$ ;等待100微妙SETB DQ;重新释放总线NOPDJNZ R2,WR1 ;写入下一位SETB DQRET;**********************DS18B20数据读取操作子程序**************************MOV R4,#4;将温度低位、高位、TH、TL从DS18B20中读出MOV R1,#TEMPL元RE00: MOV R2,#8RE01: CLR CYSETB DQNOPNOPCLR DQNOPNOPNOPSETB DQMOV R3,#09DJNZ R3,$MOV C,DQMOV R3,#3CH;存入25H、26H、27H、28H单;读前总线保持为低;开始读总线释放;延时18微妙;从DS18B20总线读得一位DJNZ R3,$;等待100微妙RRC A;把读得的位值环移给ADJNZ R2,RE01;读下一位MOV @R1,ADJNZ 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 ;MOV DPTR,#TEMPDOTTABMOVC A,@A+DPTRMOV TEMPLC,A ;TEMPLC LOW=分BCD MOV A,TEMPL ;ANL A,#0F0H ;SWAP AMOV TEMPL,AMOV A,TEMPH ;ANL A,#0FHSWAP AORL A,TEMPL ;乘0.0625小数部整数部分取出高四位取出低四位重新组合MOV TEMP_ZH,ALCALL HEX2BCD1MOV TEMPL,AANL A,#0F0HSWAP AORL A,TEMPHC ;TEMPHCBCDMOV TEMPHC,AMOV A,TEMPLANL A,#0FHSWAP A ;TEMPLC HI =BCD ORL A,TEMPLCMOV TEMPLC,AMOV A,R4JZ TEMPC12ANL A,#0FHSWAP AMOV R4,AMOV A,TEMPHC ;TEMPHC HI =BCD ANL A,#0FHLOW=十位数个位数百位数ORL A,R4TEMPC12: 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_PRINTLCALL TEMP_BJ1MOV A,TEMP_TH;加载TH数据MOV LCD_X,#3LCALL SHOW_DIG2H ;MOV A,#0CEHLCALL TEMP_BJ1MOV A,TEMP_TLMOV LCD_X,#12LCALL SHOW_DIG2L ;RETM_ALAX1: DB " LOOK ALERT CODE",0 M_ALAX2: DB "TH:TL:",0TEMP_BJ1: LCALL WCOMMOV DPTR,#BJ2MOV R1,#0MOV R0,#2BBJJ2: MOV A,R1MOVC A,@A+DPTRLCALL WDATA;设置显示位置显示数据;加载TL数据;设置显示位置显示数据;指针指到显示信息区INC R1DJNZ 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 LCDP2显示子程序POP B INC 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,73HMOV LCD_X,#6CJNE A,#1,CONV1JMP CONV2CONV1: CJNE A,#0BH,CONV11MOV A,#"-"JMP CONV111CONV11: MOV A,#" "CONV111: MOV B,LCD_XLCALL LCDP2JMP CONV3CONV2: LCALL SHOW_DIG2CONV3: INC LCD_X MOV A,72HLCALL SHOW_DIG2INC LCD_XMOV A,71HLCALL 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的CGRAMRET;*****************************************************************INIT_LCD:MOV A,#38H ;2行显示,字形5*7点阵LCALL WCOMLCALL DELAY1MOV A,#38HLCALL WCOMLCALL DELAY1MOV A,#38HLCALL WCOMLCALL DELAY1MOV A,#0CH ;开显示,显示光标,光标不闪烁LCALL WCOMLCD 初始化LCALL 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;***************************清除****************************CLR_LINE:MOV R0,#24CL1: MOV A,#' 'LCALL WDATADJNZ R0,CL11行LCD的字符RETDE:MOV R7,#250DJNZ R7,$RET;****************************LCD间接控制方式命令写入*************************WCOM:MOV P0,A ;写入命令CLR LCD_RS ;RS=L,RW=L,D0-D7=指令码,E=高脉冲CLR LCD_RW SETB LCD_ENLCALL DELAY1CLR LCD_ENRET;****************************LCD间接控制方式数据写入*************************WDATA:MOV P0,A ;写入数据SETB LCD_RSCLR LCD_RWSETB LCD_ENLCALL DECLR LCD_ENLCALL 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,#10LCALL DELAYRETDEX1: 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子程序时。
C51单片机数字温度计汇编程序及说明书
1绪论1.1选题背景随着人们生活水平的不断提高,单片机控制无疑是人们追求的目标之一,它所给人带来的方便也是不可否定的,其中数字温度计就是一个典型的例子,但人们对它的要求越来越高,要为现代人工作、科研、生活提供更好的更方便的设施就需要从单片机技术入手,一切向着数字化控制,智能化控制方向发展。
温度测量在物理实验、医疗卫生、食品生产等领域,尤其在热学试验(如:物体的比热容、汽化热、热功当量、压强温度系数等教学实验)中,有特别重要的意义。
现在所使用的温度计通常都是精度为1℃和0.1℃的水银、煤油或酒精温度计。
这些温度计的刻度间隔通常都很密,不容易准确分辨,读数困难,而且他们的热容量还比较大,达到热平衡所需的时间较长,因此很难读准,并且使用非常不方便。
本设计所介绍的数字温度计与传统的温度计相比,具有读数方便,测温范围广,测温准确等优点,其输出温度采用数字显示,主要用于对测温比较准确的场所,或科研实验室使用。
因此本课题就尝试通过编程与芯片的结合来解决传统数字温度计的弊端,设计出新型数字温度计。
1.2课题现状分析及研究意义温度传感器的发展现状:温度传感器使用范围广,数量多,居各种传感器之首,其发展大致经历了以下3个阶段:①传统的分立式温度传感器(含敏感元件)——热电偶传感器,主要是能够进行非电量和电量之间转换。
②模拟集成温度传感器/控制器。
集成传感器是采用硅半导体集成工艺制成的,因此亦称硅传感器或单片集成温度传感器。
③智能温度传感器。
它是微电子技术、计算机技术和自动测试技术(ATE_)的结晶。
智能温度传感器内部包含温度传感器、A/D传感器、信号处理器、存储器(或寄存器)和接口电路。
本课题的研究可以应用领域生产、生活等很多领域。
对于家用电器从洗衣机、微波炉到音响等等到处都可以用到温度控制器来方便大家的日常生活。
开发此产品后也可方便应用安装在小至家庭大到工厂车间,小至一个芯片大到一个机械设备。
例如在家庭客厅卧室等必要地方显示室温,可防止家里食物是否变质及早采取措施。
基于51单片机——Ds18B20温度采集,LCD显示汇编程序(附带proteus仿真图).docx
TEMP_ZH EQU 24H ; 实测温度值存放单元TEMPL EQU 25HTEMPH EQU 26H高温报警值存放单元TEMP_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 FH ;LCD 字符显示位置寄存器选择信号LCD_RS EQU P2.0 ;LCD读写信号LCD_RW EQU P2.1 ;LCD允许信号LCD_EN EQU P2.2 ;LCD是否存在标志FLAG1 EQU 20H.0 ;DS18B20KEY_UD EQU 20H.1 5 设定按键的增、减标志DQ EQU P3.3 ;DS18B20 数据信号ORG 0000HLJMP MAINORG 0030H MAIN: MOV SP,#60HMOV A,#00HMOV R0,#20HMOV R1,#10HCLEAR: MOV @R0,AINC R0DJNZ R1,CLEARLCALL SET_LCDLCALL RE_18B20 START: LCALL RSTJNB FLAG1,START1LCALL MENU_OK 信息子程序MOV TEMP_TH,#055HMOV TEMP_TL,#019HLCALL RE_18B20ALCALL WRITE_E2 ;LCALL TEMP_BJ ;JMP START2;将20H~2FH单元清零;调用18B20复位子程序;DS 1 820不存在;DS1820 存在,调用显示正确;设置TH初值85度;设置TL初值25度; 调用暂存器操作子程序写入DS18B20显示温度标记LCALL TEMP_BJSJMP $START2: LCALL RSTJNB FLAG1,START1 MOV A,#0CCH LCALL WRITE MOV A,#44H LCALL WRITE LCALL RST MOV A,#0CCH LCALL WRITE MOV A,#0BEH LCALL WRITE LCALL READ 子程序LCALL CONVTEMP 程序LCALL DISPBCD LCALL CONV LCALLTEMP_COMP 值比较子程序显示温度标记;调用DS18B2(复位子程序QS18B20不存在;跳过RoM E配命令; 温度转换命令START1: LCALL MENU_ERROR ; 调用显示出错信息子程序;跳过ROM E配; 读温度命令;调用DS18B20数据读取操作;调用温度数据BCD码处理子; 调用温度数据显示子程序;调用LCD显示处理子程序; 调用实测温度值与设定温度调用键扫描子程序 ;循环 键扫描子PROC_KEY:JB K1,PROC_K1LCALL BEEP_BL JNB K1,$MOV DPTR,#M_ALAX1 MOV A,#1LCALL LCD_PRINT LCALL LOOK_ALARM JB K3,$LCALL BEEP_BL JMP PROC_K2PROC_K1: JB K2,PROC_ENDLCALL BEEP_BL JNB K2,$MOV DPTR,#RST_A1 MOV A,#1LCALL LCD_PRINT LCALL SET_ALARMLCALL RE_18B20 将设定的 TH,TL 值写入LCALL PROC_KEYSJMP START2・ ***************************5*****************************程序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_ALARMMOV R5,#10 LCALL DELAY JMP ASZ01ASZ02: JB K3,ASZ03LCALL BEEP_BLINC TEMP_TLMOV A,TEMP_TLCJNE A,#99,ASZ021MOV TEMP_TL,#00H ASZ021: LCALL LOOK_ALARM MOV R5,#10LCALL DELAYJMP ASZ02ASZ03: JB K4,AS0LCALL BEEP_BLJNB K4,$RETASJ01: JB K2,ASJ02LCALL BEEP_BLDEC TEMP_THMOV A,TEMP_THCJNE A,#0FFH,ASJ011 ;TL 值调整(增加); 确定调整;TH 值调整(减少)JMP ASJ022ASJ011: 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_TH SUBB A,TEMP_ZH JCCHULI1MOV A,TEMPFCCJNE A,#0BH,COMP SJMPCHULI2COMP: MOV A,TEMP_ZHSUBB A,TEMP_TL ; JCCHULI2 ;MOV DPTR,#BJ5 LCALLTEMP_BJ3 CLR RELAYRETCHULI1: MOV DPTR,#BJ3 LCALL TEMP_BJ3 SETB RELAY ;LCALL BEEP_BL RET CHULI2: MOV DPTR,#BJ4 LCALL TEMP_BJ3SETB RELAY; 减数>被减数,则;借位标志位C=I,转减数>被减数,则借位标志位C=I ,转; 点亮指示灯熄灭指示灯; 蜂鸣器响熄灭指示灯LCALL BEEP_BL ; 蜂鸣器响RETTEMP_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"・ ********************************5***************************MENU_OK: MOV DPTR,#M_O MOV A,#1 ;LCALL LCD_PRINT MOVDPTR,#M_OK2 MOVA,#2 ;LCALL LCD_PRINTRETM_OK1: DB " DS18B20 OK显示正确信息子程序; 指针指到显示消息显示在第一行; 指针指到显示消息显示在第一行",0M_OK2: DB " TEMP: ",0・ ******************************** 显示出错信息子程序***************************MENU_ERROR:MoV DPTR,#M_ERROR针指到显示消息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,TSR3DJNZ R0,TSR2JMP TSR4 ;TSR3: SETB FLAG1JMP TSR5TSR4: CLR FLAG1JMP TSR7TSR5: MOV R0,#06BH TSR6: DJNZ R0,$ TSR7: SETB DQRET・ ************************ 5***************************RE_18B20:JB FLAG1,RE_18B20A RET延时置1标志位,表示DS1820存在清0标志位,表示DS1820不存在时序要求延时一段时间RE_18B20A:;等待DS18B20回应DS18B20 暂存器操作子程序LCALL RSTMOV A,#0CCH LCALL WRITE WR_SCRAPD:MOV A,#4EH LCALL WRITE MOV A,TEMP_TH LCALL WRITE MOV A,TEMP_TL LCALL WRITE MOV A,#7FH LCALL WRITERET;跳过RoME 配; 写暂器;TH ( 报警上限);TL ( 报警下限);12 位精度复制暂存器子程序;跳过ROM E 配; 把暂存器里的温度报警值拷贝到 LCALL WRITE・ ************************5*******************************WRITE_E2:LCALL RSTMoV A,#0CCH LCALL WRITE MoV A,#48H EERoM********************************READ_E2:LCALL RSTMOV A,#0CCH LCALL WRITE MOV A,#0B8H暂存器LCALL WRITE RET ;跳过RoM E 配;把EEROMl 的温度报警值拷贝回*********************STORE_DATA:MOV A,#40H LCALL WCOM MOV R2,#08H MOV DPTR,#D_DATA MOV R3,#00H S_DATA: MOV A,R3MOVC A,@A+DPTRRET・ ***********************重 读 EEROM 子 程 序・ ************************将自定义字符写入 LCD 的CGRAM 中INC R3DJNZ R2,S_DATA RETD_DATA: DB 0CH,12H,12H,0CH,00H,00H,00H,00HDS18B20 数 据 写 入 操 作 子 程 序************************CLR CWR1: CLR DQ;开始写入DS18B20总线要处于复位(低)状态MOV R3,#07DJNZ R3,$ 总线复位保持 1 6微妙以上 RRC A把一个字节DATA 分成8个BlT环移给 CMOV DQ,C ; 写入一位MOV R3,#3CH DJNZ R3,$ 等待 100 微妙SETB DQ ; 重新释放总线NOPDJNZ R2,WR1 写入下一位SETB DQLCALL WDATA; 写入数据・ ***********************WRITE: MOV R2,#8一共 8 位数据RET・ ********************** DS18B20 数据读取操作子程序**************************READ: MOV R4,#4DS18B2冲读出MOV R1,#TEMPL 元RE00: MOV R2,#8RE01: CLR CYSETB DQNOPNOPCLR DQNOPNOPNOPSETB DQMOV R3,#09DJNZ R3,$MOV C,DQ; 将温度低位、高位、TH、TL 从; 存入25H、26H、27H、28H 单; 读前总线保持为低; 开始读总线释放; 延时18 微妙;从DS18B2(总线读得一位DJNZ R3,$ ; 等待 100 微妙RRC A ; 把读得的位值环移给 A DJNZ R2,RE01; 读下一位MOV @R1,AINC R1DJNZ R4,RE00RET*************************CONVTEMP: MOV A,TEMPHANL A,#08H JZ TEMPC1 ; CLR CMOV A,TEMPL ; CPL A ; ADD A,#01H MOV TEMPL,A MOV A,TEMPH CPL A ADDC A,#00H MOV TEMPH,A・ ************************温 度 值 BCD 码 处 理 子 程 序判温度是否零下温度零上转二进制数求补(双字节) 取反加 1MOV 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=小数部分BCD整数部分MOV A,TEMPL ;取出高四位ANL A,#0F0H ;SWAP AMOV TEMPL,A取出低四位MOV A,TEMPH ;ANL A,#0FHSWAP AORL A,TEMPL ; 重新组合ORL A,TEMPLC MOV TEMPLC,A MOV A,R4 JZ TEMPC12 ANL A,#0FH SWAP A MOV R4,A MOV A,TEMPHC;TEMPHC HI = 百位数BCDANL A,#0FHBCDBCDMOV TEMP_ZH,A LCALL HEX2BCD1 MOV TEMPL,A ANL A,#0F0H SWAP AORL A,TEMPHC ;TEMPHCMOV TEMPHC,A MOV A,TEMPL ANL A,#0FH SWAP A;TEMPLC HI =LOW= 十位数个位数ORL 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 指; 针指到显示信息区M_ALAX1: DB " LOOK ALERT CODE",0 M_ALAX2: DB "TH: TL: ",0 TEMP_BJ1: LCALL WCOMMOV DPTR,#BJ2 ; 指针指到显示信息区MOV R1,#0 MOV R0,#2 BBJJ2: MOV A,R1MOVC A,@A+DPTR LCALL WDATALCALL 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 ;显示数据RETMOV A,#2; 显示在第二行INC R1DJNZ R0,BBJJ2RETBJ2: DB 00H,"C"POP B・ ************************** 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_X MOV A,BMOV B,LCD_XADD A,#30HLCALL LCDP2RETSHOW_DIG2L:MOV B,#100 DIV ABMOV A,#0AHXCH A,B DIV ABADD A,#30H PUSH BMOV B,LCD_XLCALL LCDP2 POP B INC 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,73HMOV LCD_X,#6CJNE A,#1,CONV1JMP CONV2CONV1: CJNE A,#0BH,CONV11MOV A,#"-"JMP CONV111 CONV11: MOV A,#" " CONV111: MOV B,LCD_X LCALL LCDP2JMP CONV3CONV2: LCALL SHOW_DIG2CONV3: INC LCD_XMOV A,72HLCALL SHOW_DIG2INC LCD_XMOV A,71H LCALLSHOW_DIG2INC LCD_XMOV A,#'.'; 加载百位数据; 设置位置;"-" 号显示;"+" 号不显示; 显示数据; 十位; 个位第二行显示数字子程序设置显示地址设置LCD 的第二行地址写入命令 由堆栈取出 A; 写入数据MOV B,LCD_X LCALL LCDP2 MOV A,70H INC LCD_XLCALL SHOW_DIG2 RET; 加载小数点位 ; 设置显示位置 ; 显示数据第二行显示数字子程序・ ***************************5*************************SHOW_DIG2:ADD A,#30HMOV B,LCD_XLCALL LCDP2RET・ ***************************5*************************LCDP2: PUSH ACC MOVA,B ; ADD A,#0C0H ; LCALL WCOM ; POP ACC ;LCALL WDATARETLCALL WCOM・ ***************************5*************************SET_LCD: CLR LCD_ENLCALL INIT_LCD ; LCALL STORE_DATA ; RET・ ******************************5***********************************INIT_LCD: MOV A,#38H ;2LCALL WCOM LCALL DELAY1 MOV A,#38H LCALL WCOM LCALL DELAY1 MOV A,#38H LCALL WCOM LCALL DELAY1 MOV A,#0CH ;对 LCD 做 初 始 化 设 置 及 测 试初始化 LCD将自定义字符存入LCD 的CGRAMLCD 初 始 化开显示,显示光标,光标不闪烁LCALL DELAY1MOV A,#01H ; 清除 LCD 显示屏 LCALL WCOM LCALL DELAY1 RET清 除 LCD 的 第 一 行 字 符设置 LCD 的第一行地址 设置计数值载入空格符至 LCD 输出字符至 LCD 计数结束LCD 的 第一 行或第二行 显 示字符LCD_PRINT:CJNE A,#1,LINE2 ; 判断是否为第一行LINE1: MOV A,#80H ; 设置 LCD 的第一行地址LCALL WCOM ; 写入命令LCALL CLR_LINE ; 清除该行字符数据・ *****************************5**************************CLR_LINE1:MOV A,#80HLCALL WCOM MOV R0,#24 ;C1: MOV A,#' ' ; LCALLWDATA DJNZ R0,C1 ; RET・ *************************5**********************MOV A,#80H 设置 LCD 的第一行地址LCALL WCOM ; JMP FILL LINE2: MOV A,#0C0H LCALLWCOM ; LCALL CLR_LINEMOV A,#0C0H ;LCALL WCOMFILL: CLR A ;MOVC A,@A+DPTR CJNEA,#0,LC1 ;RETLC1: LCALL WDATA INCDPTR ; JMP FILL ; RET・ ***************************5****************************CLR_LINE: MOV R0,#24 CL1: MOV A,#' 'LCALL WDATA DJNZR0,CL1写入命令设置LCD 的第二行地址写入命令清除该行字符数据设置LCD 的第二行地址填入字符由消息区取出字符判断是否为结束码写入数据指针加1继续填入字符清除1 行LCD 的字符RET DE: MOV R7,#250DJNZ R7,$ RET・ ****************************5*************************WCOM: MOV P0,ACLR LCD_RS ;RS=L,RW=L,D0-D7= 指令码,E= 高脉冲CLR LCD_RW SETB LCD_EN LCALL DELAY1 CLR LCD_EN RETLCALL DELCD 间接控制方式命令写入写入命令・ ****************************5*************************WDATA: MOV P0,ASETB LCD_RS CLR LCD_RW SETB LCD_ENLCD 间接控制方式数据写 入写入数据CLR LCD_EN LCALL DE RET・ **************************5在LCD 的第一行显示字符**************************LCDP1: PUSH ACCMOV A,B ;设置显示地址ADD A,#80H ;设置LCD的第一行地址LCALL WCOM ;写入命令POP ACC ; 由堆栈取出ALCALL WDATA ; 写入数据RET・ ******************************5声光报警子程序*******************************BEEP_BL: MOV R6,#100BL2: LCALL DEX1CPL BEEPCPL RELAYDJNZ R6,BL2MOV R5,#10LCALL DELAYRETDEX1: 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,DL2RETENDLCDlLMOT6LDS18B2Θ OK TEMP : 82.0O C8sS23Sδ≥CRYSLUIXTALIXTAL2RSTPQOfAa) P0.1∕AD1PO2∕AD2 P0.3∕ACGP0.4∕ACU PO5∕AD6P0 6∕ACePO7∕AD7 ,°u∙远2QX 'KliS BP1 5 PI 6 Pl 7 ΘO5Γ <TEXT>K3K2 PSENALE EAP1.0 PII P1 2P2ΓUAfl P2.1)W P22∕A10 P23∕A11 P24∕A12 P25∕A13 P26∕A14 P27∕A15 P3.Q∕RXD P3.1∕7XD P3.2∕iF∏D P3 3∕INT1P3 4/TD P3 5f∏ P3 6Λ⅛5 P3 7WI ■■39■ 屮 ■ g■ 卜■ ■σ∙ O■ ■ ■ J■ --■↑2・ ■ 383" ■ 374・5" ■356"7" ■338∙■ 22 ....................... ...............................9・■51•■ 22•■ 23221 ∆2i * ±2& ■2Z. ■28 ,Ir蚩工n s: ∙ inJTDS1ΘB2D <TEXT>, ∙GND ∙ ∙2・ U2。
51单片机设计数字温度计(流程图+源码+实物图片)
DS18B20获取温度程序流程图DS18B20的读字节,写字节,获取温度的程序流程图如图所示结束DS18B20初始化程序流程图写0x44启动DS18B20延时500 s_____ 、一DS18B20 初始化写0xcc跳过读RCMDS18B20获取温度程序流程图DS18B20读字节程序流程图图3-4 DS18B20程序流程图DS18B20写字节程序流程图显示程序设计显示电路是由四位一体的数码管来实现的。
由于单片机的I/O 口有限,所以数码管采用动态扫描的方式来进行显示。
程序流程图如图所示。
图显示程序流程图按键程序设计按键是用来设定上下限报警温度的。
具体的程序流程图如图所示N附 1 源程序代码******************************************************************* 程序名 ; 基于 DS18B20 的测温系统* 功 能: 实时测量温度,超过上下限报警,报警温度可手动调整。
K1 是用来 * 进入上下限调节模式的,当按一下 K1 进入上限调节模式,再按一下进入下限 * 调节模式。
在正常模式下,按一下K2 进入查看上限温度模式,显示 1s 左右自动* 退出;按一下 K3 进入查看下限温度模式,显示 1s 左右自动退出;按一下 K4 消除 * 按键音,再按一下启动按键音。
在调节上下限温度模式下, K2 是实现加 1 功能, * K1 是实现减 1 功能, K3 是用来设定上下限温度正负的。
* 编程者: ZPZ * 编程时间: 2009/10/2*******************************************************************bit s=0;〃s 是调整上下限温度时温度闪烁的标志位, s=0不显示200ms , s=1 显示 1s 左右bit s1=0; void display1(uint z); #include"ds18b20.h" //s1 标志位用于上下限查看时的显示//声明 display1 ()函数//将 ds18b20.h 头文件包含到主程序#include"keyscan.h" #include"display.h"/***********************//将 keyscan.h 头文件包含到主程序 //将 display.h 头文件包含到主程序 主函数 ************************/#include<AT89X52.h> #include<intrins.h>// 将 AT89X52.h 头文件包含到主程序 //将 intrins.h 头文件包含到主程序(调用其中的 函数延时)_nop_() 空操作#define uint unsigned int #define uchar unsigned char uchar max=0x00,min=0x00;//变量类型宏定义,用 //变量类型宏定义,用//max 是上限报警温度, uint 表示无符号整形( 16 位) uchar 表示无符号字符型( 8 位)min 是下限报警温度void main(){beer=1;led=1; timer1_init(0); get_temperature(1);while(1){keyscan();get_temperature(0);//获取温度函数//关闭蜂鸣器// 关闭LED 灯//初始化定时器1(未启动定时器1)// 首次启动DS18B20 获取温度(DS18B20 上点后自动将EEPROM 中的上下限温度复制到TH 和TL 寄存器)//主循环//按键扫描函数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单片机简易温度显示器汇编程序·.
FLAG1 BIT F0 ;DS18B20存在标志位FLAG2 EQU 27HDQ BIT P3.7TEMPER_L EQU 29HTEMPER_H EQU 28HA_BIT EQU 35HB_BIT EQU 36H;************程序起始********************ORG 0000HAJMP MAINORG 0100H;**************主程序开始************MAIN:LCALL INIT_18B20LCALL RE_CONFIGLCALL GET_TEMPERAJMP CHANGE;**********DS18B20复位程序*****************INIT_18B20: SETB DQNOPCLR DQMOV R0,#0FBHTSR1: DJNZ R0,TSR1 ;延时SETB DQMOV R0,#25HTSR2: JNB DQ ,TSR3DJNZ R0,TSR2TSR3: SETB FLAG1 ;置标志位,表明DS18B20存在AJMP TSR5TSR4: CLR FLAG1LJMP TSR7TSR5:MOV R0,#06BHTSR6:DJNZ R0,TSR6TSR7:SETB DQ ;表明不存在RET;********************设定DS18B20暂存器设定值************** RE_CONFIG:JB FLAG1,RE_CONFIG1RETRE_CONFIG1: MOV A,#0CCH ;放跳过ROM命令LCALL WRITE_18B20MOV A,#4EHLCALL WRITE_18B20 ;写暂存器命令MOV A,#00H ;报警上限中写入00HLCALL WRITE_18B20MOV A,#00H ;报警下限中写入00HLCALL WRITE_18B20MOV A,#1FH ;选择九位温度分辨率LCALL WRITE_18B20RET;*****************读转换后的温度值****************GET_TEMPER:SETB DQLCALL INIT_18B20JB FLAG1,TSS2RET ;若不存在则返回TSS2: MOV A,#0CCH ;跳过ROMLCALL WRITE_18B20MOV A,#44H ;发出温度转换命令LCALL WRITE_18B20LCALL D1ms ;延时LCALL INIT_18B20MOV A,#0CCH ;跳过ROMLCALL WRITE_18B20MOV A,#0BEH ;发出读温度换命令LCALL WRITE_18B20LCALL READ2_18B20 ;读两个字节的温度RET;***************写DS18B20程序************WRITE_18B20:MOV R2,#8CLR CWR1:CLR DQMOV R3,#6DJNZ R3,$RRC AMOV DQ,CMOV R3,#23DJNZ R3,$SETB DQNOPDJNZ R2,WR1SETB DQRET;***********读18B20程序,读出两个字节的温度*********READ2_18B20:MOV R4,#2MOV R1,#29H ;低位存在29 H,高位存在28H RE00: MOV R2,#8RE01: CLR CSETB CNOPNOPCLR DQNOPNOPNOPSETB DQMOV R3,#7DJNZ R3,$MOV C,DQMOV R3,#23DJNZ R3,$RRC ADJNZ R2,RE01MOV @R1,ADEC R1DJNZ R4,RE00RET;************读出的温度进行数据转换**************CHANGE: CLR FLAG2.0MOV A,28HSUBB A,#0F8HJC TEM0 ;判断温度值是否为负,若不是则跳转SETB FLAG2.0 ;是,置标志位FLAG2MOV A,28HCPL AMOV 28H,AMOV A,29HCPL AINC AMOV 29H,ATEM0: MOV A,29HMOV C,28H.0 ;将28H中的最低位移入CRRC AMOV C,28H.1RRC AMOV C,28H.2RRC AMOV C,28H.3RRC AMOV 29H,ALCALL DISPLAY ;调用数码管显示子程序LJMP MAIN;*******************DISPLAY******DISPLAY: mov a,29H;将29H中的十六进制数转换成10进制mov b,#10 ;10进制/10=10进制div abmov b_bit,a ;十位在amov a_bit,b ;个位在bmov r0,#4dpl1: mov r1,#250 ;显示1000次dplop: mov a,a_bit ;取个位数SETB P2.3CLR P2.0MOV P0,#0x3facall d1msmov dptr,#TAB1 ;指定查表启始地址MOVC A,@A+DPTR ;查个位数的7段代码SETB P2.0CLR P2.1;开个位显示mov p0,a ;送出个位的7段代码acall d1ms ;显示1msmov a,b_bit ;取十位数mov dptr,#TAB ;指定查表启始地址MOVC A,@A+DPTR ;查十位数的7段代码setb P2.1clr P2.2;开十位显示mov p0,a ;送出十位的7段代码acall d1ms ;显示1msJNB FLAG2.0 , FUSETB P2.2CLR P2.3MOV P0,#40HFU: SETB P2.2acall d1msdjnz r1,dplop ;100次没完循环djnz r0,dpl1 ;4个100次没完循环ret;***********************************D1MS: MOV R7,#20 ;1MS延时(按12MHZ算)DJNZ R7,$RET;**********************************************************TAB: DB 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71TAB1: DB 0BFH,86H,0DBH,0CFH,0E6H,0EDH,0FDH,87H,0FFH,0EFH。
基于51单片机――Ds18B20温度采集,LCD显示汇编程序(附带proteus仿真图)
TEMP_ZH EQU 24H ;实测温度值存放单元TEMPL EQU 25H TEMPH EQU 26HTEMP_TH EQU 27H ;高温报警值存放单元TEMP_TL EQU28H ;TEMPHC EQU 29H ;TEMPLC EQU 2AHTEMPFC EQU 2BHK1 EQU P1.4K2 EQU P1.5 ;K3 EQU P1.6 ;K4 EQU P1.7 ;BEEP EQU P3.7 ;RELAY EQU P1.3 ;LCD_X EQU 2FH ;LCDLCD_RS EQU P2.0 ;LCDLCD_RW EQU P2.1 ;LCDLCD_EN EQU P2.2 ;LCDFLAG1 EQU 20H.0 ;DS18B20KEY_UD EQU 20H.1 ;DQEQU P3.3低温报警值存放单元正、负温度值标记查询按键设置/调整键调整键确定键蜂鸣器指示灯字符显示位置寄存器选择信号读写信号允许信号是否存在标志设定按键的增、减标志数据信号;;DS18B20ORG 0000HLJMP MAINORG 0030HMAIN: MOV SP,#60HMOV A,#00HMOV R0,#20HMOV R1,#10HCLEAR: MOV @R0,AINC R0DJNZ R1,CLEARLCALL SET_LCDLCALL RE_18B20START: LCALL RSTJNB FLAG1,START1LCALL MENU_OK信息子程序MOV TEMP_TH,#055HMOV TEMP_TL,#019HLCALL RE_18B20ALCALL WRITE_E2 ;LCALL TEMP_BJ ;JMP START2;将20H~2FH单元清零;调用18B20复位子程序;DS1820不存在;DS1820存在,调用显示正确设置TH初值85度设置TL初值25度调用暂存器操作子程序写入DS18B20显示温度标记;;;START1: LCALL MENU_ERROR;调用显示出错信息子程序LCALL TEMP_BJ ;显示温度标记SJMP $START2: LCALL RST;调用DS18B20复位子程序JNBFLAG1,START1;DS18B20不存在MOV A,#0CCHLCALL WRITEMOV A,#44HLCALL WRITELCALL RSTMOV A,#0CCHLCALL WRITEMOV A,#0BEHLCALL WRITELCALL READ子程序LCALL CONVTEMP程序LCALL DISPBCDLCALL CONVLCALL TEMP_COMP值比较子程序;跳过ROM匹配命令;温度转换命令;跳过ROM匹配;读温度命令;调用DS18B20数据读取操作;调用温度数据BCD码处理子;调用温度数据显示子程序;调用LCD显示处理子程序;调用实测温度值与设定温度LCALLPROC_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值写入DS18B20 LCALL WRITE_E2PROC_K2: LCALL MENU_OKLCALL TEMP_BJPROC_END:RET;******************************************************SET_ALARM:LCALL LOOK_ALARMAS0: JB K1,AS00LCALL BEEP_BLJNB K1,$CPL 20H.1 ;UP/DOWNAS00: JB 20H.1,ASZ01 ;20H.1=1JMP ASJ01 ;20H.1=0ASZ01: JB K2,ASZ02 ;THLCALL BEEP_BLINC TEMP_THMOV A,TEMP_THCJNE A,#120,ASZ011MOV TEMP_TH,#0ASZ011: LCALL LOOK_ALARM设定温度报警值标记,增加,减小值调整(增加)TH、TLMOV R5,#10LCALL 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,AS0LCALL BEEP_BLJNB K4,$RETASJ01: JB K2,ASJ02LCALL BEEP_BLDEC TEMP_THMOV A,TEMP_THCJNE A,#0FFH,ASJ011;确定调整;TH值调整(减少)JMP ASJ022ASJ011: 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:MOVA,TEMP_THSUBBA,TEMP_ZH;减数>被减数,则JC CHULI1;借位标志位C=1,转MOV A,TEMPFCCJNEA,#0BH,COMPSJMPCHULI2COMP: MOV A,TEMP_ZHSUBB A,TEMP_TL ;JC CHULI2 ;MOV DPTR,#BJ5LCALL TEMP_BJ3CLR RELAYRETCHULI1: MOV DPTR,#BJ3LCALL TEMP_BJ3SETB RELAY ;LCALL BEEP_BLRETCHULI2: MOV DPTR,#BJ4LCALL TEMP_BJ3SETB RELAY ;减数>被减数,则借位标志位C=1,转;点亮指示灯熄灭指示灯蜂鸣器响熄灭指示灯;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,TSR1程序SETB DQ;拉高数据线NOPNOPNOPMOV R0,#32HTSR2: JNB DQ,TSR3;等待DS18B20回应DJNZ R0,TSR2JMP TSR4 ;延时TSR3: SETB FLAG1 ;置1标志位,表示DS1820存在JMP TSR5 TSR4: CLR FLAG1 ;清0标志位,表示DS1820不存在JMP TSR7 TSR5: 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位精度RET;************************复制暂存器子程序*******************************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,#40HMOV 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微妙以上RRCA ;把一个字节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元RE00: MOV R2,#8RE01: CLR CYSETB DQNOPNOPCLR DQNOPNOPNOPSETB DQMOV R3,#09DJNZ R3,$MOV C,DQMOV R3,#3CH;存入25H、26H、27H、28H单;读前总线保持为低;开始读总线释放;延时18微妙;从DS18B20总线读得一位DJNZ 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 ;MOV DPTR,#TEMPDOTTABMOVC A,@A+DPTRMOV TEMPLC,A ;TEMPLC LOW=分BCD MOV A,TEMPL ;ANL A,#0F0H ;SWAP AMOV TEMPL,AMOV A,TEMPH ;ANL A,#0FHSWAP AORL A,TEMPL ;乘0.0625小数部整数部分取出高四位取出低四位重新组合MOV TEMP_ZH,ALCALL HEX2BCD1MOV TEMPL,AANL A,#0F0HSWAP AORL A,TEMPHC ;TEMPHCBCDMOV TEMPHC,AMOV A,TEMPLANL A,#0FHSWAP A ;TEMPLC HI =BCD ORL A,TEMPLCMOV TEMPLC,AMOV A,R4JZ TEMPC12ANL A,#0FHSWAP AMOV R4,AMOV A,TEMPHC ;TEMPHC HI =BCDANL A,#0FHLOW=十位数个位数百位数ORL 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,#3LCALL SHOW_DIG2H ;MOV A,#0CEHLCALL TEMP_BJ1MOV A,TEMP_TLMOV LCD_X,#12LCALL SHOW_DIG2L ;RETM_ALAX1: DB " LOOK ALERT CODE",0M_ALAX2: DB "TH: TL: ",0TEMP_BJ1: LCALL WCOMMOV DPTR,#BJ2MOV R1,#0MOV R0,#2BBJJ2: MOV A,R1MOVC A,@A+DPTRLCALL WDATA;设置显示位置显示数据;加载TL数据;设置显示位置显示数据;指针指到显示信息区INC R1DJNZ 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 LCDP2显示子程序POP B INC 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,73HMOV LCD_X,#6CJNE A,#1,CONV1JMP CONV2CONV1: CJNE A,#0BH,CONV11MOV A,#"-"JMP CONV111CONV11: MOV A,#" "CONV111: MOV B,LCD_XLCALL LCDP2JMP CONV3CONV2: LCALL SHOW_DIG2CONV3: INC LCD_XMOV A,72HLCALL SHOW_DIG2MOV A,71HLCALL 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_XRET;***************************第二行显示数字子程序*************************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的CGRAMRET;*****************************************************************INIT_LCD: MOV A,#38H ;2行显示,字形5*7点阵LCALL WCOMLCALL DELAY1MOV A,#38HLCALL DELAY1MOV A,#38HLCALL WCOMLCALL DELAY1MOV A,#0CH ;开显示,显示光标,光标不闪烁LCALL WCOMLCD 初始化LCALL 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;***************************清除****************************CLR_LINE: MOV R0,#24CL1: MOV A,#' 'LCALL WDATADJNZ R0,CL11行LCD的字符RETDE: MOV R7,#250DJNZ R7,$RET;****************************LCD间接控制方式命令写入*************************WCOM: MOV P0,A ;写入命令CLR LCD_RS ;RS=L,RW=L,D0-D7=指令码,E=高脉冲CLR LCD_RW SETB LCD_ENLCALL DELAY1CLR LCD_ENRET;****************************LCD间接控制方式数据写入*************************WDATA: MOV P0,A ;写入数据SETB LCD_RSCLR LCD_RWSETB LCD_ENLCALL DECLR LCD_ENLCALL 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,#10LCALL DELAYRETDEX1: 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子程序时。
基于51单片机的12864显示温度(ds18b20)
#ifndef __LCD12864_H#define __LCD12864_H//---包含头文件---//#include<reg51.h>//---重定义关键词---//#ifndef uchar#define uchar unsigned char#endif#ifndef uint#define uint unsigned int#endif//---如果使用画图模式定义这个---//#define LCD12864_PICTURE//---定义使用的IO口---//#define LCD12864_DATAPORT P1 //数据IO口sbit LCD12864_RS = P2^6; //(数据命令)寄存器选择输入sbit LCD12864_RW = P2^5; //液晶读/写控制sbit LCD12864_EN = P2^7; //液晶使能控制sbit LCD12864_PSB = P3^2; //串/并方式控制sbit LCD12864_RST = P3^4; //复位端//---声明全局函数---//void LCD12864_Delay1ms(uint c);uchar LCD12864_Busy(void);void LCD12864_WriteCmd(uchar cmd);void LCD12864_WriteData(uchar dat);void LCD12864_Init();void LCD12864_ClearScreen(void);void LCD12864_SetWindow(uchar x, uchar y);void LCD12864_DrowPic(uchar *a);void LCD12864_DrowPoint(uchar x, uchar y);#endif#ifndef __TEMP_H_#define __TEMP_H_#include<reg51.h>//---重定义关键词---//#ifndef uchar#define uchar unsigned char#endif#ifndef uint#define uint unsigned int#endif//--定义使用的IO口--//sbit DSPORT=P3^3;//--声明全局函数--//void Delay1ms(uint );uchar Ds18b20Init();void Ds18b20WriteByte(uchar com);uchar Ds18b20ReadByte();void Ds18b20ChangTemp();void Ds18b20ReadTempCom();int Ds18b20ReadTemp();#endif#include"lcd12864.h"/****************************************************************************** ** 函数名: LCD12864_Delay1ms* 函数功能: 延时1MS* 输入: c* 输出: 无******************************************************************************* /void LCD12864_Delay1ms(uint c)uchar a,b;for(; c>0; c--){for(b=199; b>0; b--){for(a=1; a>0; a--);}}}/****************************************************************************** ** 函数名: LCD12864_Busy* 函数功能: 检测LCD是否忙* 输入: 无* 输出: 1或0(1表示不忙,0表示忙)******************************************************************************* /uchar LCD12864_Busy(void){uchar i = 0;LCD12864_RS = 0; //选择命令LCD12864_RW = 1; //选择读取LCD12864_EN = 1;LCD12864_Delay1ms(1);while((LCD12864_DA TAPORT & 0x80) == 0x80) //检测读取到的值{i++;if(i > 100){LCD12864_EN = 0;return 0; //超过等待时间返回0表示失败}}LCD12864_EN = 0;return 1;}/****************************************************************************** ** 函数名: LCD12864_WriteCmd* 函数功能: 写命令* 输入: cmd* 输出: 无******************************************************************************* /void LCD12864_WriteCmd(uchar cmd){uchar i;i = 0;while( LCD12864_Busy() == 0){LCD12864_Delay1ms(1);i++;if( i>100){return; //超过等待退出}}LCD12864_RS = 0; //选择命令LCD12864_RW = 0; //选择写入LCD12864_EN = 0; //初始化使能端LCD12864_DATAPORT = cmd; //放置数据LCD12864_EN = 1; //写时序LCD12864_Delay1ms(1);LCD12864_EN = 0;}/****************************************************************************** ** 函数名: LCD12864_WriteData* 函数功能: 写数据* 输入: dat* 输出: 无******************************************************************************* /void LCD12864_WriteData(uchar dat){uchar i;i = 0;while( LCD12864_Busy() == 0){LCD12864_Delay1ms(1);i++;if( i>100){return; //超过等待退出}}LCD12864_RS = 1; //选择数据LCD12864_RW = 0; //选择写入LCD12864_EN = 0; //初始化使能端LCD12864_DATAPORT = dat; //放置数据LCD12864_EN = 1; //写时序LCD12864_Delay1ms(1);LCD12864_EN = 0;}/****************************************************************************** ** 函数名: LCD12864_ReadData* 函数功能: 读取数据* 输入: 无* 输出: 读取到的8位数据******************************************************************************* /#ifdef LCD12864_PICTUREuchar LCD12864_ReadData(void){uchar i, readValue;i = 0;while( LCD12864_Busy() == 0){LCD12864_Delay1ms(1);i++;if( i>100){return 0; //超过等待退出}}LCD12864_RS = 1; //选择命令LCD12864_RW = 1;LCD12864_EN = 0;LCD12864_Delay1ms(1); //等待LCD12864_EN = 1;LCD12864_Delay1ms(1);readValue = LCD12864_DA TAPORT;LCD12864_EN = 0;return readValue;}#endif/****************************************************************************** ** 函数名: LCD12864_Init* 函数功能: 初始化LCD12864* 输入: 无* 输出: 无******************************************************************************* /void LCD12864_Init(){LCD12864_PSB = 1; //选择并行输入LCD12864_RST = 1; //复位LCD12864_WriteCmd(0x30); //选择基本指令操作LCD12864_WriteCmd(0x0c); //显示开,关光标LCD12864_WriteCmd(0x01); //清除LCD12864的显示内容}/****************************************************************************** ** 函数名: LCD12864_ClearScreen* 函数功能: 在画图模式下,LCD12864的01H命令不能清屏,所以要自己写一* * 屏函数* 输入: 无* 输出: 无******************************************************************************* /#ifdef LCD12864_PICTUREvoid LCD12864_ClearScreen(void){uchar i,j;LCD12864_WriteCmd(0x34); //开启拓展指令集for(i=0;i<32;i++) //因为LCD有纵坐标32格所以写三十二次{LCD12864_WriteCmd(0x80+i); //先写入纵坐标Y的值LCD12864_WriteCmd(0x80); //再写入横坐标X的值for(j=0;j<32;j++) //横坐标有16位,每位写入两个字节的的数据,也{ //就写入32次以为当写入两个字节之后横坐标会自LCD12864_WriteData(0x00); //动加1,所以就不用再次写入地址了。
用单片机显示温度的汇编程序
用单片机显示温度的汇编程序一、引言在现代科技发展的背景下,温度的测量和显示变得越来越重要。
而单片机作为一种集成电路,具有高效、可靠、灵活等特点,被广泛应用于温度测量和显示领域。
本文将以汇编语言为主,介绍如何使用单片机实现温度的测量和显示。
二、硬件准备我们需要准备相应的硬件设备。
主要包括:单片机、温度传感器、数码管等。
其中,单片机是核心控制器,温度传感器用于测量温度,数码管用于显示温度数值。
三、软件准备在开始编写汇编程序之前,我们需要安装相应的开发工具和编译器。
常用的开发工具有Keil、IAR等,编译器可以选择C51等。
四、编写汇编程序1. 初始化在汇编程序中,首先需要进行初始化操作。
具体步骤如下:(1)设置端口:将数码管所在的端口设置为输出模式,用于控制数码管的显示。
(2)初始化温度传感器:根据具体型号和通信协议,进行相应的初始化设置。
2. 温度测量在初始化完成后,可以开始进行温度的测量。
具体步骤如下:(1)启动温度传感器:发送启动命令,使传感器开始工作。
(2)等待温度传感器完成测量:根据传感器的特性,等待一定的时间,使传感器完成温度的测量。
(3)读取温度值:将传感器测量到的温度值读取到寄存器中。
3. 温度显示在获取到温度值后,可以开始进行温度的显示。
具体步骤如下:(1)将温度值转换为数码管所需的显示格式:根据实际需要,将温度值进行转换,转换为数码管可以显示的格式。
(2)将转换后的数值依次发送到数码管:根据数码管的接口协议,将转换后的数值依次发送到数码管,使其显示温度数值。
五、调试与测试在编写完成汇编程序后,需要进行调试和测试,以确保程序运行正常。
可以通过连接单片机和电脑进行调试,观察温度数值是否正确显示在数码管上。
六、总结本文以汇编语言为主,介绍了使用单片机显示温度的方法。
通过编写汇编程序,实现了温度的测量和显示功能,将温度数值准确地显示在数码管上。
这种方法在温度测量和显示领域具有广泛的应用前景,可以满足各种温度监测和控制的需求。
51单片机温度计程序
5)在计时状态停止时按动KFUN键可复位计时时间
6)按动KFUN键可启动或停止计时
7)在计时过程中按动KADD或KSUB键,可暂停计时和连续计时
8)倒顺计时的任意情况下按动KSET键,可退出计时回到正常的时钟状态
//uchar DB_tmp[5]; //存放从键盘输入的密码
uchar Disp[4];//显示寄存器
uchar Bset=0;//功能状态寄存器。
uchar error;//记录密码错误状态
uchar hold=50;//蜂鸣器保持时间。
uchar msecl,msec,second;//10毫秒,0.5秒,秒计时单元。
write_byte(0x44);//发出温度转换命令
delay(70);//800us
ow_reset();//p
for(i=32;i>0;i--);
write_byte(0xcc);
write_byte(0xbe);//发出读温度命令
for(i=2;i>0;i--);
5、单灯亮时,需要输入正确密码,亮起双灯才能修改密码
6、长按Kset键,系统锁定,红灯亮起
三、温度模块
可设定报警温度上限和下限。温度超限时,发出蜂鸣报警声。
1、在时间模块,通过长按set键进入温度模块。
2、在温度模块下,按动up键进入温度上限设置。按动down键,进入温度下限报警设置。
void delay(uchar i)
{
uchar j;
基于51单片机的数字温度计设计及应用
基于51单片机的数字温度计设计及应用数字温度计是一种测量环境温度的设备,它使用数字技术来转换和显示温度值。
基于51单片机的数字温度计设计及应用,我们将使用51单片机作为主控芯片,采集传感器的温度数据并将其转换为数字信号,然后通过数码管显示出来。
首先,我们需要选择合适的温度传感器。
常见的温度传感器有热敏电阻、热电偶和数字温度传感器等。
在本设计中,我们将使用DS18B20数字温度传感器。
DS18B20具有高精度、数字输出、通信简单等优点,非常适合于数字温度计的设计。
接下来,我们需要设计硬件电路。
首先,将DS18B20传感器连接到51单片机的GPIO引脚,并通过一条数据线进行通信。
接下来,将51单片机的引脚连接到数码管显示模块,用于将温度值显示出来。
此外,还可以添加其他功能,如按键开关用于控制菜单切换、蜂鸣器用于报警等。
在软件设计上,首先需要初始化51单片机的GPIO引脚,配置为输入或输出模式,通信时需要配置为模拟输入模式。
然后,利用51单片机的定时器模块生成一定频率的时钟信号,用于与DS18B20传感器通信。
在温度读取过程中,我们需要发送一系列的指令给DS18B20传感器,然后接收传感器返回的温度值。
根据DS18B20传感器的数据手册,我们可以编写相应的C语言代码进行数据的读取和解析。
接着,我们需要将读取到的温度值进行转换和显示。
由于DS18B20传感器输出的温度值为16位二进制补码形式,我们可以使用移位和逻辑运算等操作进行转换。
转换后的温度值可以直接显示在数码管上,通过扫描显示的方式实时更新温度数值。
在应用方面,基于51单片机的数字温度计可以广泛应用于各种温度测量场景。
例如,可以应用于室内温度测量,工业过程控制,农业温室监测等。
由于51单片机具有低功耗、成本低廉等优点,这种数字温度计可以在各种资源有限的环境中使用。
除了基本功能外,我们还可以进行功能扩展。
例如,可以添加存储功能,将温度数据保存到外部存储器中,以便进行后续分析和处理。
基于51单片机的数字温度计实现
基于51单片机的数字温度计实现数字温度计是一种能够精确测量温度的仪器,利用数字技术将温度传感器测得的模拟信号转换成数字信号,以显示出实时温度数值。
在这个任务中,我们要使用51单片机来实现一个基于数字技术的温度计。
首先,我们需要一种温度传感器,常用的有热敏电阻传感器和数字温度传感器。
在这里,我们选择使用热敏电阻传感器,因为它价格低廉且性能稳定。
热敏电阻传感器的电阻值会随着温度的变化而发生改变,我们可以利用这个特性来测量温度。
51单片机是一种常用的微型计算机芯片,具有强大的计算和控制能力,非常适合用于实现温度计。
我们可以将热敏电阻传感器连接到单片机的模拟输入引脚上,通过读取引脚上的电压值来获取温度值。
接下来,我们需要编写51单片机的程序来实现温度的转换和显示。
首先,我们需要将模拟信号通过模数转换器(ADC)转换成数字信号。
然后,我们可以通过一定的算法将数字信号转换成对应的温度数值。
为了实现温度的显示,我们可以连接一个LCD液晶屏到51单片机上。
LCD屏幕可以显示数字和字符,我们可以在屏幕上显示实时的温度数值。
除了温度的显示,我们还可以添加一些功能来增强温度计的实用性。
例如,我们可以设置一个温度报警功能,在温度超过一定阈值时发出声音或亮起警示灯。
这样可以方便用户随时知晓温度是否正常。
另外,我们还可以为温度计添加保存数据的功能。
通过连接一个存储器芯片,我们可以将温度数据存储下来,方便后续分析和查看。
总之,基于51单片机的数字温度计实现可以通过连接热敏电阻传感器并编写相应的程序来实现温度的测量和显示。
通过添加额外的功能,例如温度报警和数据存储,可以增强温度计的实用性和功能性。
这样的温度计可以广泛应用于室内温度检测、工业控制和科研实验等领域。
51单片机显示温度程序
{ 1,0,0,1,1,0,0 }, // = 4
{ 0,1,0,0,1,0,0 }, // = 5
digitalWrite(g, HIGH);
digitalWrite(p, HIGH);
}
// 点亮对应数字的数码管
void lightSegments(int x) {
for (int i = 0; i < 7; i++) {
digitalWrite(segs[i], seven_seg_digits[x][i]);
digitalWrite(d4, LOW);
switch(x)
{
case 1:
digitalWrite(d1, HIGH);
break;
case 2:
digitalWrite(d2, HIGH);
break;
case 3:
digitalWrite(d3, HIGH);
break;
default:
digitalWrite(d4, HIGH);
break;
}
}
void dispDec(int x) //设定开启小数点
{
digitalWrite(p, LOW);
}
void clearLEDs() //清屏
{
#include <OneWire.h>
#include <DallasTemperature.h>
#include <MsTimer2.h>
// 定义DS18B20数据口连接arduino的2号IO上
基于51单片机的温度控制及显示系统
基于51单片机的温度控制及显示系统65100226 徐凤贺基于51单片机的温度控制及显示系统摘要:在现代化工业生产中,温度是常用的测量机被控参数。
本温度控制及显示装置采用STC89C51为核心控制器件实现对温度在50℃到70℃的自动控制。
由数字温度传感器DS18B20构成信号采集电路,由LED数码管构成静态显示用于显示温度值,由发光二级管来模拟控制器件,红色二极管模拟加热器件,绿色二极管模拟降温装置。
关键词:STC89C51单片机 DS18B20 发光二级管 LED显示一设计任务和要求1 任务设计并制作一个温度自动控制及显示装置,可以让温度保持在50℃到70℃,并能用LED显示所采集的温度。
2 要求(1)利用18B20温度传感器检测温度,并采集的温度值送入AT89C51单片机。
(2)当温度低于50℃时加热,高于50℃时停止加热,高于70℃时制冷。
(3)能用LED显示实时温度。
二方案分析与论证1 单片机模块方案论证方案一:采用MC68HC05/08系列单片机对系统进行控制。
其乘法和除法指令给编程带来了便利。
但是其指令系统共有89条指令,不利于CPU的执行速度。
方案二:采用MSP430X44X系列单片机对系统进行控制。
其端口过多,操作繁杂,指令虽与MCS-51系列单片机相似,却比MCS-51系列单片机更难操作,而且本装置不需要过多的IO口。
方案三:采用MCS-51系列单片机对系统进行控制。
MCS-51系列单片机采用哈佛体系结构,其程序存储器和数据存储器独立编址。
7中寻址方式,111条系统指令,操作简单。
MCS-51系列单片机内部自带2个定时计数器方便定时计数操作,此外MCS-51系列单片机有5种中断方式,方便中断编程控制。
综上所述:控制器选方案三.2 温度传感器模块方案论证方案一:用DS18B20监测环境温度并送给单片机。
DS18B20 与单片机的接口电路非常简单。
DS18B20 只有三个引脚一个接地,一个接电源,一个数字输入输出引脚接单片机I/O 口。
基于51单片机的DS18B20温度显示
基于51单片机的DS18B20温度显示本讲内容:了解温度传感器DS18B20的使用,并通过一个例程展示温度传感器DS18B20测温过程。
DS18B20简介:DS18B20 是单线数字温度传感器,即“一线器件”,其具有独特的优点:(1)采用单总线的接口方式与微处理器连接时仅需要一条口线即可实现微处理器与 DS18B20 的双向通讯。
单总线具有经济性好,抗干扰能力强,适合于恶劣环境的现场温度测量,使用方便等优点,使用户可轻松地组建传感器网络。
(2)测量温度范围宽,测量精度高。
DS18B20 的测量范围为-55 ℃ ~+ 125 ℃;在 -10~+ 85°C 范围内,精度为± 0.5°C 。
(3)多点组网功能多个 DS18B20 并联在惟一的单线上,实现多点测温。
DS18B20的存储器由一个高速暂存RAM 和一个非易失性、电可擦除(E2)RAM 组成。
配置寄存器:出场设置默认R0、R1为11。
也就是12位分辨率,也就是1位代表0.0625摄氏度。
DS18B20经转换所得的温度值以二字节补码形式存放在高速暂存存储器的第0和第1个字节。
所以当我们只想简单的读取温度值的时候,只用读取暂存器中的第0和第1个字节就可以了。
简单的读取温度值的步骤如下: 1:跳过ROM 操作 2:发送温度转换命令 3:跳过ROM 操作 4:发送读取温度命令 5:读取温度值 DS18B20接口电路图:DS18B20的初始化:主机首先发出一个480-960微秒的低电平脉冲,然后释放总线变为高电平,并在随后的480微秒时间内对总线进行检测,如果有低电平出现说明总线上有器件已做出应答。
若无低电平出现一直都是高电平说明总线上无器件应答。
做为从器件的DS18B20在一上电后就一直在检测总线上是否有480-960微秒的低电平出现,如果有,在总线转为高电平后等待15-60微秒后将总线电平拉低60-240微秒做出响应存在脉冲,告诉主机本器件已做好准备。
基于51单片机数字温度计设计与实现
基于51单片机数字温度计设计与实现数字温度计是一种常见的电子仪器,用于测量和显示温度。
本文将介绍如何基于51单片机设计和实现一个数字温度计。
首先,我们需要了解51单片机的基本原理和工作方式。
51单片机是一款广泛应用于嵌入式系统中的微控制器,具有低成本、易编程、可扩展等特点。
它由中央处理器、存储器、输入输出端口和定时器等组成,可以实现各种功能。
接下来,我们可以开始设计数字温度计的硬件部分。
首先,我们需要一个温度传感器,如DS18B20数字温度传感器。
该传感器具有高精度和数字输出的特点,可以直接与51单片机进行通信。
然后,将传感器与51单片机的引脚相连,通过读取传感器输出的温度值,即可得到实时的温度数据。
为了方便用户查看温度,我们可以通过数码管或LCD显示屏显示温度值。
数码管是一种7段显示器件,可以显示数字0-9的字符。
我们可以通过将温度值拆分成各个位数,然后将对应的数字发送到数码管上,实现温度的显示。
此外,我们还可以为温度计添加一些附加功能。
例如,可以通过按键切换温度的单位,从摄氏度切换到华氏度。
还可以设置温度报警功能,当温度超过一定阈值时,触发蜂鸣器或LED灯进行报警。
在软件设计方面,我们需要编写51单片机的固件程序来实现温度计的功能。
首先,我们需要初始化51单片机的引脚和定时器。
然后,可以设置一个定时器中断,用于定时读取温度传感器的数值。
在定时器中断的处理函数中,读取温度传感器的数值,并将其转换为摄氏度或华氏度,然后发送到数码管或LCD显示屏上。
此外,我们还可以添加一些交互功能,例如按键实现温度单位切换或报警阈值的设置功能。
通过按键检测的方式,可以在主循环中判断按键的按下和释放,并根据按键的状态进行相应的操作。
最后,我们需要将编写好的固件程序下载到51单片机的存储器中。
可以使用ISP编程器或者串口下载方式进行下载。
下载完成后,将51单片机与硬件连接好,就可以通过操作按键和观察数码管或LCD显示屏来实现数字温度计的功能了。
基于51单片机的温度检测系统程序及仿真
//****************************************//**用DS18B20进行测量,lcd1602显示**//****************************************#include "reg51。
h”#include ”intrins.h”#define uchar unsigned char#define uint unsigned intuchar code table1 []={"ID: "}; //欢迎显示,包括空格在内〈=16uchar code table2 []={"Name: "};//欢迎显示,包括空格在内〈=16uchar code str1 []={” Temperature "};uchar code str2 []={" "};//************管脚定义************************sbit lcd_rs = P3^0; //液晶数据命令选择端sbit lcd_en = P3^1; //液晶使能sbit DQ = P3^6; //液晶使能//************参数定义************************uint tvalue;//温度值uchar tflag;//温度正负标志uchar data disdata[5];//************子函数定义************************void delay(uchar z); //delay延时子程序void init_lcd(); //LCD1602初始化函数void write_com(uchar com); //LCD1602写指令函数void write_data(uchar date); //LCD1602写数据函数void lcd1602_display(uchar *q,uchar *p);//LCD1602显示函数void welcome(); //LCD1602显示欢迎函数void delay_DS18B20(uint i); //delay_DS18B20函数void Init_DS18B20_display(); //DS18B20初始化显示void Init_DS18B20(); //DS18B20初始化uchar ReadOneByte(); //DS18B20读一字节void WriteOneByte(uchar dat); //DS18B20写一字节Read_Temperature(); //DS18B20读取温度值并转换void DS18B20_display(); //DS18B20温度显示//************主函数************************void main(){ welcome();delay(2000);Init_DS18B20_display();while(1){Read_Temperature();DS18B20_display();}}//************delay延时子程序************************void delay(uchar z){uchar x,y;for(x=0;x<z;x++)for(y=0;y〈114;y++);}//************LCD1602初始化函数************************void init_lcd(){write_com(0x38); //设置16*2显示,5*7点阵,8位数据接口write_com(0x08); //写一个字符后地址指针加1write_com(0x01); //显示清零,数据指针清零write_com(0x06); //写一个字符后地址指针加1write_com(0x0c); //关显示,光标不显示不闪烁}//************LCD1602写指令函数************************void write_com(uchar com){delay(5);lcd_rs = 0; // 选择写指令lcd_en = 0; // 将使能端置0P2 = com; // 将要写的命令送到数据总线上delay(5); // 延时5ms,待数据稳定lcd_en = 1; // 由于初始化已将lcd_en置为0,使能端给一个高脉冲, delay(5); // 延时5ms,待数据稳定lcd_en = 0; // 将使能端置0以完成脉冲}//************LCD1602写数据函数************************void write_data(uchar date){delay(5);lcd_rs = 1; // 选择写数据lcd_en = 0; // 将使能端置0P2 = date; // 将要写的数据送到数据总线上delay(5); // 延时5ms,待数据稳定lcd_en = 1; // 由于初始化已将lcd_en置为0,使能端给一个高脉冲,delay(5); // 延时5ms,待数据稳定lcd_en = 0; // 将使能端置0以完成脉冲}//************LCD1602显示函数******************void lcd1602_display(uchar *q,uchar *p){write_com(0x80); // 现将数据指针定位到第一行第一个字处while(*q!=’\0'){write_data(*q);q++;delay(1);}write_com(0xc0); // 现将数据指针定位到第二行第一个字处while(*p!=’\0’){write_data(*p);p++;delay(1);}}//************LCD1602显示欢迎函数******************void welcome(){init_lcd();lcd1602_display(table1,table2);delay(5000);}//************DS18B20初始化显示**************void Init_DS18B20_display(){init_lcd();lcd1602_display(str1,str2);}//************LCD1602显示函数******************void delay_DS18B20(uint i){while(i-—);}//************DS18B20初始化******************void Init_DS18B20(){DQ = 1; //DQ复位delay_DS18B20(4); //延时DQ = 0; //DQ拉低delay_DS18B20(100); //精确延时大于480usDQ = 1; //拉高delay_DS18B20(40);}//************DS18B20读一字节******************uchar ReadOneByte(){uchar i,dat = 0;for(i=8;i>0;i--){DQ = 0;//给脉冲信号dat>>=1;DQ = 1; //给脉冲信号if(DQ) dat|=0x80;delay_DS18B20(10);}return (dat);}//************DS18B20写一字节****************** void WriteOneByte(uchar dat){uchar i;for(i=8;i〉0;i—-){DQ = 0;DQ = dat&0x01;delay_DS18B20(10);DQ = 1;dat〉>=1;}}//************DS18B20读取温度值并转换******************Read_Temperature(){uchar a,b;Init_DS18B20();WriteOneByte(0xcc); //跳过读序列号WriteOneByte(0x44); //启动温度转换Init_DS18B20();WriteOneByte(0xcc); //跳过读序列号WriteOneByte(0xbe); //读取温度a = ReadOneByte();b = ReadOneByte();tvalue=b;tvalue〈<=8;tvalue=tvalue|a;if(tvalue<0xfff)tflag = 0;else{tvalue = ~tvalue+1;tflag = 1;}tvalue = tvalue*(0。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
FLAG1 BIT F0 ;DS18B20存在标志位
FLAG2 EQU 27H
DQ BIT P3.7
TEMPER_L EQU 29H
TEMPER_H EQU 28H
A_BIT EQU 35H
B_BIT EQU 36H
;************程序起始********************
ORG 0000H
AJMP MAIN
ORG 0100H
;**************主程序开始************
MAIN:
LCALL INIT_18B20
LCALL RE_CONFIG
LCALL GET_TEMPER
AJMP CHANGE
;**********DS18B20复位程序*****************
INIT_18B20: SETB DQ
NOP
CLR DQ
MOV R0,#0FBH
TSR1: DJNZ R0,TSR1 ;延时
SETB DQ
MOV R0,#25H
TSR2: JNB DQ ,TSR3
DJNZ R0,TSR2
TSR3: SETB FLAG1 ;置标志位,表明DS18B20存在AJMP TSR5
TSR4: CLR FLAG1
LJMP TSR7
TSR5:MOV R0,#06BH
TSR6:DJNZ R0,TSR6
TSR7:SETB DQ ;表明不存在
RET
;********************设定DS18B20暂存器设定值************** RE_CONFIG:
JB FLAG1,RE_CONFIG1
RET
RE_CONFIG1: MOV A,#0CCH ;放跳过ROM命令
LCALL WRITE_18B20
MOV A,#4EH
LCALL WRITE_18B20 ;写暂存器命令
MOV A,#00H ;报警上限中写入00H
LCALL WRITE_18B20
MOV A,#00H ;报警下限中写入00H
LCALL WRITE_18B20
MOV A,#1FH ;选择九位温度分辨率
LCALL WRITE_18B20
RET
;*****************读转换后的温度值****************
GET_TEMPER:
SETB DQ
LCALL INIT_18B20
JB FLAG1,TSS2
RET ;若不存在则返回TSS2: MOV A,#0CCH ;跳过ROM
LCALL WRITE_18B20
MOV A,#44H ;发出温度转换命令
LCALL WRITE_18B20
LCALL D1ms ;延时
LCALL INIT_18B20
MOV A,#0CCH ;跳过ROM
LCALL WRITE_18B20
MOV A,#0BEH ;发出读温度换命令
LCALL WRITE_18B20
LCALL READ2_18B20 ;读两个字节的温度
RET
;***************写DS18B20程序************
WRITE_18B20:
MOV R2,#8
CLR C
WR1:
CLR DQ
MOV R3,#6
DJNZ R3,$
RRC A
MOV DQ,C
MOV R3,#23
DJNZ R3,$
SETB DQ
NOP
DJNZ R2,WR1
SETB DQ
RET
;***********读18B20程序,读出两个字节的温度*********
READ2_18B20:
MOV R4,#2
MOV R1,#29H ;低位存在29 H,高位存在28H RE00: MOV R2,#8
RE01: CLR C
SETB C
NOP
NOP
CLR DQ
NOP
NOP
NOP
SETB DQ
MOV R3,#7
DJNZ R3,$
MOV C,DQ
MOV R3,#23
DJNZ R3,$
RRC A
DJNZ R2,RE01
MOV @R1,A
DEC R1
DJNZ R4,RE00
RET
;************读出的温度进行数据转换**************
CHANGE: CLR FLAG2.0
MOV A,28H
SUBB A,#0F8H
JC TEM0 ;判断温度值是否为负,若不是则跳转
SETB FLAG2.0 ;是,置标志位FLAG2
MOV A,28H
CPL A
MOV 28H,A
MOV A,29H
CPL A
INC A
MOV 29H,A
TEM0: MOV A,29H
MOV C,28H.0 ;将28H中的最低位移入C
RRC A
MOV C,28H.1
RRC A
MOV C,28H.2
RRC A
MOV C,28H.3
RRC A
MOV 29H,A
LCALL DISPLAY ;调用数码管显示子程序
LJMP MAIN
;*******************DISPLAY******
DISPLAY: mov a,29H;将29H中的十六进制数转换成10进制mov b,#10 ;10进制/10=10进制
div ab
mov b_bit,a ;十位在a
mov a_bit,b ;个位在b
mov r0,#4
dpl1: mov r1,#250 ;显示1000次
dplop: mov a,a_bit ;取个位数
SETB P2.3
CLR P2.0
MOV P0,#0x3f
acall d1ms
mov dptr,#TAB1 ;指定查表启始地址
MOVC A,@A+DPTR ;查个位数的7段代码
SETB P2.0
CLR P2.1;开个位显示
mov p0,a ;送出个位的7段代码
acall d1ms ;显示1ms
mov a,b_bit ;取十位数
mov dptr,#TAB ;指定查表启始地址
MOVC A,@A+DPTR ;查十位数的7段代码
setb P2.1
clr P2.2;开十位显示
mov p0,a ;送出十位的7段代码
acall d1ms ;显示1ms
JNB FLAG2.0 , FU
SETB P2.2
CLR P2.3
MOV P0,#40H
FU: SETB P2.2
acall d1ms
djnz r1,dplop ;100次没完循环
djnz r0,dpl1 ;4个100次没完循环
ret
;***********************************
D1MS: MOV R7,#20 ;1MS延时(按12MHZ算)
DJNZ R7,$
RET
;**********************************************************
TAB: DB 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71
TAB1: DB 0BFH,86H,0DBH,0CFH,0E6H,0EDH,0FDH,87H,0FFH,0EFH。