⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 1602_lcd at89s52.txt

📁 使用1602_LCD AT89S52 18B20实现的温度报警
💻 TXT
📖 第 1 页 / 共 4 页
字号:
;********************************************************
;使用1602_LCD AT89S52  18B20实现的温度报警,时间可调显示,
;一天可设三个闹钟,八首音乐,一个秒表,
;全汇编实现,程序差不多写满8K BYTES 了

;硬件电路比较简单,主要靠程序上的实现

;完成时间____2006\09\27\sml 
;********系统初始化***********************
T2CON   EQU 0C8H  
CP_RL2  BIT 0C8H.0
C_T2    BIT 0C8H.1
TR2     BIT 0C8H.2
EXEN2   BIT 0C8H.3
TCLK    BIT 0C8H.4
RCLK    BIT 0C8H.5
EXF2    BIT 0C8H.6
TF2     BIT 0C8H.7
RCAP2H  EQU 0CBH
RCAP2L  EQU 0CAH
TH2     EQU 0CDH
TL2     EQU 0CCH
ET2     BIT IE.5
ORG 00H
JMP INPORT
ORG 0BH
LJMP TM0
 ORG 001BH
 LJMP INTT0
 ORG 002BH
LJMP TIME_T2
ORG 30H
INPORT:
TMP_H EQU 29H ;温度高字节
TMP_L EQU 28H
TEMPHEAD EQU 6BH
DI_DA DATA 21H
	SEC DATA 22H
	MIN DATA 23H
	HOUR DATA 24H
RS EQU P3.5;确定具体硬件的连接方式 
RW EQU P3.4 ;确定具体硬件的连接方式
E  EQU P3.3 ;确定具体硬件的连接方式

;秒表暂RAM单元定义
WATCH_H EQU 4DH
WATCH_M EQU 4EH
WATCH_S EQU 4FH
WATCH_MS EQU 50H
WATCH_H_H EQU 51H
WATCH_H_L EQU 52H
WATCH_M_H EQU 53H
WATCH_M_L EQU 54H
WATCH_S_H EQU 55H
WATCH_S_L EQU 56H
WATCH_MS_H EQU 57H
WATCH_MS_L EQU 58H

ALARM1_H EQU 59H
ALARM1_M EQU 5AH
ALARM2_H EQU 5BH
ALARM2_M EQU 5CH
ALARM3_H EQU 5DH
ALARM3_M EQU 5EH
ALARM1_H_H EQU 5FH
ALARM1_H_L EQU 60H
ALARM2_H_H EQU 61H
ALARM2_H_L EQU 62H
ALARM3_H_H EQU 63H
ALARM3_H_L EQU 64H
ALARM1_M_H EQU 65H
ALARM1_M_L EQU 66H
ALARM2_M_H EQU 67H
ALARM2_M_L EQU 68H
ALARM3_M_H EQU 69H
ALARM3_M_L EQU 6AH

STOPWATCH_FLAG1 EQU 04H
CLR 04H

ALARM1_ON_OR_OFF EQU 07H
ALARM2_ON_OR_OFF EQU 06H
ALARM3_ON_OR_OFF EQU 05H

;TEMPERATURE_ALARM_BEEP_FLAG EQU 04H;在温度CONTROL时,要考虑到这条件进去

KEY_SET EQU P0.3
KEY_UP  EQU P0.4
KEY_DOWN EQU P0.5
DS18B20_FLAG EQU PSW.0;开始时要查18B20存在否
SET_FLAG EQU 01H
FLASH_FLAG EQU 02H
K_ON EQU 03H;是个位标志哦
SETB K_ON
SETB FLASH_FLAG 
SETB SET_FLAG
CLR 07H
CLR 06H
CLR 05H


MOV A,#0
MOV 25H,A
MOV 26H,A

MOV 32H,A
MOV 33H,A



MOV R4,#14;  
MOV TMOD,#11H
	MOV TL0,#0B0H
	MOV TH0,#3CH
	SETB ET0
	SETB TR0
	SETB ET1
	MOV DI_DA,#00H
	

	 CLR C_T2 ;
      CLR CP_RL2;允许重载
	  ;T2MOD的TO2是T2输出允许
      MOV RCAP2H,#0D9H ;预先值高   10ms  12MHZ 
      MOV RCAP2L,#0B8H
	  MOV TH2,#0D9H
	  MOV TL2,#0B8H
	   
	  SETB ET2
	   SETB EA


