DS18B20汇编程序

合集下载

DS18B20多路温度采集汇编程序

DS18B20多路温度采集汇编程序

4路DS18B20温度显示汇编程序(可设置上下限和分路查看)作者蔡雄略;操作说明:;------------------------------------------;功能说明:模式选择键按下后,选择循环显示、分路查看,上限设置,下限设置功能;每按一次模式键,对应的模式指示灯会亮起。

;循环显示模式时候,每秒显示一下各路温度状况;分路查看时界面冻结每按一次+或-键进行各路切换;上限设置时每按一次+或-键对各路上限报警进行设置;下限设置时每按一次+或-键对各路下限报警进行设置;------------------------------------------仿真效果图:程序如下:;------------------------------------------;功能说明:模式选择键按下后,选择循环显示、分路查看,上限设置,下限设置功能;循环显示模式时候,每秒显示一下各路温度状况;分路查看时界面冻结每按一次+或-键进行各路切换;上限设置时每按一次+或-键对各路上限报警进行设置;下限设置时每按一次+或-键对各路下限报警进行设置;------------------------------------------;主程序S0EQU30H;50ms计数寄存器MODE_CONT EQU S0+1;模式计数器DS18B20_CONT EQU S0+2HI_TMP_SET_IN EQU S0+3;进水口LOW_TMP_SET_IN EQU S0+4HI_TMP_SET_OUT EQU S0+5;出水口LOW_TMP_SET_OUT EQU S0+6HI_TMP_SET_FRONT EQU S0+7;前后点HI_TMP_SET_BACK EQU S0+8TMP_IN EQU S0+12TMP_OUT EQU S0+13TMP_FRONT EQU S0+14TMP_BACK EQU S0+15DISPLAY_DATA EQU P0;LED数据口KEY_PORT EQU P3;按键口COM_TEMPERL_L BIT P2.7COM_TEMPERL_H BIT P2.6COM_TEMPERH_L BIT P2.5COM_TEMPERH_H BIT P2.4COM_DS18B20_NUM BIT P2.2LED_LOW_SET BIT P3.0LED_HI_SET BIT P3.1LED_CHECK BIT P3.2LED_NORMAL BIT P3.3IN_LED_ALARM_HI BIT P1.1;ININ_LED_ALARM_LOW BIT P1.3OUT_LED_ALARM_HI BIT P1.0;INOUT_LED_ALARM_LOW BIT P1.2FRONT_LED_ALARM_HI BIT P2.0BACK_LED_ALARM_HI BIT P2.1FLAG1BIT20H.5;DS18B20存在标志位DQ1BIT P1.7DQ2BIT P1.6DQ3BIT P1.5DQ4BIT P1.4TEMPER_L EQU28HTEMPER_H EQU27H;------------------------------------------ORG0000HAJMP STARTORG000BH;T0入口LJMP T_INT;------------------------------------------;START初始化;------------------------------------------ORG100HSTART:MOV TEMPER_L,#00HMOV TEMPER_H,#00HMOV MODE_CONT,#00HMOV DS18B20_CONT,#00HMOV HI_TMP_SET_IN,#100;进水口MOV LOW_TMP_SET_IN,#10MOV HI_TMP_SET_OUT,#100;出水口MOV LOW_TMP_SET_OUT,#10MOV HI_TMP_SET_FRONT,#100MOV HI_TMP_SET_BACK,#100CLR TMP_INCLR TMP_OUTCLR TMP_FRONTCLR TMP_BACKMOV S0,#00HMOV TMOD,#01HMOV TH0,#3CH;定时器0,模式1,定时时常50mS MOV TL0,#0B0HMOV IE,#82HMOV KEY_PORT,#0F8HSETB TR0;运行T0LCALL INIT_18B20;------------------------------------------;主函数;------------------------------------------MAIN:LCALL KEYLCALL GET_TEMPER;获取各路温度LCALL DISPLAY;调用显示程序LJMP MAIN;------------------------------------------;T0中服程序,实现1秒一次切换,同时1秒一次的比较各路温度是否超标;------------------------------------------;T0中服程序T_INT:PUSH ACCPUSH PSWMOV TH0,#3CH;定时器0,模式1,定时时常50mSMOV TL0,#0B0H;------------------------------NEXT:INC S0MOV A,S0CJNE A,#14H,ZDMOV S0,#00H;到1S后进行切换INC DS18B20_CONTMOV A,DS18B20_CONTCJNE A,#04H,ZDMOV DS18B20_CONT,#00HLCALL CHECK1;判断各路温度是否超标ZD:POP PSWPOP ACCRETI;-------------------------------------------;ALARM_CHECK;判断各路温度是否超标;-------------------------------------------CHECK1:MOV R0,TMP_INMOV R1,HI_TMP_SET_INLCALL ALARM_CALJZ ALARM_HI_NORMALSETB IN_LED_ALARM_HIJMP CHECK2ALARM_HI_NORMAL:CLR IN_LED_ALARM_HICHECK2:MOV R0,TMP_INMOV R1,LOW_TMP_SET_INLCALL ALARM_CALJNZ CCSETB IN_LED_ALARM_LOWJMP DDCC:CLR IN_LED_ALARM_LOW DD:MOV R0,TMP_OUTMOV R1,HI_TMP_SET_OUTLCALL ALARM_CALJZ EESETB OUT_LED_ALARM_HIJMP DDDEE:CLR OUT_LED_ALARM_HI DDD:MOV R0,TMP_OUTMOV R1,LOW_TMP_SET_OUTLCALL ALARM_CALJNZ FFSETB OUT_LED_ALARM_LOWJMP GGFF:CLR OUT_LED_ALARM_LOW GG:MOV R0,TMP_OUTMOV R1,HI_TMP_SET_FRONTLCALL ALARM_CALJZ HHSETB FRONT_LED_ALARM_HIJMP IIHH:CLR FRONT_LED_ALARM_HI II:MOV R0,TMP_OUTMOV R1,HI_TMP_SET_BACKLCALL ALARM_CALJZ JJSETB BACK_LED_ALARM_HIJMP ALARM_RET1JJ:CLR BACK_LED_ALARM_HI ALARM_RET1:RET;------------------------------------------;R0=R1A=2,R0<R1A=0,R0>R1A=1 ;比较大小;------------------------------------------ALARM_CAL:;R0,R1MOV A,R0SUBB A,R1JC SMALLMOV A,#01HJMP COMP_RETSMALL:MOV A,#0HCOMP_RET:RET;------------------------------------------;显示子程序;时分秒显示;------------------------------------------DISPLAY:MOV DPTR,#TABMOV A,TEMPER_LMOV B,#10DIV ABMOV R4,AMOV R5,BMOV A,R5;温度低位MOVC A,@A+DPTR;显示输出MOV DISPLAY_DATA,ASETB COM_TEMPERL_LLCALL DELAY5MSCLR COM_TEMPERL_LMOV A,R4MOVC A,@A+DPTR;显示输出MOV DISPLAY_DATA,ASETB COM_TEMPERL_HLCALL DELAY5MSCLR COM_TEMPERL_HMOV A,TEMPER_H;温度高位MOV B,#10DIV ABMOV R4,AMOV R5,BMOV A,R5MOVC A,@A+DPTR;显示输出ANL A,#7FH;MOV DISPLAY_DATA,ASETB COM_TEMPERH_LLCALL DELAY5MSCLR COM_TEMPERH_LMOV A,R4MOVC A,@A+DPTRMOV DISPLAY_DATA,ASETB COM_TEMPERH_HLCALL DELAY5MSCLR COM_TEMPERH_HMOV A,DS18B20_CONTINC AMOVC A,@A+DPTR;显示输出MOV DISPLAY_DATA,ASETB COM_DS18B20_NUMLCALL DELAY5MSCLR COM_DS18B20_NUMRET;------------------------------------------;键盘扫描程序;------------------------------------------KEY:;KEY_PORT,#0FFHMOV A,KEY_PORTCPL AANL A,#0F0HJZ RET1LCALL DELAY10MSMOV A,KEY_PORTCPL AANL A,#0F0HJZ RET1JB ACC.7,MODE_CHANGEJB ACC.6,MODE_DEC_JJB ACC.5,MODE_ADD_JJB ACC.4,NUM_ADD_JRET1:RETMODE_DEC_J:LJMP MODE_DECRETMODE_ADD_J:LJMP MODE_ADDRETNUM_ADD_J:LJMP NUM_ADDRETMODE_CHANGE:INC MODE_CONTMOV A,MODE_CONTCJNE A,#04H,MODE_RETMOV MODE_CONT,#00HSETB TR0MODE_RET:LCALL MODE_DEL WAIT:LCALL DISPLAYJNB P3.7,WAITRETMODE_DEL:MOV A,MODE_CONTCJNE A,#00H,MOD_1CLR LED_LOW_SETCLR LED_HI_SETCLR LED_CHECKSETB LED_NORMALRETMOD_1:CJNE A,#01H,MOD_2CLR LED_LOW_SETCLR LED_HI_SETSETB LED_CHECKCLR LED_NORMALCLR TR0RETMOD_2:CJNE A,#02H,MOD_3CLR LED_LOW_SETSETB LED_HI_SETCLR LED_CHECKCLR LED_NORMALCLR TR0RETMOD_3:SETB LED_LOW_SETCLR LED_HI_SETCLR LED_CHECKCLR LED_NORMALCLR TR0RET;-----------------------------------;----------------------------------MODE_DEC:;模式0MOV A,MODE_CONTCJNE A,#00H,MODE_DEC_1 WAIT1:LCALL DISPLAYJNB P3.6,WAIT1RETMODE_DEC_1:;模式1CJNE A,#01H,MODE_DEC_2MOV A,DS18B20_CONTCJNE A,#00H,MODE_DEC_11MOV DS18B20_CONT,#03H WAIT2:LCALL DISPLAYJNB P3.6,WAIT2RETMODE_DEC_11:DEC DS18B20_CONTWAIT3:LCALL DISPLAYJNB P3.6,WAIT3RETMODE_DEC_2:;模式2IN口CJNE A,#02H,MODE_DEC_3MOV A,DS18B20_CONTCJNE A,#00H,MODE_DEC_21DEC HI_TMP_SET_INMOV A,HI_TMP_SET_OUTJNZ MODE_DEC_DELMOV HI_TMP_SET_IN,#64H MODE_DEC_DEL:MOV TEMPER_H,HI_TMP_SET_INMOV TEMPER_L,#00HJMP MODE_DEC_RETMODE_DEC_21:;OUT口MOV A,DS18B20_CONTCJNE A,#01H,MODE_DEC_22DEC HI_TMP_SET_OUTMOV A,HI_TMP_SET_OUTJNZ MODE_DEC_RET1MOV HI_TMP_SET_OUT,#64H MODE_DEC_RET1:MOV TEMPER_H,HI_TMP_SET_OUTMOV TEMPER_L,#00HJMP MODE_DEC_RETMODE_DEC_22:;前点CJNE A,#02H,MODE_DEC_23DEC HI_TMP_SET_FRONTMOV A,HI_TMP_SET_FRONTJNZ MODE_DEC_RET2MOV HI_TMP_SET_FRONT,#64H MODE_DEC_RET2:MOV TEMPER_H,HI_TMP_SET_FRONT MOV TEMPER_L,#00HJMP MODE_DEC_RETMODE_DEC_23:;后点DEC HI_TMP_SET_BACKMOV A,HI_TMP_SET_BACKJNZ MODE_DEC_XMOV HI_TMP_SET_BACK,#64H MODE_DEC_X:MOV TEMPER_H,HI_TMP_SET_BACK MOV TEMPER_L,#00HMODE_DEC_RET:WAIT4:LCALL DISPLAYJNB P3.6,WAIT4RET;------------------------------------;-----------------------------------MODE_DEC_3:;模式3MOV A,DS18B20_CONTCJNE A,#00H,MODE_DEC_21BDEC LOW_TMP_SET_INMOV A,LOW_TMP_SET_INJNZ MODE_DEC_DELBMOV LOW_TMP_SET_IN,#64H MODE_DEC_DELB:MOV TEMPER_H,LOW_TMP_SET_IN MOV TEMPER_L,#00HJMP MODE_DEC_RETBMODE_DEC_21B:;OUT口MOV A,DS18B20_CONTCJNE A,#01H,MODE_DEC_RETBDEC LOW_TMP_SET_OUTMOV A,LOW_TMP_SET_OUTJNZ MODE_DEC_RET1BMOV LOW_TMP_SET_OUT,#64H MODE_DEC_RET1B:MOV TEMPER_H,LOW_TMP_SET_OUT MOV TEMPER_L,#00HMODE_DEC_RETB:WAIT5:LCALL DISPLAYJNB P3.6,WAIT5RET;-----------------------------------;----------------------------------MODE_ADD:MOV A,MODE_CONTCJNE A,#00H,MODE_ADD_1WAIT6:LCALL DISPLAYJNB P3.5,WAIT6RETMODE_ADD_1:;模式1CJNE A,#01H,MODE_ADD_2MOV A,DS18B20_CONTCJNE A,#03H,MODE_ADD_11MOV DS18B20_CONT,#00HWAIT7:LCALL DISPLAYJNB P3.5,WAIT7RETMODE_ADD_11:INC DS18B20_CONTWAIT8:LCALL DISPLAYJNB P3.5,WAIT8RETMODE_ADD_2:;模式2IN口CJNE A,#02H,MODE_ADD_3MOV A,DS18B20_CONTCJNE A,#00H,MODE_ADD_21INC HI_TMP_SET_INMOV A,HI_TMP_SET_OUTCJNE A,#64H,MODE_ADD_DELMOV HI_TMP_SET_IN,#00H MODE_ADD_DEL:MOV TEMPER_H,HI_TMP_SET_IN MOV TEMPER_L,#00HJMP MODE_ADD_RETMODE_ADD_21:;OUT口MOV A,DS18B20_CONTCJNE A,#01H,MODE_ADD_22INC HI_TMP_SET_OUTMOV A,HI_TMP_SET_OUTCJNE A,#64H,MODE_ADD_RET1MOV HI_TMP_SET_OUT,#00H MODE_ADD_RET1:MOV TEMPER_H,HI_TMP_SET_OUTMOV TEMPER_L,#00HJMP MODE_ADD_RETMODE_ADD_22:;前点CJNE A,#02H,MODE_ADD_23INC HI_TMP_SET_FRONTMOV A,HI_TMP_SET_FRONTCJNE A,#64H,MODE_ADD_RET2MOV HI_TMP_SET_FRONT,#00H MODE_ADD_RET2:MOV TEMPER_H,HI_TMP_SET_FRONT MOV TEMPER_L,#00HJMP MODE_ADD_RETMODE_ADD_23:;后点INC HI_TMP_SET_BACKMOV A,HI_TMP_SET_BACKCJNE A,#64H,MODE_ADD_XMOV HI_TMP_SET_BACK,#00HMODE_ADD_X:MOV TEMPER_H,HI_TMP_SET_BACKMOV TEMPER_L,#00HMODE_ADD_RET:WAIT9:LCALL DISPLAYJNB P3.5,WAIT9RET;------------------------------------;-----------------------------------MODE_ADD_3:;模式3MOV A,DS18B20_CONTCJNE A,#00H,MODE_ADD_21BINC LOW_TMP_SET_INMOV A,LOW_TMP_SET_INCJNE A,#64H,MODE_ADD_DELBMOV LOW_TMP_SET_IN,#00H MODE_ADD_DELB:MOV TEMPER_H,LOW_TMP_SET_IN MOV TEMPER_L,#00HJMP MODE_ADD_RETBMODE_ADD_21B:;OUT口MOV A,DS18B20_CONTCJNE A,#01H,MODE_ADD_RETBINC LOW_TMP_SET_OUTMOV A,LOW_TMP_SET_OUTCJNE A,#64H,MODE_ADD_RET1BMOV LOW_TMP_SET_OUT,#64H MODE_ADD_RET1B:MOV TEMPER_H,LOW_TMP_SET_OUT MOV TEMPER_L,#00HMODE_ADD_RETB:WAIT71:LCALL DISPLAYJNB P3.5,WAIT71RET;----------------------------------;----------------------------------NUM_ADD:INC DS18B20_CONTMOV A,DS18B20_CONTCJNE A,#04H,NUM_ADD_RETMOV DS18B20_CONT,#00HNUM_ADD_RET:WAIT81:LCALL DISPLAYJNB P3.5,WAIT81RET;--------------------------------DELAY;延时程序;----------------------------------DELAY5MS:MOV R1,#2;5mS延时#5D1:MOV R2,#248D2:DJNZ R2,D2DJNZ R1,D1RET;------------------------------------------10MS DELAY DELAY10MS:MOV R3,#25;10mS延时D4:MOV R4,#200D3:DJNZ R4,D3DJNZ R3,D4RET;**********DS18B20复位程序***************** INIT_18B20:SETB DQ1SETB DQ2SETB DQ3SETB DQ4NOPNOPNOPNOPCLR DQ1CLR DQ2CLR DQ3CLR DQ4MOV R0,#0FBHTSR1:DJNZ R0,TSR1;延时SETB DQ1SETB DQ2SETB DQ3SETB DQ4MOV R0,#25HTSR2:JNB DQ1,TSR3JNB DQ2,TSR3JNB DQ3,TSR3JNB DQ4,TSR3DJNZ R0,TSR2TSR3:SETB FLAG1;置标志位,表明DS18B20存在AJMP TSR5TSR4:CLR FLAG1LJMP TSR7TSR5:MOV R0,#06BHTSR6:DJNZ R0,TSR6TSR7:SETB DQ1;表明不存在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,#7FH;选择12位温度分辨率LCALL WRITE_18B20RET;*****************读转换后的温度值**************** GET_TEMPER:MOV A,MODE_CONTJZ GET_NEXT;只有模式零才GETCJNE A,#02H,AARETAA:CJNE A,#03H,GET_NEXTRETGET_NEXT:SETB DQ1SETB DQ2SETB DQ3SETB DQ4LCALL INIT_18B20JB FLAG1,TSS2RET;若不存在则返回TSS2:MOV A,#0CCH;跳过ROMLCALL WRITE_18B20MOV A,#44H;发出温度转换命令LCALL WRITE_18B20LCALL INIT_18B20MOV A,#0CCH;跳过ROMLCALL WRITE_18B20MOV A,#0BEH;发出读温度换命令LCALL WRITE_18B20MOV A,DS18B20_CONTCJNE A,#00H,READ_1LCALL READ2_18B20LCALL CHANGE1MOV TMP_IN,TEMPER_HRETREAD_1:MOV A,DS18B20_CONTCJNE A,#01H,READ_2LCALL READ2_18B20_2LCALL CHANGE1MOV TMP_OUT,TEMPER_HRETREAD_2:MOV A,DS18B20_CONTCJNE A,#02H,READ_3LCALL READ2_18B20_3LCALL CHANGE1MOV TMP_FRONT,TEMPER_HRETREAD_3:LCALL READ2_18B20_4;读两个字节的温度LCALL CHANGE1MOV TMP_BACK,TEMPER_HRET;**************************************;***************写DS18B20程序************ WRITE_18B20:MOV R2,#8CLR CWR1:CLR DQ1CLR DQ2CLR DQ3CLR DQ4MOV R3,#6DJNZ R3,$RRC AMOV DQ1,CMOV DQ2,CMOV DQ3,CMOV DQ4,CMOV R3,#23DJNZ R3,$SETB DQ1SETB DQ2SETB DQ3SETB DQ4NOPDJNZ R2,WR1SETB DQ1SETB DQ2SETB DQ3SETB DQ4RET;***********读18B20程序,读出两个字节的温度*********READ2_18B20:MOV R4,#2;低位存在29H,高位存在TEMPER_H MOV R1,#TEMPER_LRE00:MOV R2,#8RE01:CLR CSETB CNOPNOPCLR DQ1NOPNOPSETB DQ1MOV R3,#7DJNZ R3,$MOV C,DQ1MOV R3,#23DJNZ R3,$RRC ADJNZ R2,RE01MOV@R1,ADEC R1DJNZ R4,RE00RET;***********读18B20_2程序,读出两个字节的温度********* READ2_18B20_2:MOV R4,#2;低位存在29H,高位存在TEMPER_H MOV R1,#TEMPER_LRE001:MOV R2,#8RE012:CLR CSETB CNOPCLR DQ2NOPNOPNOPSETB DQ2MOV R3,#7DJNZ R3,$MOV C,DQ2MOV R3,#23DJNZ R3,$RRC ADJNZ R2,RE012MOV@R1,ADEC R1DJNZ R4,RE001RET;***********读18B20_3程序,读出两个字节的温度********* READ2_18B20_3:MOV R4,#2;低位存在29H,高位存在TEMPER_H MOV R1,#TEMPER_LRE002:MOV R2,#8RE013:CLR CSETB CNOPNOPCLR DQ3NOPNOPNOPSETB DQ3MOV R3,#7DJNZ R3,$MOV C,DQ3MOV R3,#23DJNZ R3,$RRC ADJNZ R2,RE013MOV@R1,ADEC R1DJNZ R4,RE002RET;***********读18B20_3程序,读出两个字节的温度********* READ2_18B20_4:MOV R4,#2;低位存在29H,高位存在TEMPER_H MOV R1,#TEMPER_LRE003:MOV R2,#8RE014:CLR CSETB CNOPNOPCLR DQ4NOPNOPNOPSETB DQ4MOV R3,#7DJNZ R3,$MOV C,DQ4MOV R3,#23DJNZ R3,$RRC ADJNZ R2,RE014MOV@R1,ADEC R1DJNZ R4,RE003RET;************读出的温度进行数据转换**************CHANGE1:MOV A,MODE_CONTJZ CHANGE1_NEXT;只有模式零和1才GETCJNE A,#02H,BBRETBB:CJNE A,#03H,CHANGE1_NEXTRETCHANGE1_NEXT:MOV A,TEMPER_LANL A,#0FHMOV B,#6HMUL ABMOV R0,AMOV A,TEMPER_LMOV C,TEMPER_H.0;将TEMPER_H中的最低位移入C RRC AMOV C,TEMPER_H.1RRC AMOV C,TEMPER_H.2RRC AMOV C,TEMPER_H.3RRC AMOV TEMPER_H,AMOV TEMPER_L,R0RET;***********************************D1MS:MOV R7,#80;1MS延时(按12MHZ算)DJNZ R7,$RET;*************************TAB:DB0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90HEND;DB3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,77H,7CH,39H,5EH,79H,71H,0H;共阴极LED;END。

