• 学而时习之专栏
  • 温故而知新专栏



  • 液晶显示温度控制程序



    对温度进行实时监测与控制。由温度传感器DS18B20对温度进行采样和转换成数字信号送入单片机,并与设定的报警温度上、下限值进行比较,信息通过LCD显示出来。如实时温度超过设定的上、下限值,一方面由LCD显示信息,并发出警报声;另一方面自动控制继电器(Relay)开接通或断开,从而控制加热源的开与断,达到对温度进行实时控制的目的。


    在单片机中端口接有LCD模块,用来显示温度的,P2.5是温度传感器DS18B20的信号线引脚DQ连接,用来传递控制指令和接收温度信息,P2.1至P2.4分别接有K1至K4,4个按钮开关,用来温度值的输入和调整


    电路图如下:
    2402电路图
    程序如下:

    01 ; ―――――――――――――――――――――――――――――――

    02 ; 温度值存放单元


    04 TEMPL EQU 25H ;低温度值存放单元

    05 TEMPH EQU 26H ;高温度值存放单元

    06 TEMP_TH EQU 27H ;高温报警值存放单元

    07 TEMP_TL EQU 28H ;低温报警值存放单元

    08 TEMPHC EQU 29H ;存十位数 BCD码

    09 TEMPLC EQU 2AH ;存个位数 BCD码

    10 ;―――――――――――――

    11 按键输入引脚定义

    12 K1 EQU P2.1

    13 K2 EQU P2.2

    14 K3 EQU P2.3

    15 K4 EQU P2.4

    16 ;―――――――――――――

    17 SPK EQU P3.4 ;蜂鸣器引脚

    18 RELAY EQU P2.0 ;继电器引脚

    19 X EQU 2FH ;LCD 地址变量

    20 ;―――――――――――――

    21 ;LCD控制引脚

    22 RS EQU P3.5

    23 RW EQU P3.6

    24 E EQU P3.7

    25 ;―――――――――――――

    26 FLAG EQU 20H.0 ;DS18B20是否存在标记

    27 KEY_UD EQU 20H.1 ;设定 KEY 的UP与DOWN 标记

    28 DQ EQU P2.5

    29

    30 ;============= 主程序 ==============

    31

    32 MAIN:

    33 ACALL SET_LCD ;LCD初始化设置子程序

    34 ACALL WR_THL ;将报警上下线写入暂存寄存器子程序

    35 TOOP: ACALL RESET_1820 ;调用18B20复位子程序

    36 JNB FLAG,TOOP1 ;DS1820不存在转移TOOP1处

    37 ACALL MEU_OK ;调用显示"OK"信息子程序

    38 ACALL RE_THL ;把EEROM里温度报警值拷贝回暂存器

    39 ACALL TEMP_BJ ;显示温度标记"℃"

    40 JMP TOOP2

    41 TOOP1: ACALL MEU_ERROR ;显示"ERROR"信息

    42 ACALL TEMP_BJ ;显示温度标记

    43 JMP $ ;等待

    44 ;――――――――――――――

    45 TOOP2:

    46 ACALL RE_TEMP ;调用读取温度数据子程序

    47 ACALL SET_DATA ;调用处理显示温度数据子程序

    48 ACALL TEMP_COMP ;实际温度值与标记温度值比较子程序

    49 ACALL P_KEY ;调用按键扫描子程序

    50 SJMP TOOP2 ;循环

    51

    52 ;--------―― 读取温度数据子程序 --------――

    53 RE_TEMP:

    54 ACALL RESET_1820 ;18B20复位子程序

    55 JNB FLAG,TOOP1 ;DS1820不存在

    56 MOV A,#0CCH ;跳过ROM匹配

    57 ACALL WRITE_1820 ;写入子程序

    58 MOV A,#44H ;发出温度转换命令

    59 ACALL WRITE_1820 ;调写入子程序

    60 ACALL RESET_1820 ;调复位子程序

    61 MOV A,#0CCH ;跳过ROM匹配

    62 ACALL WRITE_1820 ;写入子程序

    63 MOV A,#0BEH ;发出读温度命令

    64 ACALL WRITE_1820 ;写入子程序

    65 ACALL READ_1820 ;调用读取子程序

    66 RET

    67

    68 ;-------- 温度数据处理显示子程序----------

    69 SET_DATA:

    70 ACALL CONV_TEMP ;处理温度 BCD 码子程序

    71 ACALL DISP_BCD ;显示区 BCD 码温度值刷新子程序

    72 ACALL CONV ;LCD显示子程序

    73 RET

    74

    75;----------- 按键键扫描子程序 ----------

    76 P_KEY: ;按键K1处理

    77 JB K1, PK1 ;K1键未按,转到PK1处

    78 ACALL SPK_BZ ;K1键按下,一声鸣响

    79 JNB K1,$ ;等按键放开

    80 MOV DPTR,#M_ALAX1 ;存M_ALAX1表

    81 MOV A,#1

    82 ACALL LCD_PRINT ;显示字符

    83 ACALL LOOK_ALARM ;显示信息区子程序

    84 JB K3, $ ;等待K3按下

    85 ACALL SPK_BZ ;一声鸣响

    86 JMP PK2 ;转到标号 PK2处

    87 PK1: ; 按键K2处理

    88 JB K2, PK3 ;K2键未按,转到PK3处

    89 ACALL SPK_BZ ;K2键按下,一声鸣响

    90 JNB K2,$ ;等按键放开

    91 MOV DPTR, #TA1 ;存#TA1表

    92 MOV A,#1

    93 ACALL LCD_PRINT ;显示字符

    94 ACALL SET_ALARM ;设定报警值 TH、TL

    95 ACALL WR_THL ;将设定的TH,TL值写入DS18B20内

    96 ACALL WRITE_E2 ;调用报警值拷贝EEROM子程序

    97 PK2:

    98 ACALL MEU_OK ;显示"OK"信息子程序

    99 ACALL TEMP_BJ ;显示温度标记子程序

    100 PK3:

    101 RET

    102 ;―――――――――――――

    103 TA1: ;菜单表

    104 DB "RESET ALERT CODE"

    105 ;―――――――――――――

    106

    107 ;--------- 设定报警值 TH、TL子程序 --------

    108 SET_ALARM:

    109 ACALL LOOK_ALARM ;调用显示信息区子程序

    110 A0: JB K1,A2 ;按下K1(查看键),程序向下运行

    111 ACALL SPK_BZ ;蜂鸣器响一声

    112 JNB K1,$ ;等放开

    113 CPL 20H.1 ;UP/DOWN 标记反向

    114 A2: JB 20H.1,A3 ;20H.1=1,UP,转移到A3。

    115 JMP A8 ;20H.1=0,DOWN,转移到A8

    116 ;―――――――――――――

    117 ; TH值调整(增加)

    118 A3: JB K2, A5 ;按下K2(设定键),程序向下运行

    119 ACALL SPK_BZ ;蜂鸣器响一声

    120 INC TEMP_TH ;TH值调整(增加)

    121 MOV A,TEMP_TH ;TH值送入A

    122 CJNE A,#120,A4 ;TH值增到120,程序向下运行

    123 MOV TEMP_TH,#0 ;TH值清0

    124 A4: ACALL LOOK_ALARM ;调用显示信息区子程序

    125 MOV R5, #10

    126 ACALL DELAY ;调用延时程序

    127 JMP A3 ;循环

    128 ;―――――――――――――

    129 ;TL值调整(增加)

    130 A5: JB K3,A7 ;按下K3(TL值设定键)程序向下运行

    131 ACALL SPK_BZ ;蜂鸣器响一声

    132 INC TEMP_TL ;TL值增加1

    133 MOV A, TEMP_TL ;TL值送入A

    134 CJNE A,#99,A6 ;比较,若A=99,程序向下运行

    135 MOV TEMP_TL,#00H ;TL值清0

    136 A6: ACALL LOOK_ALARM ;调用显示信息区子程序

    137 MOV R5, #10

    138 ACALL DELAY ;调用延时程序

    139 JMP A5 ;程序转移到A5,循环

    140 ;―――――――――――――

    141 ;确定调整 OK

    142 A7: JB K4, A0 ;按下K4(调整确定键),程序向下运行

    143 ACALL SPK_BZ ;蜂鸣器响一声

    144 JNB K4, $ ;等放开

    145 RET ;程序返回

    146 ;―――――――――――――

    147 ;TH值调整 (减少)

    148 A8: JB K2, A10 ;按下K2(设定键),程序向下运行

    149 ACALL SPK_BZ ;蜂鸣器响一声

    150 DEC TEMP_TH ;TH值减1

    151 MOV A,TEMP_TH ;TH值送入A

    152 CJNE A,#0FFH,A9 ;比较,若A=0FF,程序向下运行

    153 JMP A12 ;转移到A12

    154 A9: ACALL LOOK_ALARM ;调用显示信息区子程序

    155 MOV R5, #10

    156 ACALL DELAY ;调用延时子程序

    157 JMP A0 ;转移到A12

    158 ;――――――――――――――

    159 ;TL值调整(减少)

    160 A10: JB K3, A13 ;按K3(TL值设定键),程序向下运行

    161 ACALL SPK_BZ ;蜂鸣器响一声

    162 DEC TEMP_TL ;TL值减1

    163 MOV A,TEMP_TL ;TH值送入A

    164 CJNE A,#0FFH,A11 ;比较,若A=0FF,程序向下运行

    165 JMP A12 ;转移到A12

    166 A11: ACALL LOOK_ALARM ;调用显示信息区子程序

    167 MOV R5, #10

    168 ACALL DELAY ;调用延时子程序

    169 JMP A0 ;转移到A0

    170 A12: CPL 20H.1 ;UP/DOWN 标记反向

    171 JMP A3 ;转移到A3 ,TH值调整(增加)

    172 A13: JMP A7 ;转移到A7 ,确定调整 OK

    173 RET ;子程序返回

    174

    175 ;---------- 显示信息区子程序-----------

    176 LOOK_ALARM:

    177 MOV DPTR,#M_ALAX2 ;存表

    178 MOV A,#2 ;显示在第二行

    179 ACALL LCD_PRINT ;调用显示字符子程序

    180 MOV A,#0C6H ;显示起始地址为第二行第7位

    181 ACALL TEMP_BJ1 ;调用显示温度标记子程序

    182 MOV A,TEMP_TH ;加载TH数据

    183 MOV X,#3 ;设置位置

    184 ACALL SHOW_LINE2H ;显示数据

    185 ;―――――――――――――

    186 MOV A,#0CEH ;设定显示起始地址为第二行第15位

    187 ACALL TEMP_BJ1 ;调用显示温度标记子程序

    188 MOV A,TEMP_TL ;加载TL数据

    189 MOV X,#12 ;设置位置

    190 ACALL SHOW_LINE2L ;显示数据

    191 RET

    192 ;――――――――――――――

    193 M_ALAX1:

    194 DB " LOOK ALERT CODE",0

    195 M_ALAX2:

    196 DB "TH: TL: ",0

    197 ;――――――――――――――

    198 ;――――――显示温度标记子程序――――――

    199 TEMP_BJ1:

    200 ACALL WR_COMM ;调用写指令子程序

    201 MOV DPTR,#BJ2 ;存代码表

    202 MOV R1,#0 ;使指针指到表中第一个码

    203 MOV R0,#2 ;取码次数

    205 B0: MOV A,R1 ;A为0

    206 MOVC A,@A+DPTR ;读取码

    207 ACALL WR_DATA ;调用写数据子程序

    208 INC R1 ;R1值加1

    209 DJNZ R0,B0 ;判断是否将代码读取完?

    210 RET

    211 ;―――――――――――――

    212 BJ2: ;代码表

    213 DB 00H,"C"

    214 ;―――――――――――――

    215

    216 ;―――――在 LCD 的第二行显示高温数字――――

    217 SHOW_LINE2H:

    218 MOV B,#100 ;设置被除数,B为百位数

    219 DIV AB ;除法运算,结果A存商数,B存余数

    220 ADD A,#30H ;低半字节加30得到ASCII码(转换为字符)

    221 PUSH B ;B放入堆栈暂存起来

    222 MOV B,X ;设置LCD显示的位置

    223 ACALL LCDP2 ;由LCD显示出来

    224 ;―――――――――――――

    225 POP B ;B由堆栈取出来

    226 MOV A,#0AH ;A赋值10

    227 XCH A,B ;A、B数据互换,B为十位数

    228 DIV AB ;除法运算,结果A存商数,B存余数

    229 ADD A,#30H ;转换为字符

    230 INC X ;LCD显示位位置加1

    231 PUSH B ;B放入堆栈暂存起来

    232 MOV B,X ;设置LCD显示的位置

    233 ACALL LCDP2 ;由LCD显示出来

    234 ;―――――――――――――

    235 POP B ;B由堆栈取出来

    236 INC X ;LCD显示位位置加1

    237 MOV A,B ;B为个位数

    238 MOV B,X ;设置LCD显示的位置

    239 ADD A,#30H ;转换为字符

    240 ACALL LCDP2 ;由LCD显示出来

    241 RET

    242

    243 ;―――――在 LCD 的第二行显示低温数字―――――

    244 SHOW_LINE2L:

    245 MOV B,#100 ;设置被除数

    246 DIV AB ;除法运算,结果A存商数,B存余数

    247 MOV A,#0AH ;A赋值10

    248 XCH A,B ;A、B数据互换,B为十位数

    249 DIV AB ;除法运算,结果A存商数,B存余数

    250 ADD A,#30H ;转换为字符

    251 PUSH B ;B放入堆栈暂存起来

    252 MOV B,X ;设置LCD显示的位置

    253 CALL LCDP2 ;由LCD显示出来

    254 ;――――――――――――――

    255 POP B ;B由堆栈取出来

    256 INC X ;LCD显示位位置加1

    257 MOV A,B ;B为个位数

    258 MOV B,X ;设置LCD显示的位置

    259 ADD A,#30H ;转换为字符

    260 ACALL LCDP2 ;由LCD显示出来

    261 RET

    262

    263 ;----------- 温度值比较子程序------------

    264

    265 ;实际温度值与标记温度值比较

    266 TEMP_COMP:

    267 MOV A,TEMP_TH ;高温报警值送入A

    268 SUBB A,TEMP_ZH ;减数>被减数,则

    269 JC TCL1 ;借位标志位C=1,转TCL1

    270 MOV A,TEMP_ZH ;实时温度送入A

    271 SUBB A,TEMP_TL ;减数>被减数,则

    272 JC TCL2 ;借位标志位C=1,转TCL2

    273 MOV DPTR,#BJ5 ;存表BJ5

    274 ACALL TEMP_BJ3 ;调用显示高、低温度及加热标记子程序

    275 CLR RELAY ;继电器吸合

    276 RET

    277 ;―――――――――――――

    278 TCL1: ;实时温度>高温报警值的处理程序

    279 MOV DPTR,#BJ3 ;存入#BJ3表

    280 ACALL TEMP_BJ3 ;调用显示高、低温度及加热标记子程序

    281 SETB RELAY ;继电器关闭

    282 ACALL SPK_BZ ;调用鸣响子程序

    283 RET

    284 ;―――――――――――――-

    285 TCL2: ;实时温度<高温报警值的处理程序

    286 MOV DPTR,#BJ4 ;存入#BJ4表

    287 ACALL TEMP_BJ3 ;调用显示高、低温度及加标记子程序

    288 ACALL SPK_BZ ;调用鸣响子程序

    289 RET

    290

    291 ;--- 显示高、低温度及加热标记程序----

    292 TEMP_BJ3:

    293 MOV A,#0CEH ;设定显示位置

    294 ACALL WR_COMM ;调用写指令子程序

    295 MOV R1,#0 ;使指针指到表中第一个码

    296 MOV R0,#2 ;取码次数

    297 BJJ: MOV A,R1 ;A为0

    298 MOVC A,@A+DPTR ;读取码

    299 ACALL WR_DATA ;调用写数据子程序

    300 INC R1 ;R1值加1

    301 DJNZ R0,BJJ ;判断是否将代码读取完?

    302 RET

    303 ;―――――――――――――

    304 BJ3:

    305 DB ">H"

    306 BJ4:

    307 DB "
    308 BJ5:

    309 DB " !"

    310 ;―――――――――――――

    311

    312 ;--------- 报警上下线写入暂存器子程序 --------

    313 WR_THL:

    314 JB FLAG,WR_T ;FLAG=1,表示DS18B20存在,转WR_T 处

    315 RET

    316 ;―――――――――――――

    317 WR_T:

    318 ACALL RESET_1820 ;调用18B20复位子程序

    319 MOV A,#0CCH ;跳过ROM匹配

    320 LCALL WRITE_1820 ;调用写入子程序

    321 MOV A,#4EH ;写暂存寄存器

    322 LCALL WRITE_1820 ;调用写入子程序

    323 MOV A,TEMP_TH ;TH(报警上限)

    324 LCALL WRITE_1820 ;调用写入子程序

    325 MOV A,TEMP_TL ;TL(报警下限)

    326 LCALL WRITE_1820 ;调用写入子程序

    327 MOV A,#7FH ;12位精确度

    328 LCALL WRITE_1820 ;调用写入子程序

    329 RET

    330

    331;--------- 报警值拷贝到EEROM子程序 -----------

    332 WRITE_E2:

    333 ACALL RESET_1820 ;调用18B20复位子程序

    334 MOV A,#0CCH ;跳过ROM匹配

    335 LCALL WRITE_1820 ;调用写入子程序

    336 MOV A,#48H ;[48H]为拷贝到EEROM的指令代码

    337 LCALL WRITE_1820 ;调用写入子程序

    338 RET

    339

    340 ;---------- 报警值拷贝回暂存器子程序 ----------

    341 RE_THL:

    342 ACALL RESET_1820 ;调用18B20复位子程序

    343 MOV A,#0CCH ;跳过ROM匹配

    344 LCALL WRITE_1820 ;调用写入子程序

    345 MOV A,#0B8H ;把EEROM里的温度报警值拷贝回暂存器

    346 ACALL WRITE_1820 ;调用写入子程序

    347 RET

    348

    349 ;---------- 处理温度 BCD 码子程序 ----------

    350 CONV_TEMP:

    351 MOV A,TEMPH ;判温度是否零下

    352 ANL A,#80H

    353 JZ TC1 ;温度零转TC1处

    354 CLR C ;C=0

    355 MOV A,TEMPL ;二进制数求补(双字节)

    356 CPL A ;取反加1

    357 ADD A,#01H

    358 MOV TEMPL,A

    359 MOV A,TEMPH

    360 CPL A

    361 ADDC A,#00H

    362 MOV TEMPH,A

    363 JMP TC2

    364 ;―――――――――――――

    365 TC1: MOV TEMPHC,#0AH

    366 TC2: MOV A,TEMPHC

    367 SWAP A ;高、低位交换

    368 MOV TEMPHC,A

    369 MOV A,TEMPL

    370 ANL A,#0FH ;乘0.0625

    371 MOV DPTR,#DOTTAB

    372 MOVC A,@A+DPTR

    373 MOV TEMPLC,A ;TEMPLC LOW=小数部分 BCD

    374 ;―――――――――――――

    375 MOV A,TEMPL ;整数部分

    376 ANL A,#0F0H ;取出高四位

    377 SWAP A ;高、低位交换

    378 MOV TEMPL,A

    379 MOV A,TEMPH

    380 ANL A,#0FH ;取出低四位

    381 SWAP A ;高、低位交换

    382 ORL A,TEMPL ;重新组合

    383 MOV TEMP_ZH,A

    384 LCALL HEX2BCD1

    385 MOV TEMPL,A

    386 ANL A,#0F0H ;取出高四位

    387 SWAP A ;高、低位交换

    388 ORL A,TEMPHC ;TEMPHC LOW = 十位数 BCD

    389 MOV TEMPHC,A

    390 MOV A,TEMPL

    391 ANL A,#0FH ;取出低四位

    392 SWAP A ;高、低位交换

    393 ORL A,TEMPLC ;TEMPLC HI = 个位数 BCD

    394 MOV TEMPLC,A

    395 MOV A,R4

    396 JZ TC3

    397 ANL A,#0FH ;取出低四位

    398 SWAP A ;高、低位交换

    399 MOV R4,A

    400 MOV A,TEMPHC ;TEMPHC HI = 百位数 BCD

    401 ANL A,#0FH ;取出低四位

    402 ORL A,R4

    403 MOV TEMPHC,A

    404 TC3: RET

    405;―――――――――――――

    406 HEX2BCD1:

    407 MOV B,#064H ;十六进制-> BCD

    408 DIV AB ;B= A % 100

    409 MOV R4,A ;R4 = 百位数

    410 MOV A,#0AH

    411 XCH A,B

    412 DIV AB ;B = A % B

    413 SWAP A ;高、低位交换

    414 ORL A,B

    415 RET

    416 ;―――――――――――――

    417 ; 小数部分码表

    418 DOTTAB:

    419 DB 00H,00H,01H,01H,02H,03H,03H,04H

    420 DB 05H,05H,06H,06H,07H,08H,08H,09H

    421 ;―――――――――――――

    422

    423 ;-------- 显示区BCD 码温度值刷新子程序 --------

    424 DISP_BCD:

    425 MOV A,TEMPLC ;个位数BCD码送入A

    426 ANL A,#0FH ;取低位码

    427 MOV 70H,A ;小数位

    428 MOV A,TEMPLC

    429 SWAP A ;高、低位交换

    430 ANL A,#0FH ;取结果数的高位

    431 MOV 71H,A ;个位

    432 MOV A,TEMPHC

    433 ANL A,#0FH ;取低位码

    434 MOV 72H,A ;十位

    435 MOV A,TEMPHC

    436 SWAP A ;高、低位交换

    437 ANL A,#0FH ;取结果数的高位

    438 MOV 73H,A ;百位

    439 MOV A,TEMPHC

    440 ANL A,#0F0H ;取低位码

    441 CJNE A,#010H,DI0

    442 JMP DI2

    443 ;―――――――――――――

    444 DI0: MOV A,TEMPHC

    445 ANL A,#0FH ;取低位码

    446 JNZ DI2 ;十位数是0

    447 MOV A,TEMPHC

    448 SWAP A ;高、低位交换

    449 ANL A,#0FH ;取结果数的高位

    450 MOV 73H,#0AH ;符号位不显示

    451 MOV 72H,A ;十位数显示符号

    452 DI2: RET

    453

    454 ;―――――――― DS18B20复位初始化子程序 ――――――――――

    455 RESET_1820: ;复位(有具体的时序要求)

    456 SETB DQ

    457 NOP

    458 CLR DQ

    459 ;―――――――――――――

    460 ;主机发出延时537微秒的复位低脉冲

    461 MOV R1,#3

    462 DLY: MOV R0,#107

    463 DJNZ R0,$

    464 DJNZ R1,DLY

    465 ;―――――――――――――

    466 ;然后拉高数据线

    467 SETB DQ

    468 NOP

    469 NOP

    470 NOP

    471 ;―――――――――――――

    472 ;等待DS18B20回应

    473 MOV R0,#25H

    474 T2: JNB DQ ,T3

    475 DJNZ R0, T2

    476 JMP T4

    477 ;―――――――――――――

    478 ;置标志位FLAG=1,表示DS1820存在

    479 T3: SETB FLAG

    480 JMP T5

    481 ;―――――――――――――

    482 ;清标志位FLAG=0,表示DS1820不存在

    483 T4: CLR FLAG

    484 JMP T7

    485 ;―――――――――――――

    486 ;时序要求延时一段时间

    487 T5: MOV R0,#117

    488 T6: DJNZ R0,T6

    489 ;――――――――――――――

    490 T7: SETB DQ

    491 RET

    492

    493;―――――――――― 写入DS18B20子程序 ―――――――――――

    494 ;写入DS18B20(有具体的时序要求)

    495 WRITE_1820:

    496 MOV R2,#8 ;一共8位数据

    497 CLR C ;C=0

    498 WR1:

    499 CLR DQ ;总线低位,开始写入

    500 MOV R3,#6

    501 DJNZ R3,$ ;保持16微秒以上

    502 RRC A ;把字节DATA分成8个BIT环移给C

    503 MOV DQ, C ;写入一个BIT

    504 MOV R3,#23

    505 DJNZ R3,$ ;等待

    506 SETB DQ ;重新释放总线

    507 NOP

    508 DJNZ R2,WR1 ;写入下一个BIT

    509 SETB DQ ;释放总线

    510 RET

    511

    512 ;―――――――――― 读出DS18B20子程序 ―――――――――――

    513 ;将温度值从DS18B20中读出(有具体的时序要求)

    514 READ_1820:

    515 MOV R4,#4

    516 MOV R1,#TEMPL ;存入25H、26H、27H、28H

    517 RE0:

    518 MOV R2,#8 ;数据一共有8位

    519 RE1:

    520 CLR C

    521 SETB DQ

    522 NOP

    523 NOP

    524 CLR DQ ;读前总线保持为低位

    525 NOP

    526 NOP

    527 NOP

    528 SETB DQ ;总线释放

    529 ;―――――――――――――

    530 MOV R3,#9

    531 DJNZ R3,$ ;延时18微妙

    532 MOV C, DQ ;从总线读到一个BIT

    533 ;―――――――――――――

    534 MOV R3,#23 ;

    535 DJNZ R3,$ ;等待50微秒

    536 RRC A ;把读得的位值环移给A

    537 DJNZ R2,RE1 ;读下一个BIT

    538 MOV @R1,A

    539 INC R1 ; R1内数据递增

    540 DJNZ R4,RE0

    541 RET

    542

    543 ;=========== LCD 1602 显示程序 ===========

    544 ;初始化设置

    545 SET_LCD:

    546 CLR E

    547 CALL INIT_LCD ;初始化 LCD

    548 CALL STORE_DATA ;将自定义字符存入LCD的CGRAM

    549 RET

    550

    551;----------- LCD 初始化子程序 -----------

    552 INIT_LCD:

    553 MOV A,#38H ;设置8位、2行、5x7点阵

    554 ACALL WR_COMM ; 调用写指令子程序

    555 ACALL DELAY1 ;调用延时子程序

    556 MOV A,#0CH ;开显示,光标不闪烁

    557 ACALL WR_COMM ;调用写指令子程序 ;

    558 ACALL DELAY1 ;调用延时子程序

    559 MOV A,#01H ;清除 LCD 显示屏

    560 ACALL WR_COMM ;调用写指令子程序 ;

    561 ACALL DELAY1 ;调用延时子程序

    562 RET

    563

    564 ;---------- 显示温度标记子程序 -----------

    565 TEMP_BJ:

    566 MOV A, #0CBH ;设定第二行起始地址

    567 ACALL WR_COMM ;调用写指令子程序

    568 MOV DPTR,#BJ ;存代码表

    569 MOV R1 ,#0 ;使指针指到表中第一个码

    570 MOV R0 ,#2 ;取码次数

    571 TP1:

    572 MOV A,R1 ;A为0

    573 MOVC A,@A+DPTR ;取码

    574 ACALL WR_DATA ;调用写数据子程序

    575 INC R1 ;R1值加1

    576 DJNZ R0,TP1 ;判断是否将代码读取完?

    577 RET

    578 ;―――――――――――――

    579 BJ: ;代码表

    580 DB 00H, "C"

    581;―――――――――――――

    582

    583;----------- 自定义字符子程序 -----------

    584 ;将自定义字符写入LCD1602的CGRAM中

    585 STORE_DATA:

    586 MOV A,#40H ;指定CG RAM起始地址

    587 ACALL WR_COMM ;将指令写入LCD

    588 MOV R2,#08H ;图形数据长度8个字节

    589 MOV DPTR,#TAB ;存代码表

    590 MOV R3,#00H ;使指针指到表中第一个码

    591 S_D: MOV A,R3 ;A为0

    592 MOVC A,@A+DPTR ;读取表代码

    593 ACALL WR_DATA ;调用写入数据指令

    594 INC R3 ;R3值加1

    595 DJNZ R2, S_D ;判断是否将代码读取完?

    596 RET ;

    597 ;―――――――――――――

    598 TAB: ;代码表

    599 DB 0CH,12H,12H,0CH

    600 DB 00H,00H,00H,00H

    601 ;―――――――――――――-

    602

    603;----------- 显示“OK”信息子程序 ---------

    604 MEU_OK:

    605 MOV DPTR,#M_OK1 ;指针指到显示消息

    606 MOV A,#1 ;显示在第一行

    607 ACALL LCD_PRINT ;LCD显示

    608 MOV DPTR,#M_OK2 ;指针指到显示消息

    609 MOV A,#2 ;显示在第一行

    610 ACALL LCD_PRINT ;LCD显示

    612 RET

    613 ;――――――――――――――

    614 M_OK1:

    615 DB " DS18B20 OK ",0

    616 M_OK2:

    617 DB " TEMP: ",0

    618 ;――――――――――――――

    619

    620 ;----------显示“ERROR”信息子程序------―――

    621 MEU_ERROR:

    622 MOV DPTR,#M_ERROR1 ;指针指到显示消息1

    623 MOV A,#1 ;显示在第一行

    624 ACALL LCD_PRINT ;调用菜单显示子程序

    625 MOV DPTR,#M_ERROR2 ;指针指到显示消息1

    626 MOV A,#2 ;显示在第一行

    627 ACALL LCD_PRINT ;调用菜单显示子程序

    628 RET

    629 ;---------------

    630 M_ERROR1: ;代码表

    631 DB " DS18B20 ERROR ",0

    632 M_ERROR2:

    633 DB " TEMP: ---- ",0

    634 ;---------------

    635

    636 ;------――――― 菜单显示子程序 ―――――――-----

    637 ;在LCD的第一行或第二行显示字符

    638 LCD_PRINT:

    639 CJNE A,#1,LINE2 ;判断是否为第一行

    640 LINE1:

    641 ACALL CLR_LINE ;清除该行字符数据

    642 MOV A,#80H ;设置 LCD 的第一行地址

    643 ACALL WR_COMM ;写入命令

    644 JMP FILL

    645 LINE2:

    646 ACALL CLR_LINE ;清除该行字符数据

    647 MOV A,#0C0H ;设置 LCD 的第二行地址

    648 ACALL WR_COMM

    649 FILL:

    650 CLR A ;填入字符

    651 MOVC A,@A+DPTR ;由消息区取出字符

    652 CJNE A,#0,LC1 ;判断是否为结束码

    653 RET

    654 LC1:

    655 ACALL WR_DATA ;写入数据

    656 INC DPTR ;指针加1

    657 JMP FILL ;继续填入字符

    658 RET

    659

    660 ;---------― LCD显示子程序 ----------

    661 CONV:

    662 MOV A,73H ;加载百位数据

    663 MOV X,#6 ;设置位置

    664 CJNE A,#1,CO1

    665 JMP CO2

    666 CO1:

    667 MOV A,#" "

    668 MOV B,X

    669 ACALL LCDP2

    670 JMP CO3

    671 CO2:

    672 ACALL SHOW_LINE2 ;显示数据

    673 CO3: INC X ;位加1

    674 MOV A,72H ;十位

    675 ACALL SHOW_LINE2 ;显示数据

    676 INC X ;位加1

    677 MOV A, 71H ;个位

    678 ACALL SHOW_LINE2 ;显示数据

    679 INC X ;位加1

    680 MOV A,#'.'

    681 MOV B,X

    682 ACALL LCDP2 ;显示字符

    683 MOV A,70H ;加载小数点位

    684 INC X ;设置位置

    685 ACALL SHOW_LINE2 ;显示数据

    686 RET

    687

    688;-----―― 显示第二行 -----―――

    689 ;在 LCD 的第二行显示数字

    690 SHOW_LINE2:

    691 ADD A,#30H

    692 MOV B,X

    693 ACALL LCDP2

    694 RET

    695 LCDP2: ;在LCD的第二行显示字符

    696 PUSH ACC ;放入堆栈

    697 MOV A,B ;设置显示地址

    698 ADD A,#0C0H ;设置LCD的第二行地址

    699 ACALL WR_COMM ;写入命令

    700 POP ACC ;由堆栈取出A

    701 ACALL WR_DATA ;写入数据

    702 RET

    703

    704 ;-----―――――― 写指令子程序 ――――――――――--

    705 WR_COMM:

    706 MOV P1,A ;写入指令

    707 CLR RS ;RS=0,选择指令寄存器

    708 CLR RW ;RW=0,选择写模式

    709 SETB E ;E=1,允许读/写LCM

    710 ACALL DELAY1 ;延时5MS

    711 CLR E ;E=0,禁止读/写LCM

    712 RET

    713

    714 ;---------――― 写数据子程序 ------------

    715 WR_DATA:

    716 MOV P1,A ;写入数据

    717 SETB RS ;RS=1,选择数据寄存器

    718 CLR RW ;RW=0,选择写模式

    719 SETB E ;E=1,允许读/写LCM

    720 ACALL DE ;延时0.5MS

    721 CLR E ;E=0,禁止读/写LCM

    722 ACALL DE ;延时0.5MS

    723 RET

    724

    725 ;---------- 清除LCD 的字符-------------

    726 CLR_LINE:

    727 MOV R0,#24 ;设置计数值

    728 CL1: MOV A,#' ' ;载入空格符至LCD

    729 ACALL WR_DATA ;输出字符至LCD

    730 DJNZ R0,CL1 ;判断

    731 RET

    732 ;--------------

    733 CLR_LINE1: ;清除LCD的第一行字符

    734 MOV A,#80H ;设置 LCD 的第一行地址

    735 ACALL WR_COMM ;调用写指令子程序

    736 MOV R0,#24 ;设置计数值

    737 C1: MOV A,#' ' ;载入空格符至LCD

    738 ACALL WR_DATA ;输出字符至LCD

    739 DJNZ R0,C1 ;计数结束

    740 RET

    741

    742 ;------------- 鸣响子程序------------

    743 SPK_BZ:

    744 MOV R6,#100

    745 BZ2: ACALL DEX1

    746 CPL SPK

    747 DJNZ R6,BZ2

    748 MOV R5,#10

    749 ACALL DELAY

    750 RET

    751 DEX1: MOV R7,#180

    752 DE2: NOP

    753 DJNZ R7,DE2

    754 RET

    755

    756 ;-------------延时子程序-------------

    757 DELAY: ;延时时间为:R5×10MS

    759 DL1: MOV R7,#100

    760 DJNZ R7,$

    761 DJNZ R6,DL1

    762 DJNZ R5,DELAY

    763 RET

    764 ;―――――――――――――

    765 DELAY1: ;延时时间为5MS

    766 MOV R6,#25

    767 DL2: MOV R7,#100

    768 DJNZ R7,$

    769 DJNZ R6,DL2

    770 RET

    771 ;―――――――――――――

    772 DE:

    773 MOV R7,#250 ;延时时间为0.5MS

    774 DJNZ R7,$

    775 RET

    776 ;-----------――

    777 END