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

📄 all.asm

📁 一个基于PID算法和模糊控制算法的水温控制系统
💻 ASM
字号:

TEMPDIN	EQU 	P1.4
;****************
;时间常数定义
;****************
TIMEL		EQU	0E0H
TIMEH		EQU	0B1H
BITST		EQU	20H
TIME1SOK	BIT	BITST.1
TEMPH		EQU 	21H		;从温度传感器得到的数据暂存
TEMPL		EQU	22H

TEMPL_ZAN	EQU	57H              ;上一次测得数据暂存
TEMPH_ZAN	EQU	56H

TEMPL1		EQU	50H              ;供存储三次测得的数据的差值
TEMPH1		EQU	51H
TEMPL2		EQU	52H            
TEMPH2		EQU	53H
TEMPL3		EQU	54H
TEMPH3		EQU	55H

TEMP_HH		EQU	23H		;BCD转换后的温度数据,百位+十位压缩,当百位为零时,存的是符号位正:A 负:B
TEMP_HL		EQU	24H		;高位为个位,低位为无用数据
TEMP_LH		EQU	25H		;小数压缩
TEMP_LL		EQU	26H
TSET	EQU 	37H
COM     EQU	3DH		;指令寄存器
DAT	EQU	3EH		;数据寄存器
TGETD	EQU 	3FH
BUFFER	EQU 	40H
CW_ADD	EQU	0000H		;指令口写地址
DW_ADD	EQU	0001H		;数据口写地址
CR_ADD	EQU	0002H		;指令口读地址

KEY_ADD 	EQU     P1
COL		EQU     28H
KEYCODE		EQU     29H

TEMP_RD_H            EQU     41H
TEMP_RD_L            EQU     42H

TEMP_RD_H1            EQU     43H       ;键盘值暂存
TEMP_RD_L1            EQU     44H
PMWCON                EQU     5FH       ;脉宽调制控制寄存器
pid                   equ     5eh

ORG 	0000H
LJMP 	STARTMEASURE
ORG 0003H
LJMP PRG_INT0		;键盘中断服务程序
ORG	000BH
LJMP	TOIT
	ORG 0100H
STARTMEASURE:
	MOV SP,#61H
        mov pid,#02h    ;kip预置为2
        MOV TEMP_RD_H #02H
        MOV TEMP_RD_H #80H
CLSMEM:	MOV R0,#30H
	MOV R1,#60H
CLSMEM1:MOV @R0,#00H
	INC R0
	DJNZ R1,CLSMEM1
	MOV TMOD,#01H
	MOV TH0,#TIMEL
	MOV TL0,#TIMEH
        LCALL KEYINI	;准备键盘中断
	MOV IP,#01H		;INT0优先级最高
	MOV IE,#00000001B	;设定INT0
	SJMP INIT
ERROR:	NOP
	LJMP STARTMEASURE
	NOP
INIT:	NOP
	SETB ET0
	SETB TR0
	SETB EA
	MOV PSW,#00H
	JMP START
;****************
;准备键盘中断
;****************
KEYINI:	MOV A,#0FH              ;准备键盘中断
	MOVX KEY_ADD,A
        RET
;****************
;键盘中断服务程序
;****************
PRG_INT0:LCALL KEYSCAN                  ;键盘中断服务程序
	 JNC NEXT
	 AJMP SKIP4
NEXT:	 MOV A,KEYCODE                   ;温度增10度
	 CJNE A,#0EEH,NEXT1

         MOV A,TEMP_RD_L1
         CLR C
         ADD A,#0A0H
         MOV TEMP_RD_L1,A
         MOV A,TEMP_RD_H1
         ADDC A,00H
         MOV  TEMP_RD_H1,A

	 JMP SKIP4
NEXT1:	 CJNE A,#0EDH,NEXT2		;温度减10度

	 MOV A,TEMP_RD_L1
         CLR C
         SUBB A,#0A0H
         MOV TEMP_RD_L,A
         MOV A,TEMP_RD_H1
         SUBB A,00H
         MOV  TEMP_RD_H1,A

	 JMP SKIP4
NEXT2:   CJNE A,#0EBH,NEXT3		;确认键
         mov TEMP_RD_H,TEMP_RD_H1
         mov TEMP_RD_L,TEMP_RD_L1

 	 JMP SKIP4