DS18B20汇编程序

DS18B20汇编程序

DS18B20汇编程序,1602液晶显示 2006-1-13 9:44:34TEMPER_L EQU 36HTEMPER_H EQU 35HTEMPER_NUM EQU 60HFLAG1 BIT 00HDQ BIT P3.3RS EQU P3.7 ;RS <---->P2.0RW EQU P3.6 ;R/W <--->P2.1E EQU P3.5 ;E <----->P2.2LCD_DB EQU P1AAA:MOV SP,#70HLCALL GET_TEMPERLCALL TEMPER_COVLCALL DISPLAY;调用显示子程序LJMP AAANOP;------------------读出转换后的温度值GET_TEMPER:SETB DQ ; 定时入口BCD:LCALL INIT_1820JB FLAG1,S22LJMP CC ; 若DS18B20不存在则返回S22:LCALL DELAY1MOV A,#0CCH ; 跳过ROM匹配------0CCLCALL WRITE_1820MOV A,#44H ; 发出温度转换命令LCALL WRITE_1820NOPLCALL DELAYLCALL DELAYCBA:LCALL INIT_1820JB FLAG1,ABCLJMP CBAABC:LCALL DELAY1MOV A,#0CCH ; 跳过ROM匹配LCALL WRITE_1820MOV A,#0BEH ; 发出读温度命令LCALL WRITE_1820LCALL READ_18200 ;READ_1820RET;------------------读DS18B20的程序,从DS18B20中读出一个字节的数据READ_1820:MOV R2,#8RE1:CLR CSETB DQNOPNOPCLR DQNOPNOPNOPSETB DQMOV R3,#7DJNZ R3,$MOV C,DQMOV R3,#23DJNZ R3,$RRC ADJNZ R2,RE1RET;-------------------写DS18B20的程序WRITE_1820:MOV R2,#8CLR CWR1:CLR DQMOV R3,#6DJNZ R3,$RRC AMOV DQ,CMOV R3,#23DJNZ R3,$SETB DQNOPDJNZ R2,WR1SETB DQRET;-------------------读DS18B20的程序,从DS18B20中读出两个字节的温度数据READ_18200:MOV R4,#2 ; 将温度高位和低位从DS18B20中读出MOV R1,#36H ; 低位存入36H(TEMPER_L),高位存入35H(TEMPER_H)RE00:MOV R2,#8RE01:CLR CSETB DQNOPNOPCLR DQNOPNOPNOPSETB DQMOV R3,#7DJNZ R3,$MOV C,DQMOV R3,#23DJNZ R3,$RRC ADJNZ R2,RE01MOV @R1,ADEC R1DJNZ R4,RE00RET;-------------------将从DS18B20中读出的温度数据进行转换TEMPER_COV:MOV A,#0F0HANL A,TEMPER_L ; 舍去温度低位中小数点后的四位温度数值SWAP AMOV TEMPER_NUM,AMOV A,TEMPER_LJNB ACC.3,TEMPER_COV1 ; 四舍五入去温度值INC TEMPER_NUMTEMPER_COV1:MOV A,TEMPER_HANL A,#07HSWAP AORL A,TEMPER_NUMMOV TEMPER_NUM,A ; 保存变换后的温度数据LCALL BIN_BCDRET;-------------------将16进制的温度数据转换成压缩BCD码BIN_BCD:MOV DPTR,#TEMP_TABMOV A,TEMPER_NUMMOVC A,@A+DPTRMOV TEMPER_NUM,ARETTEMP_TAB:DB 00H,01H,02H,03H,04H,05H,06H,07H DB 08H,09H,10H,11H,12H,13H,14H,15H DB 16H,17H,18H,19H,20H,21H,22H,23H DB 24H,25H,26H,27H,28H,29H,30H,31H DB 32H,33H,34H,35H,36H,37H,38H,39H DB 40H,41H,42H,43H,44H,45H,46H,47H DB 48H,49H,50H,51H,52H,53H,54H,55H DB 56H,57H,58H,59H,60H,61H,62H,63H DB 64H,65H,66H,67H,68H,69H,70H,71H DB 72H,73H,74H,75H,76H,77H,78H,79H DB 80H,81H,82H,83H,84H,85H,86H,87H DB 88H,89H,90H,91H,92H,93H,94H,95HDB 96H,97H,98H,99H;-------------------DS18B20初始化程序INIT_1820:SETB DQNOPCLR DQMOV R0,#80HTSR1:DJNZ R0,TSR1 ; 延时SETB DQMOV R0,#25H ;96US-25HTSR2:DJNZ R0,TSR2JNB DQ,TSR3LJMP TSR4 ; 延时TSR3:SETB FLAG1 ; 置标志位,表示DS1820存在LJMP TSR5TSR4:CLR FLAG1 ; 清标志位,表示DS1820不存在LJMP TSR7TSR5:MOV R0,#06BH ;200USTSR6:DJNZ R0,TSR6 ; 延时TSR7:SETB DQRET;------------------重新写DS18B20暂存存储器设定值RE_CONFIG:JB FLAG1,RE_CONFIG1 ; 若DS18B20存在,转RE_CONFIG1RETRE_CONFIG1:MOV A,#0CCH ; 发SKIP ROM命令LCALL WRITE_1820MOV A,#4EH ; 发写暂存存储器命令LCALL WRITE_1820MOV A,#00H ; TH(报警上限)中写入00HLCALL WRITE_1820MOV A,#00H ; TL(报警下限)中写入00HLCALL WRITE_1820MOV A,#7FH ; 选择12位温度分辨率LCALL WRITE_1820RET;------------------延时子程序DELAY:MOV R7,#00HMIN:DJNZ R7,YS500RETYS500:LCALL YS500USLJMP MINYS500US:MOV R6,#00HDJNZ R6,$RETDELAY1:MOV R7,#20HDJNZ R7,$RET;显示子程序display:ACALL LCD_INTMOV P1,#01H ;清屏ACALL ENABLEMOV P1,#81HLCALL ENABLEMOV P1,#'T'LCALL WRITERMOV P1,#'='LCALL WRITERCLR CLJMP DISP3RET;说明:使用前,必须先对液晶显示模块进行初始化。