LCD_INIT://lcd的初化配置
;15MS
MOV R6,#30
LCALL DELAY_BY_R6 ;15ms
MOV P1,#38H ;写38h
LCALL WRITE_NOT_CHECK_BUSY 
MOV R6,#10
LCALL DELAY_BY_R6 ;5ms																														
MOV P1,#38H
LCALL WRITE_NOT_CHECK_BUSY
MOV R6,#10
LCALL DELAY_BY_R6 ;5ms
;-----设转初始值
SETB E
MOV P1,#00000001B ;清屏并光标复位
LCALL ENABLE;调用写入命令子程序 
MOV P1,#00111000B ;8位2行5x7点阵 
LCALL ENABLE ;调用写入命令子程序 
MOV P1,#00001100B ;显示器开、光标开、光标允许闪烁
LCALL ENABLE ;调用写入命令子程序
MOV P1,#00000110B;文字不动,光标自动右移 
LCALL ENABLE ;调用写入命令子程序


STORE_DEFINE_DATA: ;把自定义字符存入CGRAM
MOV P1,#40H ;CGRAM起始地址
LCALL ENABLE
MOV R2,#8
MOV DPTR,#DEFINE_DATA
MOV R3,#0
NEXTP:
MOV A,R3
MOVC A,@A+DPTR
MOV P1,A
LCALL WRITE_DATA_TO_LCD
INC R3
DJNZ R2,NEXTP

;****************主程序*******************
START:
      LCALL RESET
     JNB  70h,MAIN1
     MOV P1,#0C0H ;写入显示起始地址(第二行第一个位置)
     LCALL ENABLE ;调用写入命令子程序(写入字符串前要查忙)

DS18B20_NOT_READY: 
                   LCALL DISPLAY_18B20_ERROR

LOOP1: 
        LCALL RESET
        JNB 70h,MAIN1
        JMP LOOP1 ;如果栓测不到18b20程序下面不执行

MAIN1: 
MOV R1,#4 ;清单元数据
MOV R0,#21H
CLEAR:MOV A,#0
MOV @R0,A
INC R0
DJNZ R1,CLEAR
MOV R1,#30
MOV R0,#4DH
CLEAR1:MOV A,#0
 MOV @R0,A
 INC R0
 DJNZ R1,CLEAR1
MOV R1,#9
MOV R0,#6BH
CLEAR2:MOV A,#0
MOV @R0,A
INC R0
DJNZ R1,CLEAR2
MOV R1,#6
MOV R0,#40H
CLEAR3:MOV A,#0
MOV @R0,A
INC R0
DJNZ R1,CLEAR3
BACKK:

MOV P1,#00000001B ;清屏并光标复位
LCALL ENABLE;调用写入命令子程序 
LCALL DISPLAY_WATING ;等待第一次结果.
LCALL SKIP_ROM 
LCALL TEMP_CONV
LCALL DELAY_600MS 
MOV P1,#00000001B ;清屏并光标复位
LCALL ENABLE;调用写入命令子程序
   
MAIN :
LCALL RESET
LCALL SKIP_ROM 
LCALL RELCALL_EPROM ;调入温度限值
MAIN_MAIN:
LCALL READ_TEMP ;读18b20的内部温度
JB 70h,DS18B20_NOT_READY ;中途失败!
LCALL DATA_CONV ; 数据转换,同时有温度比较和报警动作标志K_ON=1则对应开机器
LCALL DISPLAY_18B20_TEMP
LCALL DISPLAY_TIME
LCALL CONTROL
LCALL ALARM_COMPARE

JNB KEY_SET,S1;KEY_SET是设定上下限的标志按钮P0.3。。。
LCALL TIME_ADJ		   
LCALL MUSIC
JMP MAIN_MAIN
S1:LCALL DELAY_2MS ;延时消抖
JB KEY_SET,MAIN
JNB KEY_SET,$;等待按键放开
LCALL KEY ;有键输入
AJMP MAIN

MUSIC:MOV A,#0F0H
 MOV P2,A
 MOV A,P2
 CJNE A,#0F0H,KEYIN1
 RET

 KEYIN1:MOV R3,#0F7H;令第四行为0
        MOV R1,#00H
SCAN:   MOV A,R3
        MOV P2,A
		MOV A,P2
		MOV R4,A;读回的值暂放R4中
		SETB C
		MOV R5,#04H;四列要扫描
K:      RLC A
        JNC DONE
		INC R1
		INC R1
		DJNZ R5,K
		MOV A,R3
		SETB C
		RRC A
		MOV R3,A
		JC SCAN
		RET
DONE:MOV A,P2
     XRL A,R4
	 JZ DONE
	 MOV A,R1
	 MOV DPTR,#FUNCTION_TAB
	 JMP @A+DPTR

FUNCTION_TAB:
      AJMP FU0
	  AJMP FU1
	  AJMP FU2
	  AJMP FU3
	  AJMP FU4
	  AJMP FU5
	  AJMP FU6 
	  AJMP FU7
	  AJMP FU8
	  AJMP FU9
	  AJMP FU10
	  AJMP FU11
	  AJMP FU12
	  AJMP FU13
	  AJMP FU14
	  AJMP FU15