NEXT3:   CJNE A,#0BEH,SKIP4		;200HZ
	 ;MOV FREQ,#02H
	; LCALL DIS2
SKIP4:	 MOV A,#0FH
	 MOV A,#KEY_ADD
	 RETI



;*****************************************************
;键盘扫描程序
;R1 列值暂存,R2 循环次数计数,R3 行扫描码,A 返回键值
;键扫描程序
;*****************************************************
KEYSCAN:
        MOV A,KEY_ADD    ;读入列值
        ANL A,#0FH	  ;清高四位
        MOV COL,A         ;列信息保存在COL
        LCALL DELAY20MS        ;延时20ms

        MOV R2,#04H
        MOV R3,#0EFH	  ;使第0行输出低电平
        MOV A,R3          ;行扫描
AGAIN:  MOV A,KEY_ADD    ;读入列值
        anl a,#0fh
        MOV R1,A          ;列值暂存R1
        XRL A,#0FH	  ;异或,有键按下输出Z=0,无键按下Z=1
        JNZ KEYIN         ;A!=0F,表示找到键
        MOV A,R3          ;否则扫描下一行
        SETB C
        RLC A
        MOV R3,A          ;扫描下一行
        DJNZ R2,AGAIN
        JMP NOKEY         ;四行扫描完,未找到对应行置A=00H

KEYIN:  mov a,r1
        cjne a,COL,NOKEY1 ;延迟20ms后看是否和之前一样,如不是,则判无键输入
        LCALL DELAY20MS      ;消除键抖动

LOOP :MOV A,KEY_ADD
      ANL A,#0FH
      XRL A,#0FH
      JNZ LOOP            ;等待键放开z=0继续循环,不全零说明键还没放开

      MOV A,R3
      ANL A,#0F0H
      ORL A,R1            ;得到行列码
      MOV KEYCODE,A
      CLR C
      JMP RETURN

nokey1:MOV A,KEY_ADD
      ANL A,#0FH
      XRL A,#0FH
      JNZ nokey1
NOKEY:SETB C
RETURN: RET

DELAY20MS: MOV R7,#20  		;延时10ms
  D2  : MOV R6,#00
        DJNZ R6,$
        DJNZ R7,D2
        RET

START:	LCALL 	LCD_INIT
      	LCALL	DISPLAY1
AGAIN:	JNB TIME1SOK,$
	CLR TIME1SOK
        LCALL   JUDGE
	LCALL 	RDTEMP
	LCALL	CONVTEMP
      	LCALL 	DISPLAY2
      	LJMP 	AGAIN

JUDGE:   PUSH PSW
         PUSH ACC
         MOV R1,TEMP_RD_H
         MOV R2,TEMP_RD_L
         MOV R3,TEMPH               ;判断温差>5度,采用模糊控制
         MOV R4,TEMPL
         MOV A,R2
         CLR C
         SUBB A,R4
         MOV R5,A                   ;低位之差暂存
         MOV A,R1
         SUBB A,R3
         JNC PLUS
         CPL A
         MOV R6,A
         CLR C
         MOV A,R5
         CPL A
         ADD A,#01H
         MOV R5,A
PLUS:    MOV A,R6
         JNZ MOHU
         CLR C
         MOV A,R5
         SUBB A,50H
         JC MOHU
         SJMP PIDCON
         POP ACC
         POP PSW
         RET

;*****************
;采用模糊控制
;******************         
MONU:    MOV     58H,53H
         MOV     57H,52H
         MOV     5AH,51H
         MOV     59H,50H
         LACALL  QUCHA
         MOV     A,51H
         CLR     C
         SUBB    A,#0A0H
         JNC     MINUS1
         MOV     A,5CH
         CLR     C
         SUBB    A,#0A0H
         JNC     M_P
         MOV     PMWCON,32H     ;大火加热
         JMP     MOHURET
MINUS1:  MOV     A,5CH
         CLR     C
         SUBB    A,#0A0H
         JC      M_P
         MOV     PMWCON,#0DH     ;小火加热
         JMP     MOHURET
M_P:     MOV     PMWCON,#19H     ;中火加热
MOHURET: RET            
         
