本帖最后由 daming 于 2014-12-30 23:28 編輯
電路圖和設計詳解見:http://www.zg4o1577.cn/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 ;程序結束
復制代碼
|