FU0: 
RET 
FU1:
RET
FU2:
RET
FU3:

RET
FU4:

RET
FU5:;SETB P0.1
     ;CLR TEMPERATURE_ALARM_BEEP_FLAG

RET
FU6:
;MOV P1,#00000001B ;清屏并光标复位
;LCALL ENABLE;调用写入命令子程序 


   
   LCALL DISPLAY_ALARM_CLOCK_1;程序在后面加,只显示"ALARM_CLOCK_1"
ALARM_K:JB ALARM1_ON_OR_OFF,DISPLAY__ON
		LCALL DISPLAY_ALARM_OFF
		LJMP ALARM_DATACON_DIS
DISPLAY__ON:LCALL DISPLAY_ALARM_ON
;下面是转换
ALARM_DATACON_DIS: 
MOV A,ALARM1_H
SWAP A
ANL A,#0FH
MOV ALARM1_H_H,A
MOV A,ALARM1_H
ANL A,#0FH
MOV ALARM1_H_L,A

MOV A,ALARM1_M
SWAP A
ANL A,#0FH
MOV ALARM1_M_H,A
MOV A,ALARM1_M
ANL A,#0FH
MOV ALARM1_M_L,A


;下面是显示闹钟值

MOV P1,#11000101B
LCALL ENABLE

MOV DPTR,#LED_DATA
MOV R1,ALARM1_H_H //已经是压缩型BCD码了,
MOV R0,#1
LCALL DISPLAY

MOV DPTR,#LED_DATA
MOV R1,ALARM1_H_L //已经是压缩型BCD码了,
MOV R0,#1
LCALL DISPLAY

MOV DPTR,#MAO
MOV R1,#0;从字串中的第一个开始显示
MOV R0,#1
LCALL DISPLAY

MOV DPTR,#LED_DATA
MOV R1,ALARM1_M_H //已经是压缩型BCD码了,
MOV R0,#1
LCALL DISPLAY

MOV DPTR,#LED_DATA
MOV R1,ALARM1_M_L //已经是压缩型BCD码了
MOV R0,#1
LCALL DISPLAY


;再下面就是判P0.30.40.5了
LOOPP: JB P0.4,PANP05;转判P0.5;;;;;;;;;
LCALL DELAY2S
JB P0.4,ADJ_ALARM_H	;如果一S之后为放开了,其实是在1S前就放开了的,则知道是调闹钟的小时值的
JNB P0.4,$;1S后还未放开,则等,1S后已经放开,则早就放开,所以进行不同操作
CPL ALARM1_ON_OR_OFF;如果一S后还为0则取反ALARM1_ON_OR_OFF标志,关掉闹钟
LJMP ALARM_K
ADJ_ALARM_H:MOV A,ALARM1_H
            ADD A,#1
			DA A
			MOV ALARM1_H,A
			CJNE A,#24H,ALARM_NEXT
			MOV A,#0
			MOV ALARM1_H,A

ALARM_NEXT:LJMP ALARM_DATACON_DIS;跳到先转换数据,再显示
PANP05:JB P0.5,PAN03; 如果此时P0.5也为1,则转判P0.3
LCALL DELAY2S
JNB P0.5,$;等放开
 MOV A,ALARM1_M
            ADD A,#1
			DA A
			MOV ALARM1_M,A
			CJNE A,#60H,ALARM_NEXT
			MOV A,#0
			MOV ALARM1_M,A

		   LJMP ALARM_DATACON_DIS
PAN03:	JB P0.3,LOOPP
		LCALL DELAY2S
        JB P0.3,DISPLAY_ALARM2	;如果一S之后为放开了,其实是在1S前就放开了的,则知道是设闹钟2
        JNB P0.3,$;
		LJMP BACKK;如果长久按P0.3则跳出到主程序中去


;下面是设置第二个闹钟
DISPLAY_ALARM2:
	LCALL DISPLAY_ALARM_CLOCK_2

ALARM_K1:JB ALARM2_ON_OR_OFF,DISPLAY__ON_2
		LCALL DISPLAY_ALARM_OFF
		LJMP ALARM_DATACON_DIS_2
DISPLAY__ON_2:LCALL DISPLAY_ALARM_ON

ALARM_DATACON_DIS_2:
MOV A,ALARM2_H
SWAP A
ANL A,#0FH
MOV ALARM2_H_H,A
MOV A,ALARM2_H
ANL A,#0FH
MOV ALARM2_H_L,A

MOV A,ALARM2_M
SWAP A
ANL A,#0FH
MOV ALARM2_M_H,A
MOV A,ALARM2_M
ANL A,#0FH
MOV ALARM2_M_L,A


;下面是显示闹钟值

MOV P1,#11000101B
LCALL ENABLE

MOV DPTR,#LED_DATA
MOV R1,ALARM2_H_H //已经是压缩型BCD码了,,
MOV R0,#1
LCALL DISPLAY