;*****************
;采用PID控制
;******************  
PIDCON:  PUSH    PSW
         PUSH    ACC    
         MOV     A,50H
         mov     b,#02h
         div     ab
         mov     b,#05h
         mul     ab
         mov     R1,a  ;将En乘以2.5
         
         MOV     A,52H
         mov     b,#02h
         div     ab
         mov     b,#07h
         mul     ab
         mov     R2,a  ;将En-1乘以3.5
         
         mov     a,r1
         add     a,54h      ;2.5En+En-2
         clr     c
         subb    a,r2        ;2.5En+(En-2)-3.5(En-1)
         mov     b,pid
         mul     ab
         mov     pmwcon,a
         ret
;*****************
;定时器0中断服务程序
;******************
TOIT:	PUSH PSW
	MOV PSW,#10H
	MOV TH0,#TIMEH
	MOV TL0,#TIMEL
        SETB P1.0
CONT1:	INC 5DH
        MOV A,5DH
        CJNE A,PMWCON,CONT1
        CLR P1.0
        MOV R7,5DH
	CJNE R7,#32H,TOIT1
	MOV 5DH,#00H
	SETB TIME1SOK
TOIT1:	POP PSW
	RETI
;***************
;LCD初始化
;**************
LCD_INIT:	MOV		A,#30H			;工作方式设置指令代码
 		MOV		DPTR,#CW_ADD		;指令口地址设置
		MOV		R2,#03H 		;循环量=3
		MOVX		@DPTR,	A               ;写指令代码
INIT1:		LCALL		DELAY
		DJNZ		R2,INIT1
		MOV		A,#38H			;设置8位总线工作方式
		MOVX		@DPTR,	A
		MOV		COM,#01H		;请屏
		LCALL	     	PR1
		MOV		COM,#06H		;设置输入方式
		LCALL	     	PR1
		MOV		COM,#0CH		;设置显示方式
		LCALL	     	PR1
		RET
;延迟
DELAY:		MOV		R6,#01H
DELAY2:		MOV		R5,#00H
DELAY1:	        NOP
		DJNZ		R5,DELAY1
		DJNZ		R6,DELAY2
		RET

;写指令代码
PR1:		PUSH		DPH
		PUSH		DPL
		PUSH		ACC
 		MOV		DPTR,#CR_ADD
PR11:		MOVX		A,@DPTR		;查询是否忙
		JB		ACC.7,PR11
		MOV		A,COM
		MOV		DPTR,#CW_ADD
		MOVX		@DPTR,A
		POP		ACC
		POP		DPL
		POP		DPH
		RET

;写显示数据
PR2:		PUSH		DPH
		PUSH		DPL
		PUSH		ACC
 		MOV		DPTR,#CR_ADD
PR21:		MOVX		A,@DPTR
		JB		ACC.7,PR21
		MOV		A,DAT
		MOV		DPTR,#DW_ADD
		MOVX		@DPTR,A
		POP		ACC
		POP		DPL
		POP		DPH
		RET
;*************
;DS18B20复位
;*************
RESET1820:

LA: 	SETB 	TEMPDIN
 	MOV 	R2,#200
LB: 	CLR 	TEMPDIN
 	DJNZ 	R2,LB		;等待600us
 	SETB 	TEMPDIN
 	MOV 	R2,#30
LC: 	DJNZ 	R2,LC		;等待60us
 	CLR	C
 	ORL 	C,TEMPDIN		;读ds18b20,存在脉冲低电平
 	JC 	LB
 	MOV 	R6,#80		;
LD: 	ORL 	C,TEMPDIN
 	JC 	LP
 	DJNZ 	R6,LD
 	SJMP 	LA
LP: 	MOV 	R2,#250
LF: 	DJNZ 	R2,LF
 	RET
;*****************
;DS18B20写时序
;****************
WRITE1820:
	MOV 	R3,#8
WR1A: 	SETB 	TEMPDIN
 	MOV 	R4,#8
 	RRC 	A
 	CLR 	TEMPDIN
WR2A: 	DJNZ 	R4,WR2A		;将总线控制拉低16us后对I/O线采样
 	MOV 	TEMPDIN,C
 	MOV 	R4,#30