DS18B20汇编程序(完整版)

DS18B20汇编程序(完整版)

DS18B20汇编程序;实验目的:熟悉DS18B20的使用;六位数码管显示温度结果,其中整数部分2位,小数部分4位;每次按下RB0键后进行一次温度转换。

;硬件要求:把DS18B20插在18B20插座上; 拨码开关S10第1位置ON,其他位置OFF; 拨码开关S5、S6全部置ON,其他拨码开关全部置OFF;*****************以下是暂存器的定义*****************************#INCLUDE<P16F877A.INC>#DEFINE DQ PORTA,0 ;18B20数据口__CONFIG_DEBUG_OFF&_CP_ALL&_WRT_HALF&_CPD_ON&_LVP_OFF&_BODEN_OFF&_PWRTE_ON&_WDT_OFF&_HS _OSCCBLOCK 20HDQ_DELAY1DQ_DELAY2TEMPTEMP1TEMP2 ;存放采样到的温度值TEMP3COUNTCOUNT1ENDCTMR0_VALUE EQU 0AH ;寄存器初值为6,预分频比1:4,中断一次时间为4*(256-6)=1000usDQ_DELAY_VALUE1 EQU 0FAHDQ_DELAY_VALUE2 EQU 4H;**********************以下是程序的开始************************ ORG 00HNOPGOTO MAIN ;入口地址ORG 04HRETFIE ;在中断入口出放置一条中断返回指令,防止干扰产生中断TABLEADDWF PCL,1RETLW 0C0H ;0的编码(公阳极数码管)RETLW 0F9H ;1的编码RETLW 0A4H ;2的编码RETLW 0B0H ;3的编码RETLW 99H ;4的编码RETLW 92H ;5的编码RETLW 082H ;6RETLW 0F8H ;7RETLW 080H ;8RETLW 090H ;9;***************************主程序******************************* MAINCLRF PORTACLRF PORTBBANKSEL TRISACLRF TRISA ;A口所有先设置为输出CLRF TRISDMOVLW 01HMOVWF TRISB ;B0口为输入,其他为输出MOVLW 06HMOVWF ADCON1 ;关闭所有A/D口MOVLW 01HMOVWF OPTION_REG ;分频比1:4,定时器,内部时钟源BCF STATUS,RP0CLRF TEMPCLRF TEMP1CLRF TEMP2 ;清零临时寄存器MOVLW 8HMOVWF COUNTMOVLW 38HMOVWF FSRCLRF INDFINCF FSR,1DECFSZ COUNT,1GOTO $-3;****************************循环处理部分************************;先启动18B20温度转换程序,在判断温度转换是否完成(需750us);未完成则调用显示子程序,直到完成温度转换;完成后读取温度值;送LCD显示LOOPBTFSC PORTB,0 ;判断温度转换按键是否按下GOTO LOOP1 ;否,转显示CALL DELAY ;消抖BTFSC PORTB,0 ;再次判断GOTO LOOP1CALL RESET_18B20 ;调用复位18B20子程序MOVLW 0CCHMOVWF TEMPCALL WRITE_18B20 ;SKIP ROM命令MOVLW 44HMOVWF TEMPCALL WRITE_18B20 ;温度转换命令CLRF STATUSCALL DELAY_750MS ;调用温度转换所需要的750MS延时NOPCALL RESET_18B20MOVLW 0CCHMOVWF TEMPCALL WRITE_18B20 ;SKIP ROM命令MOVLW 0BEHMOVWF TEMPCALL WRITE_18B20 ;读温度命令CALL READ_18B20 ;调用读温度低字节MOVFW TEMPMOVWF TEMP1 ;保存到TEMP1CALL READ_18B20 ;调用读温度高字节MOVFW TEMPMOVWF TEMP2 ;保存到TMEP2CALL RESET_18B20LOOP1CALL TEMP_CHANGE ;调用温度转换程序CALL DISPLAY ;调用LCD显示程序GOTO LOOP ;循环工作;*********************复位DS18B20子程序************************** RESET_18B20;根据DATASHEET介绍,写数据时应遵照如下规定:;主控制器把总线拉低至少480us,;18B20等待15-60us后,把总线拉低做为返回给控制器的应答信号BANKSEL TRISABCF TRISA,0BCF STATUS,RP0BCF DQMOVLW 0A0HMOVWF COUNT ;160USDECFSZ COUNT,1GOTO $-1 ;拉低480usBSF DQ ;释放总线MOVLW 14HMOVWF COUNTDECFSZ COUNT,1GOTO $-1 ;等待60usBANKSEL TRISABSF TRISA,0 ;DQ设置为输入BCF STATUS,RP0BTFSC DQ ;数据线是否为低GOTO RESET_18B20 ;否则继续复位MOVLW 4HMOVWF COUNTDECFSZ COUNT,1 ;延时一段时间后再次判断GOTO $-1BTFSC DQGOTO RESET_18B20MOVLW 4BHMOVWF COUNTDECFSZ COUNT,1GOTO $-1BANKSEL TRISABCF TRISA,0 ;DQ设置为输出BCF STATUS,RP0RETURN;*********************写DS18B20子程序**************************** WRITE_18B20;根据DATASHEET介绍,写数据时应遵照如下规定:;写数据0时,主控制器把总线拉低至少60us;写数据1时,主控制器把总线拉低,但必须在15us内释放MOVLW 8HMOVWF COUNT ;8位数据BANKSEL TRISABCF TRISA,0BCF STATUS,RP0BCF STATUS,CWRITE_18B20_1BSF DQ ;先保持DQ为高MOVLW 5HMOVWF COUNT1BCF DQ ;拉低DQ15usDECFSZ COUNT1,1GOTO $-1RRF TEMP,1BTFSS STATUS,C ;判断写的数据为0还是1GOTO WRITE_0BSF DQ ;为1,立即拉高数据线GOTO WRITE_ENDWRITE_0BCF DQ ;继续保持数据线为低WRITE_ENDMOVLW 0FHMOVWF COUNT1 ;保持45msDECFSZ COUNT1,1GOTO $-1BSF DQ ;释放总线DECFSZ COUNT,1 ;是否写完8位数据GOTO WRITE_18B20_1RETURN;**********************读DS18B20子程序**************************** READ_18B20;根据DATASHEET介绍,读数据时应遵照如下规定:;读数据0时,主控制器把总线拉低后,18B20再把总线拉低60us;读数据1时,主控制器把总线拉低后,保持总线状态不变;主控制器在数据线拉低后15us内读区数据线上的状态。