MOV DPTR,#LED_DATA
MOV R1,ALARM2_H_L //已经是压缩型BCD码了,,
MOV R0,#1
LCALL DISPLAY

MOV DPTR,#MAO
MOV R1,#0;从字串中的第一个开始显示
MOV R0,#1
LCALL DISPLAY

MOV DPTR,#LED_DATA
MOV R1,ALARM2_M_H //已经是压缩型BCD码了,
MOV R0,#1
LCALL DISPLAY

MOV DPTR,#LED_DATA
MOV R1,ALARM2_M_L //已经是压缩型BCD码了,,
MOV R0,#1
LCALL DISPLAY

;顺序执行下面的

LOOPPP: JB P0.4,PANP05_2;转判P0.5;;;;;;;;;还没有写此句程序呢后面
LCALL DELAY2S
JB P0.4,ADJ_ALARM_2_H	;如果一S之后为放开了,其实是在1S前就放开了的,则知道是调闹钟的小时值的
JNB P0.4,$;1S后还未放开,则等,1S后已经放开,则早就放开,所以进行不同操作
CPL ALARM2_ON_OR_OFF;如果一S后还为0则取反ALARM1_ON_OR_OFF标志,关掉闹钟
LJMP ALARM_K1
ADJ_ALARM_2_H:
            MOV A,ALARM2_H
            ADD A,#1
			DA A
			MOV ALARM2_H,A
			CJNE A,#24H,ALARM_NEXT_2
			MOV A,#0
			MOV ALARM2_H,A

ALARM_NEXT_2:LJMP ALARM_DATACON_DIS_2;跳到先转换数据,再显示

PANP05_2:JB P0.5,PAN03_2; 如果此时P0.5也为1,则转判P0.3
LCALL DELAY2S
JNB P0.5,$;等放开
 MOV A,ALARM2_M
            ADD A,#1
			DA A
			MOV ALARM2_M,A
			CJNE A,#60H,ALARM_NEXT_2
			MOV A,#0
			MOV ALARM2_M,A

		   LJMP ALARM_DATACON_DIS_2
PAN03_2:	JB P0.3,LOOPPP
		LCALL DELAY2S
        JB P0.3,DISPLAY_ALARM3	;如果一S之后为放开了,其实是在1S前就放开了的,则知道是设闹钟2
        JNB P0.3,$;
		LJMP BACKK;如果长久按P0.3则跳出到主程序中去

;下面是设置第三个闹钟

DISPLAY_ALARM3:

  	LCALL DISPLAY_ALARM_CLOCK_3

ALARM_K2:JB ALARM3_ON_OR_OFF,DISPLAY__ON_3
		LCALL DISPLAY_ALARM_OFF
		LJMP ALARM_DATACON_DIS_3
DISPLAY__ON_3:LCALL DISPLAY_ALARM_ON

ALARM_DATACON_DIS_3:
MOV A,ALARM3_H
SWAP A
ANL A,#0FH
MOV ALARM3_H_H,A
MOV A,ALARM3_H
ANL A,#0FH
MOV ALARM3_H_L,A

MOV A,ALARM3_M
SWAP A
ANL A,#0FH
MOV ALARM3_M_H,A
MOV A,ALARM3_M
ANL A,#0FH
MOV ALARM3_M_L,A


;下面是显示闹钟值

MOV P1,#11000101B
LCALL ENABLE

MOV DPTR,#LED_DATA
MOV R1,ALARM3_H_H //已经是压缩型BCD码了
MOV R0,#1
LCALL DISPLAY

MOV DPTR,#LED_DATA
MOV R1,ALARM3_H_L //已经是压缩型BCD码了,,
MOV R0,#1
LCALL DISPLAY

MOV DPTR,#MAO
MOV R1,#0;从字串中的第一个开始显示
MOV R0,#1
LCALL DISPLAY

MOV DPTR,#LED_DATA
MOV R1,ALARM3_M_H //已经是压缩型BCD码了,
MOV R0,#1
LCALL DISPLAY

MOV DPTR,#LED_DATA
MOV R1,ALARM3_M_L //已经是压缩型BCD码了
MOV R0,#1
LCALL DISPLAY

;顺序执行下面的

LOOPPPP: JB P0.4,PANP05_3;转判P0.5;;;;;;;;;还没有写此句程序呢后面
LCALL DELAY2S
JB P0.4,ADJ_ALARM_3_H	;如果一S之后为放开了,其实是在1S前就放开了的,则知道是调闹钟的小时值的
JNB P0.4,$;1S后还未放开,则等,1S后已经放开,则早就放开,所以进行不同操作
CPL ALARM3_ON_OR_OFF;如果一S后还为0则取反ALARM1_ON_OR_OFF标志,关掉闹钟

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -