基于51单片机的温度判别系统
是单片机课程作业
分享上来
其中具体实现的功能为:
按按键1时,会进行AD转换,将AD转换器所处位置的电压值读入。
读入方式为每隔0.5s读一次,共读6次 而后对该数据进行去极值平均滤波
而后对取平均后的数据进行判断
若为36、37度,则绿灯亮,38度则红灯亮,其余则红灯亮,同时蜂鸣器响
红 绿 黄分别为P1.0 P1.1 P1.2
按按键2、3时,会切换对应显示的温度
三个按键分别为 p1.5 p1.6 p1.7 并采用了外部中断0作为按键中断
会逐步更新代码的详解。
;DELAY 函数调用A的值,其中,对应单位为A*10ms
;0809首地址 0800H
;40H 41H保存了片外RAM的下次应当使用的地址
;42H-47H保存了每次按键采集的六次数据
; 寄存器分配
;R1 R2 R3 在延时中被使用
;R4 存储要显示的值
;R1 B 在BIN2BCD中被使用
;R7 在数据采集的循环中被使用
;R0 在片内寻址中使用
ORG 0000H
LJMP MAIN
ORG 0003H;INT0
SJMP JUDGEKEY
ORG 000BH
LJMP RING
ORG 0030H
MAIN:
;初始化
ACALL INIT
;等中断
AJMP LOOP
INIT:
;打开外部中断0(给按键用),设置中断优先级为最高,
SETB IT0;设置下降沿触发
SETB EX0;打开中断开关
SETB EA
CLR RS0 ;确保使用第0组工作寄存器
CLR RS1
MOV SP,#60H
MOV DPTR,#0100H;初始化DPTR,数据从0100H开始保存
MOV 40H,DPL
MOV 41H,DPH
RET
LOOP:
SJMP $
JUDGEKEY:
MOV A,#2H ;延迟20ms
ACALL DELAY
SETB P3.2
JB P3.2,ENDJUDGEKEY
JNB P1.5,GETDATA
JNB P1.6,UP
JNB P1.7,DOWN
ENDJUDGEKEY:
RETI
GETDATA:
;将数据读取并存放在RAM中
MOV R7,#06H
MOV R0,#42H
MOV DPL,40H
MOV DPH,41H
GETLOOP:
ACALL COLLECTDATA
MOV @R0,A
INC R0
MOV R4,A
LCALL SEND
MOV A,#32H
LCALL DELAY;延迟0.5s
DJNZ R7,GETLOOP;继续循环,直到读完六次
LCALL FILTER
MOVX @DPTR,A;将去极值均值滤波后数据存放在DPTR中
MOV R4,A
ACALL SEND
INC DPL ;这里通过对DPL的操作,在DPL达到FF后,虽然+1会进位,但不会影响到DPH,因此实现了指针的改变
MOV 40H,DPL
MOV 41H,DPH
ACALL JUDGE
RETI
COLLECTDATA:
;从0809上获得数据
PUSH DPL
PUSH DPH
MOV DPTR,#0800H
MOVX @DPTR,A
NOP
SETB P3.3
JB P3.3,$
MOVX A,@DPTR
POP DPH
POP DPL
RET
UP:
INC DPTR
MOVX A,@DPTR
MOV R4,A
MOV A,DPH
CJNE A,#01H,FLOW
ACALL SEND
RETI
DOWN:
MOV A,DPL
JNZ DPL_NOT_ZERO
DEC DPH
DPL_NOT_ZERO:
DEC DPL
MOVX A,@DPTR
MOV R4,A
MOV A,DPH
CJNE A,#01H,FLOW
ACALL SEND
RETI
FLOW:
;溢出后的异常处理
MOV P1.4,C
JNC MAX
MIN:
MOV R4,#00H
ACALL SEND
RETI
MAX:
MOV R4,#0FFH
ACALL SEND
RETI
BIN2BCD:
;将A中的值转为BCD存到A中
MOV B,#10
DIV AB
MOV R1,B ;把余数(个位)保存到R1
MOV B,#10H
MUL AB
ADD A,R1
RET
SEND:
;SEND及SOUT将R4中的内容以2位BCD码进行译码,发送至数码管
MOV TMOD,#20H ;定时器1设置为模式2
MOV TL1,#0F3H ;定时器初值
MOV TH1,#0F3H ;重装值
SETB TR1 ;启动定时器1
MOV SCON,#00H ;模式0 不接收
ACALL SOUT ;先输出一个字符
RET
SOUT:
PUSH DPL
PUSH DPH
MOV DPTR,#NUMTABLE;
MOV A,R4 ;把R4的值给A
MOV B,#10H ;给A除
DIV AB ;得到高位数在A中 低位在B中
MOVC A,@A+DPTR
MOV SBUF,A ;发送高位
JNB TI,$
CLR TI
MOV A,B
MOVC A,@A+DPTR
MOV SBUF,A ;发送低位
JNB TI,$ ;没发完就跳回来
CLR TI
POP DPH
POP DPL
RET
JUDGE: ;judge the number
D1: ; eqal to 36
CJNE R4,#36H,D2
SJMP GREEN
D2: ; eqal to 37
CJNE R4,#37H,D3
SJMP GREEN
D3: ; eqal to 38
CJNE R4,#38H,D4
SJMP YELLOW
D4: ;less than 36 or more than 38
SJMP RED
RED:
SETB P1.1
SETB P1.2
CLR P1.0
ACALL WARING
RET
GREEN:
SETB P1.0
SETB P1.2
CLR P1.1
CLR TR0;关掉蜂鸣器
RET
YELLOW:
SETB P1.0
SETB P1.1
CLR P1.2
CLR TR0;关掉蜂鸣器
RET
DELAY: ;
MOV R3,A ;
DEL2:MOV R2,#028H ;
DEL1:MOV R1,#0FFH ;
DJNZ R1,$ ;2??
DJNZ R2,DEL1 ;2??
DJNZ R3,DEL2 ;2??
RET
WARING: ;
MOV TMOD , #01H ;
MOV TH0 , #0FFH
MOV TL0 , #0FFH ;
SETB ET0 ;
SETB EA ;
SETB TR0 ;
RET
RING:
CPL P1.3 ;P1.3
MOV TH0 , #0FFH
MOV TL0 , #024H ;
RETI
FILTER:
;R6 R7 作为保存最小值和最大值的寄存器
;R2 R3 作为保存加和结果的寄存器,R2低,R3高
SETB RS0
MOV R0,#42H
MOV R4,#06H ;循环6次
MOV R2,#00H
MOV R3,#00H
MOV A,@R0
MOV R6,A
MOV A,@R0
MOV R7,A
FILTERLOOP:
FINDMIN:
MOV A,R6
MOV B,@R0
CJNE A,B,JUDGEMIN
AJMP FINDMAX
JUDGEMIN:
JNC FINDMAX ;若小于则不跳,R6 <-@R0
MOV A,@R0
MOV R6,A
FINDMAX:
MOV A,R6
MOV B,@R0
CJNE A,B,JUDGEMAX
AJMP MAKESUM
JUDGEMAX:
JC MAKESUM ;若大于则不跳,R7 <-@R0
MOV A,@R0
MOV R7,A
MAKESUM:
;把数值加进去
MOV A,@R0
ACALL SUM
INC R0
DJNZ R4,FILTERLOOP;继续循环,直到读完六次
MOV A,R6 ;减掉极值
ACALL SUB
MOV A,R7
ACALL SUB
ACALL DIV4 ;把R2 R3的值除4存到A中
CLR RS0
RET
SUM:
;把A中的值加在R2 R3中
ADD A,R2
MOV R2,A
MOV A,R3
ADDC A,#00H
MOV R3,A
RET
SUB:
;把R2 R3减去A中的值
CLR C
MOV B,A
MOV A,R2
MOV R2,B
SUBB A,R2
MOV R2,A
MOV A,R3
SUBB A,#00H
MOV R3,A
RET
DIV4:
;除4
MOV R4,#2 ;循环两次
DIV4LOOP:
CLR C
MOV A,R3
RRC A
MOV R3,A
MOV A,R2
RRC A
MOV R2,A
DJNZ R4,DIV4LOOP
RET
NUMTABLE:
DB 00000011B,10011111B,00100101B,00001101B
DB 10011001B,01001001B,01000001B,00011111B
DB 00000001B,00001001B,00010001B,00000001B
DB 01100011B,00000011B,01100001B,01110001B
END