基于51单片机——Ds18B20温度采集,LCD显示汇编程序(附带proteus仿真图).docx

基于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。

(整理)温度传感器DS18b20介绍和汇编度温度程序

(整理)温度传感器DS18b20介绍和汇编度温度程序

基于proteus的51单片机仿真实例六十七、单总线温度传感器DS18B20读写实例标签: proteus温度传感器单片机单总线实例2010-02-20 01:031、I2C总线器件与单片机之间的通信需要两根线,而单总线器件与单片机间的数据通信只要一根线。

单总线适用于单主机系统,能够控制一个或多个从机设备。

主机通常是单片机,从机可以是单总线器件,他们之间通过一条信号线进行数据交换,单总线上同样允许挂接多个单总线器件,因此,每隔单总线器件必须有各自固定的地址,但总线器件通常需要接一个4.7k左右的上拉电阻,这样,当总线空闲时,状态为高电平。

2、单总线器件的数据操作过程1)初始化单总线上的所有处理均从初始化开始,单片机先发送一个复位脉冲,当单总线其间接收到复位脉冲后,先单片机发出应答信号,以便通知单片机:该器件已经准备好等待下一步操作2)识别单总线器件总线上允许挂接多个但总线器件,为便于单片机识别,每个单总线器件在出厂前都分配好了64为序列号以作为地址序列码。

