标题:
智能温度采集与控制系统源代码
[打印本页]
作者:
daming
时间:
2014-12-30 23:24
标题:
智能温度采集与控制系统源代码
本帖最后由 daming 于 2014-12-30 23:28 编辑
电路图和设计详解见:
http://www.51hei.com/bbs/dpj-29904-1.html
源程序代码如下:
;______________________________________________________________________________
K273 EQU 8100H ;加热器开关控制273芯片片选地址
DEVAD EQU 8302H ; A/D的IN1入口地址
Z8279 EQU 0FF82H ;8279 状态/命令口地址
D8279 EQU 0FF80H ;8279 数据口地址
LEDMOD EQU 00H ;8279工作方式设定:左边输入 八位字符显示
;外部译码键扫描方式,双键互锁
LEDFEQ EQU 2FH ;扫描速率
LEDCLS EQU 0C1H ;清除显示 RAM
LEDWR0 EQU 80H ;设定的将要写入的显示RAM地址
;______________________________________________________________________________
ORG 0000H
AJMP MAIN ;上电,转入主程序
ORG 000BH ;T0溢出中断入口地址
AJMP CLRLED ;转入LED清零重装初值中断服务程序
ORG 0030H
MAIN: ;主程序
MOV TMOD, #01H ;将T0设定为定时模式1
MOV TH0 , #4CH ;送初值
MOV TL0 , #00H
MOV 91H, #100 ;计时次数为100次,总定时5s
SETB P1.0 ;将加热指示灯打开显示正在加热
SETB EA ;CUP开中断
SETB ET0 ;T0中断允许
SETB TR0 ;启动定时
MOV 90H ,#0 ;送第一次比较温度,存在90单元地址里,以供下
;次比较
;(不能放在如01H里,这些被安排为R0—R7)
MOV SP, #60H ;设置堆栈,防止其地址为07H和R7等混了
LCALL INIT8279 ;初始化8279
AGAIN: ;要反复循环的程序段
LCALL H1 ;处理采进来的数据
LCALL AD_TEMP ;将处理的结果(电压值)对应为相应的温度
LCALL COMP_50 ;先和50(控制温度)比较
JC NEXT0 ;大于50度就转到相应的执行程序
AJMP NEXT3
NEXT0: JB P1.0 , NEXT1 ;正在加热否?是就执行停止加热程序
SJMP NEXT2 ;否则直接显示
NEXT1: LCALL STOP ;停止加热
NEXT2: LCALL DISP_LED ;并用LED显示出来温度
LCALL LOADAG ;再重装初值进行计时
AJMP AGAIN ;再来采样比较处理
NEXT3: LCALL COMP_TO_FOM ;不大于50度就和前一次温度比较大小
JB P1.0 ,AGAIN ;正在加热否?是就又转去重新开始采样
LCALL START ;没有正在加热就打开开关开始加热
SJMP AGAIN ;回到采样程序
ADIN: ;A/D采样子程序
MOV DPTR,#DEVAD ;送入A/D的通道1入口地址
MOVX @DPTR, A ;启动A/D开始采样
SETB P1.7 ;将A/D的EOC接入P1.7口,查询转换完成否?
JB P1.7,[ DISCUZ_CODE_1 ]nbsp; ;等待A/D转换完成
MOVX A ,@DPTR ;读转换结果
RET ;返回主调程序往下执行
STOP: ;加热器关子程序
CLR P1.0 ;加热指示灯灭
MOV DPTR,#K273 ;送入273片选地址
MOV A ,#10H ;将273的PO4口置1,关掉加热器
MOVX @DPTR,A ;关闭加热器
RET ;继续往下执行
START: ;加热器开子程序
SETB P1.0 ;加热指示灯亮
MOV DPTR,#K273 ;送入273片选地址
MOV A ,#00H ;将273的PO4口清零,打开加热器
MOVX @DPTR,A ;打开加热器
RET ;继续往下执行
LOADAG: ;重装定时器初值子程序
CLR TR0 ;先停止计时(防止有时未溢出又在重装初值)
MOV TH0 , #4CH ;初值高8位
MOV TL0 , #00H ;低8位
SETB TR0 ;再打开计时
RET ;返回主调往下执行
COMP_TO_FOM: ;当前温度和上一次比较子程序
MOV A , R6 ;当前温度送A中待比
CJNE A , 90H ,NEXT4;不相等(即为差1度以上)转NEXT4程序
SJMP NEXT5
NEXT4: LCALL DISP_LED ;显示于LED上
LCALL LOADAG ;重新装计数器初值
MOV 90H , A ;将新的温度存入90H单元地址中待和下次比较
NEXT5: RET ;返回继续执行下面程序
DISP_LED: ;LED显示子程序
LCALL B_TO_BCD ;将要显示的数据先转为BCD码
MOV A , R6
ANL A , #0FH ;先显示温度的个位
MOV R2 , A ;送给R2暂存
MOV R1 , #6 ;在第7个LED(即左起第二个)上显示个位数
PUSH DPH ;保存现场
PUSH DPL
PUSH ACC
MOV A , #LEDWR0 ;置显示起始地址
ADD A , R1 ;加上位置偏移量对应第7个LED
MOV DPTR, #Z8279
MOVX @DPTR,A ;显示在第7个LED上
MOV DPTR, #LEDSEG ;LED段码表
MOV A , R2 ;要查的数据个位数
MOVC A ,@A+DPTR ;查表
MOV DPTR,#D8279 ;8279数据口
MOVX @DPTR,A ;送出数据显示
MOV A , R6 ;显十位数字
SWAP A
ANL A , #0FH ;再显示温度的十位
MOV R2 , A ;送给R2暂存
MOV R1 , #7 ;在第8个LED(即左起第一个)上显示十位数
MOV A , #LEDWR0 ;置显示起始地址
ADD A , R1 ;加上位置偏移量对应第8个LED
MOV DPTR, #Z8279
MOVX @DPTR,A ;显示在第8个LED上
MOV DPTR, #LEDSEG ;LED段码表
MOV A , R2 ;要查的数据十位数
MOVC A ,@A+DPTR ;查表
MOV DPTR,#D8279 ;8279数据口
MOVX @DPTR,A ;送出数据显示
POP ACC ;恢复现场
POP DPL
POP DPH
RET
INIT8279: ;8279初始化子程序
PUSH DPH ;保存现场
PUSH DPL
PUSH ACC
LCALL DELAY ;延时
MOV DPTR ,#Z8279
MOV A,#LEDMOD ;置8279工作方式
MOVX @DPTR,A
MOV A,#LEDFEQ ;置键盘扫描速率
MOVX @DPTR,A
MOV A,#LEDCLS ;清除 LED 显示
MOVX @DPTR,A
LCALL DELAY ;延时
POP ACC ;恢复现场
POP DPL
POP DPH
RET
H1: ;A/D采入数据处理子程序,采入8次的数据再取平均
MOV R6 , #0 ;初始化采入总和SUM
MOV R5 , #0 ;初始化进位总和
MOV R4 , #8 ;初始化采样次数为8次
MOV R3 , #3 ;初始化移位次数为3次,相当于除以8
H2: LCALL ADIN ;采入数据,准备处理
ADD A , R6 ;将采入数据加到总和里
MOV R6 , A ;仍送回R6中保存
JNC H3 ;结果未溢出则转入判断采样是否已完程序
INC R5 ;溢出刚把溢出保存位R5加1
H3: DJNZ R4 , H2 ;采样次数未到则继续采样
H4: ;采样到了8次则进入取平均程序
CLR C ;将C清零
MOV A , R5 ;先将总和高8位R5内容右移1位,最高位用“0”填充
;移出位存入C中
RRC A
MOV R5 , A ;移完后仍存入R5中
MOV A , R6 ;再将总和低8位向右移1位,最高位用总和高8位移出位填充
;低位丢弃
RRC A
MOV R6 , A ;移完了仍存入R6中
DJNZ R3 , H4 ;除法运算是否已完?未完继续
RET ;完了返回主调程序继续往下执行
COMP_50: ;和50度比较子程序
CLR C ;将溢出位清零
MOV A ,#50 ;送比较温度
SUBB A ,R6 ;将当前温度减去50
RET ;返回往下执行
AD_TEMP: ;AD输出数字量对查表对应为温度子程序
ADD A ,#2 ;修正偏移地址,MOVC下两条指令加起来为2字节
MOVC A ,@A+PC ;查表
MOV R6 ,A ;查出的温度送入R6中存
RET
TEMP: ;A/D采出来的数据对就的温度表
DB 0 , 1 , 1 , 2 , 3 , 3 , 4 , 4 , 5 , 5 ;00H~09H对应的温度
DB 6 , 6 , 7 , 8 , 8 , 9 , 9 , 10 , 10 , 10 ;0AH~13H对应的温度
DB 11 , 11 , 12 , 12 , 13 , 13 , 14 , 14 , 14 , 15
DB 15 , 15 , 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19
DB 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22
DB 23 , 23 , 23 , 24 , 24 , 24 , 25 , 25 , 25 , 26
DB 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29
DB 29 , 30 , 30 , 30 , 31 , 31 , 31 , 31 , 32 , 32
DB 32 , 32 , 33 , 33 , 33 , 34 , 34 , 34 , 35 , 35
DB 35 , 35 , 35 , 36 , 36 , 36 , 37 , 37 , 37 , 37
DB 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40
DB 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43
DB 43 , 43 , 44 , 44 , 44 , 44 , 45 , 45 , 45 , 45
DB 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 48 , 48
DB 48 , 48 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50
DB 50 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52 , 53
DB 53 , 53 , 53 , 54 , 54 , 54 , 54 , 55 , 55 , 55
CLRLED: ;中断服务,清LED并重新计时
PUSH DPH ;保存现场
PUSH DPL
PUSH ACC
MOV DPTR,#Z8279
DJNZ 91H, RETURN ;计时到否?未到继续
MOV 91H, #100 ;到了重新装初值
MOV A ,#LEDCLS ;清LED
MOVX @DPTR,A
RETURN: LCALL LOADAG ;重装初值
POP ACC ;恢复现场
POP DPL
POP DPH
RETI ;返回中断
DELAY: ;延时子程序
PUSH 0 ;保存现场
PUSH 1
MOV 0 ,#0H
DELAY1: MOV 1 ,#0H
DJNZ 1 ,$
DJNZ 0 ,DELAY1
POP 1 ;恢复现场
POP 0
RET
B_TO_BCD: ;二进制转化BCD码子程序
MOV A , R6 ;将要转的数存入A中
MOV B , #10 ;温度不超过100故从10开始除以
DIV AB ;A存入十位数,B存个位数
SWAP A ;将A高低4字节交换
ADD A , B ;将B的个位加入A,A为BCD压缩码
MOV R6 , A ;仍存入R6中
RET ;返回调用程序往下执行
LEDSEG: ;LED段码表
DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H ;'0,1,2,3,4,5,6,7'
DB 7FH,6FH,77H,7CH,39H,5EH,79H,71H ;'8,9,A,B,C,D,E,F'
DB 6DH,02H,08H,00H,59H,0FH,76H ;'U,-,_, ,I,O,P, '
END ;程序结束
复制代码
作者:
j75748187
时间:
2015-3-30 23:55
支持一下
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1