這是用1602來顯示的,程序是修改前面幾個實驗的,當溫度<40度時電風扇不轉,當>=40度時電風扇轉動,為參加電子比賽做的單片機系統實驗。程序為匯編語言(ASM),帶詳細注釋,值得新手朋友參考! 全部程序: ORG 0000H ;單片機內存分配申明! TEMPER_L EQU 29H;用于保存讀出溫度的低8位 TEMPER_H EQU 28H;用于保存讀出溫度的高8位 FLAG1 EQU 38H;是否檢測到DS18B20標志位 a_bit equ 20h ;數碼管個位數存放內存位置 b_bit equ 21h ;數碼管十位數存放內存位置 RS EQU P3.7;確定具體硬件的連接方式 RW EQU P3.6 ;確定具體硬件的連接方式 E EQU P3.5 ;確定具體硬件的連接方式 ;主程序 MAIN: LCALL GET_TEMPER;調用讀溫度子程序 MOV A,29H MOV C,40H;將28H中的最低位移入C RRC A MOV C,41H RRC A MOV C,42H RRC A MOV C,43H RRC A MOV 29H,A clr c setb p3.0;zhelikais從這里開始是我填加的溫度控制 CJNE A,#28H,FIT SETB P3.0 AJMP DISLED FIT:CPL C MOV P3.0,C;jiesu到這里結束 DISLED:LCALL DISPLAY;調用數碼管顯示子程序 AJMP MAIN ;DS18B20復位初始化子程序 INIT_1820:SETB P2.2 NOP CLR P2.2;主機發出延時537微秒的復位低脈沖 MOV R1,#3 TSR1:MOV R0,#107 DJNZ R0,$ DJNZ R1,TSR1 SETB P2.2;然后拉高數據線 NOP NOP NOP MOV R0,#25H TSR2:JNB P2.2,TSR3;等待DS18B20回應 DJNZ R0,TSR2 LJMP TSR4 ; 延時 TSR3:SETB FLAG1 ; 置標志位,表示DS1820存在 CLR P1.7;檢查到DS18B20就點亮P1.7LED,與傳感器通信成功 LJMP TSR5 TSR4:CLR FLAG1 ; 清標志位,表示DS1820不存在 CLR P1.1;未檢查到DS18B20就點亮P1.1LED,與傳感器通信失敗 LJMP TSR7 TSR5:MOV R0,#117 TSR6:DJNZ R0,TSR6 ; 時序要求延時一段時間 TSR7:SETB P2.2 RET ;讀出轉換后的溫度值的子程序 GET_TEMPER:SETB P2.2 LCALL INIT_1820;先復位DS18B20 JB FLAG1,TSS2 CLR P1.2 RET ; 判斷DS1820是否存在?若DS18B20不存在則返回 TSS2:CLR P1.3;DS18B20已經被檢測到! MOV A,#0CCH ; 跳過ROM匹配 LCALL WRITE_1820 MOV A,#44H ; 發出溫度轉換命令 LCALL WRITE_1820 LCALL DISPLAY;這里通過調用顯示子程序實現延時一段時間,等待AD轉換結束,12位的話750微秒 LCALL INIT_1820;準備讀溫度前先復位 MOV A,#0CCH ; 跳過ROM匹配 LCALL WRITE_1820 MOV A,#0BEH ; 發出讀溫度命令 LCALL WRITE_1820 LCALL READ_18200; 將讀出的溫度數據保存到35H/36H CLR P1.4 RET ;寫DS18B20的子程序(有具體的時序要求) WRITE_1820:MOV R2,#8;一共8位數據 CLR C WR1:CLR P2.2 MOV R3,#6 DJNZ R3,$ RRC A MOV P2.2,C MOV R3,#23 DJNZ R3,$ SETB P2.2 NOP DJNZ R2,WR1 SETB P2.2 RET ; 讀DS18B20的程序,從DS18B20中讀出兩個字節的溫度數據 READ_18200:MOV R4,#2 ; 將溫度高位和低位從DS18B20中讀出 MOV R1,#29H ; 低位存入29H(TEMPER_L),高位存入28H(TEMPER_H) RE00:MOV R2,#8;數據一共有8位 RE01:CLR C SETB P2.2 NOP NOP CLR P2.2 NOP NOP NOP SETB P2.2 MOV R3,#9 RE10:DJNZ R3,RE10 MOV C,P2.2 MOV R3,#23 RE20:DJNZ R3,RE20 RRC A DJNZ R2,RE01 MOV @R1,A DEC R1 DJNZ R4,RE00 RET ;顯示子程序 display: acall DL100MS acall DL100MS mov a,29H;將29H中的十六進制數轉換成10進制 mov b,#10 ;10進制/10=10進制 div ab mov b_bit,a ;十位在a mov a_bit,b ;個位在b add a,#00110000b mov b_bit,a mov a,b add a,#00110000b mov a_bit,a MOV P1,#00000001B; ;清屏并光標復位 ACALL ENABLE;調用寫入命令子程序 MOV P1,#00111000B ;;設置顯示模式:8位2行5x7點陣 ACALL ENABLE ;調用寫入命令子程序 MOV P1,#00001111B ;;顯示器開、光標開、光標允許閃爍 ACALL ENABLE ;調用寫入命令子程序 MOV P1,#00000110B ;;文字不動,光標自動右移 ACALL ENABLE ;調用寫入命令子程序 MOV P1,#80H ;;寫入顯示起始地址(第二行第一個位置) ACALL ENABLE ;調用寫入命令子程序 MOV P1,b_bit ;;A十位送出去 SETB RS; ;RS=1 CLR RW; ;RW=0 ;準備寫入數據 CLR E; ;E=0 ;執行顯示命令 ACALL DELAY ;判斷液晶模塊是否忙? SETB E ;;E=1 ;顯示完成,程序停車 MOV P1,#00000110B ;;文字不動,光標自動右移 ACALL ENABLE ;調用寫入命令子程序 MOV P1,#81H ;;寫入顯示起始地址(第二行第2個位置) ACALL ENABLE ;調用寫入命令子程序 MOV P1,a_bit;;字母A的代碼 SETB RS; ;RS=1 CLR RW; ;RW=0 ;準備寫入數據 CLR E; ;E=0 ;執行顯示命令 ACALL DELAY ;判斷液晶模塊是否忙? SETB E ;;E=1 ;顯示完成,程序停車 ret ENABLE: CLR RS; ;寫入控制命令的子程序 CLR RW CLR E ACALL DELAY SETB E RET DELAY: MOV P1,#0FFH ;;判斷液晶顯示器是否忙的子程序 CLR RS SETB RW CLR E NOP SETB E JB P1.7,DELAY; ;如果P1.7為高電平表示忙就循環等待 RET DL100MS: MOV R7,#02H DL1: MOV R6,#0C8H DL2: MOV R5,#0FAH DJNZ R5,$ DJNZ R6,DL2 DJNZ R7,DL1 RET END