所以单片机能够根据该序列号来识别和判断对那一个单总线器件进行操作3)数据交换单片机与单总线器件之间的数据交换必须遵循严格的通信协议。

单总线协议定义了复位信号,应答信号,写/读0,写/读1的集中信号类型,所有的单总线命令都是由这些基本的信号类型组成的,除了应答信号外,其余信号都由单片机发出,并且发送的所有命令和数据都是低位在前,高位在后。

3、DS18B20的工作时序1)初始化单片机将数据线拉低480-960us后释放,等待15-60us,单总线器件即可输出一个持续时间为60-240us的低电平(应答信号),单片机受到此应答后即可进行后续操作2)写时序当主机将数据线的电平从高拉到低时,形成写时序,有写0和写1两种时序。

写时序开始后,DS18B20在15-60us期间从数据线上采样,如果采样到低电平,则向DS18B20写0,否则写1,两个独立的时序之间至少需要1us的回复时间按(拉高总线电平)3)读时序当主机从DS18B20读取数据时,产生读时序,此时,主机将数据线的电平从高拉到低使读时序被初始化。

DS18B20汇编程序-STC12C5A60S2(12T)

DS18B20汇编程序-STC12C5A60S2(12T)

;**************************************;温度传感器DS18B20测试程序;主芯片 : STC90C52RC (12T);工作频率: 12.000MHz;**************************************DQ BIT P3.3 ;DS18B20的数据口位P3.3TPH DATA 20H ;存放温度值的高字节TPL DATA 21H ;存放温度值的低字节ORG 0JMP ResetORG 100HReset:CALL DS18B20_Reset ;设备复位MOV A,#0CCH ;跳过ROM命令CALL DS18B20_WriteByte ;送出命令MOV A,#044H ;开始转换CALL DS18B20_WriteByte ;送出命令JNB DQ,$ ;等待转换完成 CALL DS18B20_Reset ;设备复位MOV A,#0CCH ;跳过ROM命令CALL DS18B20_WriteByte ;送出命令第 1 页MOV A,#0BEH ;读暂存存储器 CALL DS18B20_WriteByte ;送出命令CALL DS18B20_ReadByte ;读温度低字节 MOV TPL,A ;存储数据CALL DS18B20_ReadByte ;读温度高字节 MOV TPH,A ;存储数据JMP $;************************************** ;延时X*10微秒;不同的工作环境,需要调整此函数;入口参数:R7;出口参数:无;************************************** DelayX0us: ;2 当改用1T的MCU时,请调整此延时函数NOP ;1NOP ;1NOP ;1NOP ;1NOP ;1NOP ;1NOP ;1NOP ;1DJNZ R7,DelayX0us ;2RET ;2;**************************************第 2 页;复位DS18B20,并检测设备是否存在;入口参数:无;出口参数:无;**************************************DS18B20_Reset:CLR DQ ;送出低电平复位信号MOV R7,#48 ;延时至少480us CALL DelayX0usSETB DQ ;释放数据线MOV R7,#6 ;等待60usCALL DelayX0usMOV C,DQ ;检测存在脉冲 MOV R7,#42 ;等待设备释放数据线CALL DelayX0usJC DS18B20_Reset ;如果设备不存在,则继续等待RET;**************************************;从DS18B20读1字节数据;入口参数:无;出口参数:ACC;**************************************DS18B20_ReadByte:CLR APUSH 0MOV 0,#8 ;8位计数器第 3 页ReadNext:CLR DQ ;开始时间片NOPNOPSETB DQ ;准备接收NOPNOPMOV C,DQ ;读取数据RRC AMOV R7,#6 ;等待时间片结束 CALL DelayX0usDJNZ 0,ReadNextPOP 0RET;**************************************;向DS18B20写1字节数据;入口参数:ACC;出口参数:无;**************************************DS18B20_WriteByte:PUSH 0MOV 0,#8 ;8位计数器WriteNext:CLR DQ ;开始时间片NOPNOPRRC A ;输出数据MOV DQ,C第 4 页MOV R7,#6 ;等待时间片结束 CALL DelayX0usSETB DQ ;准备送出下一位数据DJNZ 0,WriteNextPOP 0RETEND第 5 页。