WR3A: 	DJNZ 	R4,WR3A		;写时间保持60us
	DJNZ 	R3,WR1A
 	SETB 	TEMPDIN
 	RET
;******************
;DS18B20读时序
;********************
READ1820:
	CLR 	EA
 	MOV 	R6,#8
RD1A: 	CLR 	TEMPDIN		;将总线控制拉低2us后,再拉高,以读取I/O线数据
 	MOV 	R4,#6
 	NOP
 	SETB 	TEMPDIN
RD2A: 	DJNZ 	R4,RD2A
 	MOV 	C,TEMPDIN
 	RRC 	A
 	MOV 	R5,#30
RD3A: 	DJNZ 	R5,RD3A		;读时间保持60us
 	DJNZ 	R6,RD1A
 	SETB	TEMPDIN		;对I/O采样的结尾,将I/O引脚上拉
 	SETB 	EA

 	RET
;***************
;DS18B20温度转换
;***************

RDTEMP: LCALL 	RESET1820
 	MOV 	A,#0CCH
 	LCALL 	WRITE1820
 	MOV 	A,#44H
 	LCALL 	WRITE1820
 	LCALL 	DDELAY
 	LCALL 	RESET1820
 	MOV 	A,#0CCH
 	LCALL 	WRITE1820
 	MOV 	A,#0BEH
 	LCALL 	WRITE1820
 	LCALL 	READ1820
 	MOV 	TEMPL,A        
 	LCALL 	READ1820
 	MOV 	TEMPH,A
        MOV     58H,TEMPH
        MOV     57H,TEMPL
        MOV     5AH,TEMPH_ZAN
        MOV     59H,TEMPL_ZAN
        LCALL   QUCHA           ;取差En
        MOV     55H,53H         ;差值转存
        MOV     54H,52H
        MOV     53H,51H
        MOV     52H,50H
        MOV     51H,5CH
        MOV     50H,5BH
        MOV     TEMPL_ZAN,TEMPL
        MOV     TEMPH_ZAN,TEMPH
 	RET
;***************
;取差En
;***************        
QUCHA:  pUSH     ACC
        PUSH     PSW
        MOV     R1,58H
        MOV     R2,57H
        MOV     R3,5AH
        MOV     R4,59H
        MOV     A,R2
        CLR     C
        SUBB    A,R4
        MOV     5BH,A
        MOV     A,R1
        SUBB    A,R3
        MOV     5CH,A
        POP     PSW
        POP     ACC
        RET
        
        
;********************
;处理温度BCD码字程序
;********************
CONVTEMP:	MOV A,TEMPH			;比较高位温度值的符号位
		ANL A,#80H			;如果是正的,符号为零;负的,符号为1
		JZ TEMPC1
		CLR C
		MOV A,TEMPL
		CPL A
		ADD A,#01H
		MOV TEMPL,A
		MOV A,TEMPH
		CPL A
		ADDC A,#00H
		MOV TEMPH,A
		MOV TEMP_HH,#0BH
		SJMP TEMPC11
TEMPC1:		MOV TEMP_HH,#0AH			;测的是正温
TEMPC11:	MOV A,TEMP_HH
		SWAP A
		MOV TEMP_HH,A
		MOV A,TEMPL
		ANL A,#0FH
		RL A
		MOV R5,A
		MOV DPTR,#TEMPDOTTAB
		MOVC A,@A+DPTR
		MOV TEMP_LH,A
		MOV A,R5
		INC A
		MOVC A,@A+DPTR
		MOV TEMP_LL,A
		MOV A,TEMPL
		ANL A,#0F0H
		SWAP A
		MOV TEMPL,A
		MOV A,TEMPH
		ANL A,#0FH
		SWAP A
		ORL A,TEMPL
		LCALL HEX2BCD1
		MOV TEMPL,A
		ANL A,#0F0H
		SWAP A
		ORL A,TEMP_HH
		MOV TEMP_HH,A			;A2
		MOV A,TEMPL
		ANL A,#0FH
		SWAP A
		MOV TEMP_HL,#00H
		ORL A,TEMP_HL
		MOV TEMP_HL,A
		MOV A,R7
		JZ TEMPC12
		ANL A,#0FH
		SWAP A
		MOV R7,A
		MOV A,TEMP_HH
		ANL A,#0FH
		ORL A,R7
		MOV TEMP_HH,A