单片机DS18B20温度计(有程序)

单片机DS18B20温度计(有程序)

;单片机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;}}。

DS18B20汇编程序(完整版)

DS18B20汇编程序(完整版)

DS18B20汇编程序(完整版)DS18B20汇编程序;实验目的:熟悉DS18B20的使用;六位数码管显示温度结果,其中整数部分2位,小数部分4位;每次按下RB0键后进行一次温度转换。

;硬件要求:把DS18B20插在18B20插座上; 拨码开关S10第1位置ON,其他位置OFF; 拨码开关S5、S6全部置ON,其他拨码开关全部置OFF;*****************以下是暂存器的定义*****************************#INCLUDE#DEFINE DQ PORTA,0 ;18B20数据口__CONFIG_DEBUG_OFF&_CP_ALL&_WRT_HALF&_CPD_ON&_LVP_OFF &_BODEN_OFF&_PWRTE_ON&_WDT_OFF&_HS _OSC CBLOCK 20HDQ_DELAY1DQ_DELAY2TEMPTEMP1TEMP2 ;存放采样到的温度值TEMP3COUNTCOUNT1ENDCTMR0_VALUE EQU 0AH ;寄存器初值为6,预分频比1:4,中断一次时间为4*(256-6)=1000usDQ_DELAY_VALUE1 EQU 0FAHDQ_DELAY_VALUE2 EQU 4H;**********************以下是程序的开始************************ ORG 00HNOPGOTO MAIN ;入口地址ORG 04HRETFIE ;在中断入口出放置一条中断返回指令,防止干扰产生中断TABLEADDWF PCL,1RETLW 0C0H ;0的编码(公阳极数码管)RETLW 0F9H ;1的编码RETLW 0A4H ;2的编码RETLW 0B0H ;3的编码RETLW 99H ;4的编码RETLW 92H ;5的编码RETLW 082H ;6RETLW 0F8H ;7RETLW 080H ;8RETLW 090H ;9;***************************主程序******************************* MAINCLRF PORTACLRF PORTBBANKSEL TRISACLRF TRISA ;A口所有先设置为输出CLRF TRISDMOVLW 01HMOVWF TRISB ;B0口为输入,其他为输出MOVLW 06HMOVWF ADCON1 ;关闭所有A/D口MOVLW 01HMOVWF OPTION_REG ;分频比1:4,定时器,内部时钟源BCF STATUS,RP0CLRF TEMPCLRF TEMP1CLRF TEMP2 ;清零临时寄存器MOVLW 8HMOVWF COUNTMOVLW 38HMOVWF FSRCLRF INDFINCF FSR,1DECFSZ COUNT,1GOTO $-3;****************************循环处理部分************************;先启动18B20温度转换程序,在判断温度转换是否完成(需750us);未完成则调用显示子程序,直到完成温度转换;完成后读取温度值;送LCD显示LOOPBTFSC PORTB,0 ;判断温度转换按键是否按下GOTO LOOP1 ;否,转显示CALL DELAY ;消抖BTFSC PORTB,0 ;再次判断GOTO LOOP1CALL RESET_18B20 ;调用复位18B20子程序MOVLW 0CCHMOVWF TEMPCALL WRITE_18B20 ;SKIP ROM命令MOVLW 44HMOVWF TEMPCALL WRITE_18B20 ;温度转换命令CLRF STATUSCALL DELAY_750MS ;调用温度转换所需要的750MS延时NOPCALL RESET_18B20MOVLW 0CCHMOVWF TEMPCALL WRITE_18B20 ;SKIP ROM命令MOVLW 0BEHMOVWF TEMPCALL WRITE_18B20 ;读温度命令CALL READ_18B20 ;调用读温度低字节MOVFW TEMPMOVWF TEMP1 ;保存到TEMP1CALL READ_18B20 ;调用读温度高字节MOVFW TEMPMOVWF TEMP2 ;保存到TMEP2CALL RESET_18B20LOOP1CALL TEMP_CHANGE ;调用温度转换程序CALL DISPLAY ;调用LCD显示程序GOTO LOOP ;循环工作;*********************复位DS18B20子程序************************** RESET_18B20;根据DATASHEET介绍,写数据时应遵照如下规定:;主控制器把总线拉低至少480us,;18B20等待15-60us后,把总线拉低做为返回给控制器的应答信号BANKSEL TRISABCF TRISA,0BCF STATUS,RP0BCF DQMOVLW 0A0HMOVWF COUNT ;160USDECFSZ COUNT,1GOTO $-1 ;拉低480usBSF DQ ;释放总线MOVLW 14HMOVWF COUNTDECFSZ COUNT,1GOTO $-1 ;等待60usBANKSEL TRISABSF TRISA,0 ;DQ设置为输入BCF STATUS,RP0BTFSC DQ ;数据线是否为低GOTO RESET_18B20 ;否则继续复位MOVLW 4HMOVWF COUNTDECFSZ COUNT,1 ;延时一段时间后再次判断GOTO $-1BTFSC DQGOTO RESET_18B20MOVLW 4BHMOVWF COUNTDECFSZ COUNT,1GOTO $-1BANKSEL TRISABCF TRISA,0 ;DQ设置为输出BCF STATUS,RP0RETURN;*********************写DS18B20子程序**************************** WRITE_18B20;根据DATASHEET介绍,写数据时应遵照如下规定:;写数据0时,主控制器把总线拉低至少60us;写数据1时,主控制器把总线拉低,但必须在15us内释放MOVLW 8HMOVWF COUNT ;8位数据BANKSEL TRISABCF TRISA,0BCF STATUS,RP0BCF STATUS,CWRITE_18B20_1BSF DQ ;先保持DQ为高MOVLW 5HMOVWF COUNT1BCF DQ ;拉低DQ15usDECFSZ COUNT1,1GOTO $-1RRF TEMP,1BTFSS STATUS,C ;判断写的数据为0还是1GOTO WRITE_0BSF DQ ;为1,立即拉高数据线GOTO WRITE_ENDWRITE_0BCF DQ ;继续保持数据线为低WRITE_ENDMOVLW 0FHMOVWF COUNT1 ;保持45msDECFSZ COUNT1,1GOTO $-1BSF DQ ;释放总线DECFSZ COUNT,1 ;是否写完8位数据GOTO WRITE_18B20_1RETURN;**********************读DS18B20子程序**************************** READ_18B20;根据DATASHEET介绍,读数据时应遵照如下规定:;读数据0时,主控制器把总线拉低后,18B20再把总线拉低60us ;读数据1时,主控制器把总线拉低后,保持总线状态不变;主控制器在数据线拉低后15us内读区数据线上的状态。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

FLAG BIT 00H;DS18B20存在标志位
DQ BIT P3.7
WD_L EQU 28H
WD_H EQU 29H
************程序起始********************
ORG 0000H
AJMP START
ORG 0030H
**************主程序开始************
START:MOV SP,#70H
LCALL INIT_18B20
LCALL RE_CONFIG
LCALL GET_WD
AJMP CHANGE
**********DS18B20复位程序*****************
INIT_18B20:SETB DQ
NOP
CLR DQ
MOV R0,#0FBH
DJNZ R0,$;延时
SETB DQ
MOV R0,#25H
DJNZ R0,$
JNB DQ,TSR1
AJMP TSR2
TSR1:SETB FLAG;置标志位,表明DS18B20存在
AJMP TSR3
TSR2:CLR FLAG;清标志位,表明DS18B20不存在
AJMP TSR4
TSR3:MOV R0,#6BH
DJNZ R0,$
TSR4:SETB DQ;拉高总线
RET
********************设定DS18B20暂存器设定值************** RE_CONFIG:JB FLAG,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_WD:SETB DQ
LCALL INIT_18B20
JB FLAG,TSS1
RET;若不存在则返回
TSS1:MOV A,#0CCH;跳过ROM
LCALL WRITE_18B20
MOV A,#44H;发出温度转换命令
LCALL WRITE_18B20
LCALL DISPLAY;延时
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,#28H;低位存在28H,高位存在29H RE00:MOV R2,#8
RE01:CLR C
SETB DQ
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
INC R1
DJNZ R4,RE00
RET
************读出的温度进行数据转换************** CHANGE:MOV A,28H
MOV C,29H.0;将29H中的最低位移入C
RRC A
MOV C,29H.1
RRC A
MOV C,29H.2
RRC A
MOV C,29H.3
RRC A
MOV 28H,A
LCALL DISPLAY;调用数码管显示子程序
LJMP MAIN
*******************DISPLAY******
DISPLAY:MOV A,28H;将28H中的十六进制数转换成10进制
MOV B,#10;10进制/10=10进制
DIV AB
MOV SHI,A;十位在SHI
MOV GW,B;个位在GW
MOV DPTR,#TAB ;指定查表启始地址 MOV A,GW ;取个位数
MOVC A,@A+DPTR ;查个位数的7段代码
MOV 34H,A;送出个位的7段代码
MOV A,SHI;取十位数
MOVC A,@A+DPTR ;查十位数的7段代码
MOV 35H,A;送出十位的7段代码
RET。

相关文档
最新文档