TEMPC12:	RET
;*******************
;小数分码表
;********************
TEMPDOTTAB:	DB 00H,00H
		DB 06H,25H
		DB 12H,50H
		DB 18H,75H
		DB 25H,00H
		DB 31H,25H
		DB 37H,50H
		DB 43H,75H
		DB 50H,00H
		DB 56H,25H
		DB 62H,50H
		DB 68H,75H
		DB 75H,00H
		DB 81H,25H
		DB 87H,50H
		DB 93H,75H

;********************
;单字节十六进制转BCD
;*********************
HEX2BCD1:	MOV B,#064H
		DIV AB
		MOV R7,A
		MOV A,#0AH
		XCH A,B
		DIV AB
		SWAP A
		ORL A,B
		RET

;***************************
;温度值解码子程序
;解码后放在数据缓冲区40H开始
;***************************
UNCODE:		MOV A,TEMP_LL				;小数四位最低位
		ANL A,#0FH
		MOV 46H,A
		MOV A,TEMP_LL				;小数四位次低位
		SWAP A
		ANL A,#0FH
		MOV 45H,A
		MOV A,TEMP_LH
		ANL A,#0FH
		MOV 44H,A
		MOV A,TEMP_LH
		SWAP A
		ANL A,#0FH
		MOV 43H,A
		MOV A,TEMP_HL				;个位
		SWAP A
		ANL A,#0FH
		MOV 42H,A
		MOV A,TEMP_HH				;十位
		ANL A,#0FH
		MOV 41H,A
		MOV A,TEMP_HH				;百位
		SWAP A
		ANL A,#0FH
		MOV BUFFER,A
		RET
;************************
;LCD显示子程序
;************************
DISPLAY1:	MOV		COM,#06H		;设置输入方式
		LCALL	     	PR1
		MOV		COM,#83H		;设置DDRAM地址
		LCALL	     	PR1
 		MOV		DPTR,#TABCR		;设置字表首地址
		MOV		R2,#0BH 		;循环量设置
		MOV		R3,#00H
CR_1:		MOV		A,R3
		MOVC		A,@A+DPTR
		MOV		DAT,A
		LCALL		PR2
		INC		R3
		LCALL		DELAY
		LCALL		DELAY
		LCALL		DELAY
		DJNZ		R2,CR_1
		RET

TABCR:		DB "TEMPERATURE"



DISPLAY2:	MOV		COM,#06H          ;设置输入方式
		LCALL		PR1               ;设置第二行DDRAM地址
		MOV		COM,#0C5H
		LCALL	     	PR1
		MOV		R1,#BUFFER
		MOV		A,@R1
		CJNE		A,#01H,DISLOOP
		ADD		A,#30H
		JMP		DISNEXT
	DISLOOP:ADD		A,#20H
 	DISNEXT:MOV 		DAT,A
 		LCALL		PR2
 		INC 		R1
 		MOV 		A,@R1
 		ADD 		A,#30H
 		MOV 		DAT,A
 		LCALL		PR2
 		INC 		R1
 		MOV 		A,@R1
 		ADD 		A,#30H
 		MOV 		DAT,A
 		LCALL		PR2
 		MOV		A,#2EH
 		MOV		DAT,A
 		LCALL		PR2
 		INC 		R1
 		MOV 		A,@R1
 		ADD 		A,#30H
 		MOV 		DAT,A
 		LCALL		PR2
 		INC		R1
 		MOV 		A,@R1
 		ADD 		A,#30H
 		MOV 		DAT,A
 		LCALL		PR2
 		INC		R1
 		MOV 		A,@R1
 		ADD 		A,#30H
 		MOV 		DAT,A
 		LCALL		PR2
 		INC		R1
 		MOV 		A,@R1
 		ADD 		A,#30H
 		MOV 		DAT,A
 		LCALL		PR2
		RET

DDELAY: MOV 	R7,#5
DL2: 	MOV 	R6,#100
DL1: 	MOV 	R5,#250
DL0: 	DJNZ 	R5,DL0
 	DJNZ 	R6,DL1
 	DJNZ 	R7,DL2
 	RET

 	END



⌨️ 快捷键说明

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