電風扇定時時間60分鐘覺得短了些,如果一直開的話,吹到天亮人也難受,能定時個三四小時比較合適,手頭上有若干閑置了十余年的STC89C51RC,所以就用它來制作個長定時器,使用EC11帶開關旋轉編碼器調時間,很便宜,一塊多錢一只還包郵,也可以用按鍵代替編碼器,只是調時間的時候不如編碼器那么方便快捷,顯示用TM1637四位數碼管顯示模塊,3塊錢包郵,便宜又好用,它能顯示到99小時,所以最長定時可達99小時59分59秒,雖然實際使用不需要那么長的定時。制作好后不對電風扇作任何改動,只是把雙向可控硅的T1、T2分別與原定時器那兩根線接好就可以了,也就是與原定時器并聯,把原定時器調到OFF位置。單片機改用其他型號的話,需要改動一些地方,如EEPROM操作、扇區地址、數量、特殊功能寄存器地址、看門狗預分頻數等等.
電路原理圖如下:
電路接線圖.JPG (89.95 KB, 下載次數: 106)
下載附件
2020-7-10 23:37 上傳
單片機源程序如下:
- ;===================================================================================
- ;TM1637顯示模塊,EC11編碼器,電風扇長定時+自然風匯編程序
- ;楊小強,2020年6月
- ;單片機:STC89C51RC,晶振:11.0592MHz
- ;顯示:(TM1637)4位數碼管顯示模塊
- ;調整、設置:EC11帶開關5腳旋轉編碼器,也可以用按鍵代替
- ;電源:閑置5V手機充電器
- ;
- ;最長定時99小時59分59秒,簡單的采用間歇通/斷電方式模擬自然風,周期可調,用可控硅控制通斷。
- ;
- ;按編碼器開關1次:正常/自然風切換,自然風狀態時LED指示燈亮,可控硅間歇通斷電
- ;按編碼器開關2次:定時時間清零,風扇電機斷電,兩次按鍵動作之間不大于0.6秒
- ;
- ;長按編碼器開關5秒以上15秒以內,松開按鍵后進入設置狀態,退出設置狀態:設置完第五項后按編碼器開關、或任意一
- ;項中停15秒無任何操作,就自動保存并退出。根據數碼管左邊顯示的數字進行以下各項設置,通過旋轉編碼器加或減,
- ;按編碼器開關進入下一項設置:
- ;一、顯示1——設置自然風狀態時,通斷電周期時長,5~30秒,默認為10秒
- ;二、顯示2——設置自然風時電機通電時長,最短為2秒;最長為上一項所設的周期減3秒,比如上一項設置的周期為10秒,
- ; 則本項最多可以設置到7秒;
- ;三、顯示3——設置3小時以下定時調整時,編碼器每轉動一格的增(減)值:5、10、15、20、25、30分鐘,默認10分鐘,
- ; 3小時以上增(減)值30分鐘;10小時以上增(減)值1個小時;20小時以上增(減)值2個小時
- ;四、顯示4——設置電風扇插電就自動填入的定時時間,0~30小時,默認8小時
- ;五、顯示5——設置數碼管亮度,1~8級,默認為3級
- ;
- ;長按編碼器開關15秒:恢復各項默認設置,數碼管顯示88:88
- ;
- ;設置保存失敗顯示5秒E1
- ;
- ;--------------------------- 端口定義 ---------------------------
- CLK EQU P1.5 ;接顯示模塊TM1637的CLK
- DIO EQU P1.6 ;接顯示模塊TM1637的DIO
- EC11A EQU P3.2 ;接編碼器的A引腳,外部中斷INT0,也可以接一個按鍵代替
- EC11B EQU P3.3 ;接編碼器的B引腳,外部中斷INT1,也可以接一個按鍵代替
- EC11K EQU P3.4 ;接編碼器的按鍵開關引腳
- RLED EQU P0.4 ;只要發生過復位就一直保持低電平,如有需要可接上LED方便觀察
- LED EQU P0.5 ;自然風狀態LED指示燈,低電平亮
- MOC EQU P0.7 ;接MOC3022光控可控硅,低電平時風扇電機通電
- ;--------------------------- 位地址及RAM的使用 ---------------------------
- ;(20H)第0位:1=編碼器已經轉動,等待主程序處理,0=沒有轉動或主程序已處理
- ;(20H)第1位:1=編碼器順時針正轉;0=編碼器逆時針反轉
- ;(20H)第2位:1=自然風狀態;0=正常狀態
- ;(20H)第3位:1=禁止;0=允許。進行各項設置時使用,允許/禁止檢查剩余時間
- ;(20H)第4位:1=閃爍顯示;0=不閃爍。進行各項設置時用
- ;(20H)第5位:1=不顯示,0=顯示,數字及冒號閃爍時用,由T0中斷每0.5秒取反一次
- ;(20H)第6位:1=顯示3秒88:88;0=正常
- ;(20H)第7位:1=顯示5秒E1;0=正常
- FWBZ1 EQU 022H ;復位判斷標志1,也作EEPROM數據判斷標志
- FWBZ2 EQU 023H ;復位判斷標志2,也作EEPROM數據判斷標志
- ZRFZQ EQU 024H ;自然風時通斷電周期時長
- ZRFSJ EQU 025H ;自然風時電機通電時長
- BMQZJ EQU 026H ;編碼器每轉動一小格的增(減)值
- SDDS EQU 027H ;上電就自動設定的定時時間(小時)
- SMGLD EQU 028H ;數碼管亮度
- DSSJS EQU 029H ;定時時間,時
- DSSJF EQU 02AH ;定時時間,分
- DSSJM EQU 02BH ;定時時間,秒
- ZQ EQU 02CH ;T0中斷使用,自然風通斷電周期時長
- SJ EQU 02DH ;T0中斷使用,自然風時電機通電時長
- SJJS EQU 02EH ;時間計數,每10毫秒減1,為0后定時時間減1秒,重新把HMJS處定義的計數值放入這里
- MJS EQU 02FH ;按鍵處理時用,秒計數,每秒減1,直到為0
- SSSC EQU 030H ;閃爍時長,每秒減1,直到為0
- XSHC1 EQU 031H ;上次顯示的內容,與當前不同就立即顯示,相同就每0.5秒顯示一次
- XSHC2 EQU 032H ;上次顯示的內容,與當前不同就立即顯示,相同就每0.5秒顯示一次
- XXSZ EQU 033H ;下限數值,進行各項設置時用
- SXSZ EQU 034H ;上限數值,進行各項設置時用
- ZXM1 EQU 035H ;顯示用,待發送到TM1637的字形碼1
- ZXM2 EQU 036H ;顯示用,待發送到TM1637的字形碼2
- ZXM3 EQU 037H ;顯示用,待發送到TM1637的字形碼3
- ZXM4 EQU 038H ;顯示用,待發送到TM1637的字形碼4
- DSZJ EQU 039H ;加減定時時間使用
- DISPL EQU 03AH ;設置要顯示的目標:
- ;0=顯示定時時間
- ;1=顯示1——設置自然風狀態時的通斷電周期時長
- ;2=顯示2——設置自然風時電機通電時長
- ;3=顯示3——設置3小時以下定時調整時,編碼器每轉動一小格的增(減)值
- ;4=顯示4——設置上電自動填入的定時時間
- ;5=顯示5——設置數碼管亮度
- ;--------------- 看門狗、EEPROM特殊功能寄存器地址 ---------------
- AUXR EQU 08EH ;輔助寄存器
- WDT_CONTR EQU 0E1H ;看門狗地址
- IAP_DATA EQU 0E2H ;數據寄存器,讀出、寫入的數據放在此處
- IAP_ADDRH EQU 0E3H ;地址寄存器高八位
- IAP_ADDRL EQU 0E4H ;地址寄存器低八位
- IAP_CMD EQU 0E5H ;命令寄存器,0=關閉,1=讀,2=寫,3=擦除
- IAP_TRIG EQU 0E6H ;命令觸發寄存器,每次操作先放入46H再放入B9,命令立即被觸發起動
- IAP_CONTR EQU 0E7H ;控制寄存器,Flash操作允許/禁止及等待時間
- ENABLE_IAP EQU 083H ;定義Flash操作等待時間及允許IAP/ISP/EEPROM操作的常數,時鐘<12MHz時為83H
- ;==========================================================================
- ORG 0000H
- LJMP START
- ORG 0003H ;外部中斷INT0入口
- LJMP INT_0 ;外部中斷INT0入口
- ORG 000BH ;T0中斷入口
- LJMP T0INT ;T0中斷入口
- ORG 0013H ;外部中斷INT1入口
- LJMP INT_1 ;外部中斷INT1入口
- ORG 0030H ;程序代碼始址安排在30H
- ;------------------------------------------------------------------------------------------------
- ;定義時間計數值,當定時時間實際走時誤差較大時,可調整此數值使誤差減小
- ;例如每分鐘快7秒,就把此數值改為112D(7秒÷60秒×100≈12,12+100=112);每分鐘慢6秒,就
- ;把此數值改為90D(6秒÷60秒×100=10,100-10=90)
- ;------------------------------------------------------------------------------------------------
- HMJS: DB 100D ;定義時間計數值,100表示100×10毫秒=1秒,后面的D表示是十進制數
- ;--------------- 定時器0中斷(10毫秒產生一次中斷) ---------------
- T0INT: PUSH ACC
- PUSH PSW
- LCALL TIME ;處理各項時間
- LCALL Control ;根據條件控制自然風LED指示燈和可控硅(或繼電器)
- LCALL DISPLAY ;顯示
- POP PSW
- POP ACC
- RETI
- ;--------------- 外部中斷INT0,P3.2接編碼器A引腳 ---------------
- INT_0: PUSH PSW
- JB 00H,INT0_1 ;如果位地址0H為1就退出中斷處理程序,等待主程序處理
- SETB 00H ;把位地址00H置為1,表示編碼器已轉動,等待主程序處理
- SETB 01H ;是順時針正轉,把位地址01H置為1
- INT0_1: POP PSW
- RETI
- ;--------------- 外部中斷INT1,P3.3接編碼器B引腳 ---------------
- INT_1: PUSH PSW
- JB 00H,INT1_1 ;如果位地址0H為1就退出中斷處理程序,等待主程序處理
- SETB 00H ;把位地址00H置為1,表示編碼器已轉動,等待主程序處理
- CLR 01H ;是逆時針反轉,把位地址01H置為0
- INT1_1: POP PSW
- RETI
- ;--------------- 設置各項默認值 ----------------
- SZMRZ: MOV ZRFZQ,#10 ;自然風狀態時,通斷電周期時長(秒)
- MOV ZRFSJ,#5 ;自然風時電機通電時長(秒)
- MOV BMQZJ,#10 ;編碼器每轉動一小格的+、-值(分鐘))
- MOV SDDS,#8 ;上電就自動設定的定時時間(小時)
- MOV SMGLD,#3 ;數碼管亮度,8級亮度最高
- RET
- ;--------------- T0、INT0、INT1中斷設置 ----------------
- SETINT: ANL AUXR,#7FH ;定時器時鐘12T模式
- ANL TMOD,#0F0H ;設置定時器模式
- MOV TL0,#000H ;設置定時初值,10毫秒產生一次中斷(晶振:11.0592MHz)
- MOV TH0,#0DCH ;設置定時初值,10毫秒產生一次中斷(晶振:11.0592MHz)
- CLR TF0 ;清除TF0標志
- SETB ET0 ;允許定時器0中斷
- SETB TR0 ;定時器0開始計時
- SETB IT0 ;設外部中斷INT0為下降沿觸發
- SETB EX0 ;允許外部中斷INT0
- SETB IT1 ;設外部中斷INT1為下降沿觸發
- SETB EX1 ;允許外部中斷INT1
- SETB EA ;允許全局中斷
- RET
- ;--------------- 啟動看門狗及喂狗,11.0592MHz預分頻數=4(142.2毫秒),00111001B(39H) ----------------
- WG: MOV WDT_CONTR,#00111001B
- RET
- ;******************************************** 主程序開始 ********************************************
- START: MOV SP,#050H ;設置堆棧指針
- MOV A,FWBZ1 ;
- CJNE A,#0C8H,START0 ;
- MOV A,FWBZ2 ;檢查復位判斷標志,不相同說明是初次上電,從初始化開始運行
- CJNE A,#0D9H,START0 ;
- LCALL SETINT ;中斷設置
- CLR RLED ;RAM內容沒變,說明是被干擾等原因復位,不是初次上電,點亮復位LED指示燈
- MOV A,DISPL ;
- CJNE A,#5,SAT1 ;不管是什么原因復位,只要RAM不被改變就跳過初始化,繼續運行
- LJMP STARTB ;
- SAT1: CJNE A,#4,SAT2 ;
- LJMP STARTA ;
- SAT2: CJNE A,#3,SAT3 ;根據DISPL的內容跳轉到復位前的位置
- LJMP START9 ;
- SAT3: CJNE A,#2,SAT4 ;
- LJMP START8 ;
- SAT4: CJNE A,#1,START2 ;
- LJMP START7 ;
- START0: CLR A
- MOV R0,#30H ;
- MOV R1,#20H ;
- START1: MOV @R1,A ;初始化,從RAM地址20H開始清零30H個字節
- INC R1 ;
- DJNZ R0,START1 ;
- LCALL SETINT ;初始化,中斷設置
- MOV FWBZ1,#0C8H ;初始化,放入復位判斷標志1到RAM
- MOV FWBZ2,#0D9H ;初始化,放入復位判斷標志2到RAM
- LCALL REEP ;初始化,讀EEPROM保存的各項設置,如果沒有就設為默認值并保存
- SETB RLED ;初始化,設RLED為高電平,復位LED指示燈不亮
- ;
- START2: LCALL WG ;喂狗
- MOV DISPL,#0 ;設置要顯示的目標,0=顯示定時時間
- CLR 06H ;位地址06H置為0,顯示定時時間
- CLR 07H ;位地址07H置為0,顯示定時時間
- JNB 00H,START3 ;如果位地址00H為0(編碼器沒有轉動)就轉移
- SETB EC11A ;拉高編碼器A引腳電平
- SETB EC11B ;拉高編碼器B引腳電平
- JNB EC11A,START3 ;如果仍為0(低電平)就轉移,說明還沒有旋轉到卡點位置
- JNB EC11B,START3 ;如果仍為0(低電平)就轉移,說明還沒有旋轉到卡點位置
- LCALL DSSJZJ ;AB引腳都為高電平了,已經旋轉到卡點位置,根據方向增減定時時間
- CLR 00H ;把位地址00H置為0,表示已經響應并處理編碼器旋轉動作
- START3: LCALL SKEY ;掃描編碼器按鍵開關
- JNC START2 ;沒有按鍵動作(C=0)就轉移
- LCALL KEY ;有按鍵動作,調用編碼器按鍵開關處理子程序
- CJNE A,#1,START4 ;如果不是按下1次(正常/自然風切換)就轉移
- CPL 02H ;是按1次,位地址第02位取反,自然風/正常狀態切換
- LJMP START2
- START4: CJNE A,#2,START5 ;如果不是2(定時時間置為零)就轉移
- LCALL DSSJQL ;是按2次,定時時間清零
- LJMP START2
- START5: CJNE A,#3,START7 ;如果不是3(恢復默認設置)就轉移
- LCALL SZMRZ ;恢復各項默認設置
- SETB 06H ;把位地址06H設置為1,數碼管顯示3秒88:88
- MOV SSSC,#3 ;3秒
- MOV ZXM1,#0FFH ;8
- MOV ZXM2,#0FFH ;8
- MOV ZXM3,#0FFH ;8
- MOV ZXM4,#0FFH ;8
- LCALL DISP ;顯示
- START6: MOV A,SSSC
- LCALL WG ;喂狗
- JNZ START6 ;等待SSSC為0秒
- LCALL WSET ;保存設置
- LCALL KEYEX ;等待按鍵松開
- LJMP START2
- START7: MOV DISPL,#1 ;是4,進入各項設置,1=顯示“1——設置自然風狀態時通斷電周期時長”
- LCALL ZQSZ ;周期時長設置
- JNZ START8 ;如果是按下編碼器按鍵開關返回,就轉移,進行下一項設置
- LJMP START2 ;是15秒無操作自動保存返回,設置結束
- START8: MOV DISPL,#2 ;2=顯示“2——設置自然風時電機通電時長”
- LCALL TDSC ;通電時長設置
- JNZ START9 ;如果是按下編碼器按鍵開關返回,就轉移,進行下一項設置
- LJMP START2 ;是15秒無操作自動保存返回,設置結束
- START9: MOV DISPL,#3 ;3=顯示“3——設置2小時以下定時調整時,編碼器每轉動一格的增(減)值”
- LCALL BMQZJZ ;編碼器增減值設置
- JNZ STARTA ;如果是按下編碼器按鍵開關返回,就轉移,進行下一項設置
- LJMP START2 ;是15秒無操作自動保存返回,設置結束
- STARTA: MOV DISPL,#4 ;4=顯示“4——設置插電自動填入的定時時間”
- LCALL SDDSSJ ;上電定時時間設置(小時)
- JNZ STARTB ;如果是按下編碼器按鍵開關返回,就轉移,進行下一項設置
- LJMP START2 ;是15秒無操作自動保存返回,設置結束
- STARTB: MOV DISPL,#5 ;5=顯示“5——設置數碼管亮度”
- LCALL LDSZ ;亮度設置
- LJMP START2
- ;--------------------------------------------------------------------------------------------------------
- ;子程序:根據編碼器旋轉方向加減定時時間。
- ;3小時及以下,按設置的值加減:5、10、15、20、25、30分鐘
- ;3小時以上每次增(減)30分鐘;10小時以上每次增(減)1個小時;20小時以上每次增(減)2個小時
- ;--------------------------------------------------------------------------------------------------------
- DSSJZJ: MOV DSSJM,#59 ;先放入59到定時時間(秒)
- MOV A,DSSJS ;裝入定時時間(時)
- CJNE A,#20,DSZJ1 ;當前“時”是否等于或大于20
- DSZJ1: JC DSZJ2 ;小于就轉移
- MOV DSZJ,#2 ;等于或大于20,加減2個小時
- LJMP DSZJ4
- DSZJ2: CJNE A,#10,DSZJ3 ;當前“時”是否等于或大于10
- DSZJ3: JC DSZJ8 ;小于就轉移
- MOV DSZJ,#1 ;等于或大于10,加減1個小時
- DSZJ4: JNB 01H,DSZJ6 ;如果位地址01H為0(逆時針反轉)就轉移
- ADD A,DSZJ ;是正轉,加
- CJNE A,#100,DSZJ5 ;加完后是否等于或大于100
- DSZJ5: JC DSZJ7 ;如果小于就轉移,把A放回到DSSJS
- MOV DSSJS,#99 ;已經大于99了,直接設置為99:59:59
- MOV DSSJF,#59 ;已經大于99了,直接設置為99:59:59
- RET
- DSZJ6: SUBB A,DSZJ ;是反轉,減
- DSZJ7: MOV DSSJS,A ;把計算結果放入DSSJS
- RET
- DSZJ8: MOV DSZJ,BMQZJ ;把設置的“增(減)值”放入DSZJ
- CJNE A,#3,DSZJ11 ;當前“時”不是3就轉移
- JB 01H,DSZJ12 ;是3,如果位地址01H為1(正轉)就轉移,把DSZJ處的“增(減)值”改為30(分鐘)
- MOV A,DSSJF ;是反轉,裝入定時時間(分)
- JZ DSZJ13 ;如果當前“分”為0(3:00)就轉移,按設置的增(減)值減
- CJNE A,#30,DSZJ9 ;“分”不為0,是否等于或大于30
- DSZJ9: JC DSZJ10 ;小于就轉移,把0放入定時時間(分),使時間變為3:00
- SUBB A,#30 ;等于或大于,減30分
- MOV DSSJF,A ;把計算結果放入定時時間(分)
- RET
- DSZJ10: MOV DSSJF,#0 ;小于30,把0放入定時時間(分),使時間變為3:00
- RET
- DSZJ11: JC DSZJ13 ;小于3就轉移
- DSZJ12: MOV DSZJ,#30 ;大于3:00,把DSZJ處的“增(減)值”改為30(分鐘)
- DSZJ13: MOV A,DSSJF ;裝入定時時間(分)
- JNB 01H,DSZJ16 ;如果位地址01H為0(逆時針反轉)就轉移
- ADD A,DSZJ ;是正轉,當前“分”直接加DSZJ處的“增(減)值”
- CJNE A,#60,DSZJ14 ;加完后“分”是否等于或大于60
- DSZJ14: JC DSZJ15 ;小于60就轉移,把A放入定時時間(分)
- SUBB A,#60 ;等于或大于60,就減60,然后小時加1
- MOV DSSJF,A ;把A放入定時時間(分)
- MOV A,DSSJS ;裝入“時”
- INC A ;小時加1
- MOV DSSJS,A
- CJNE A,#3,DSZJ19 ;加完后“時”不是3就轉移,退出
- CLR A ;加完后大于3:00了,把0放入定時時間(分),使時間變為3:00
- DSZJ15: MOV DSSJF,A
- RET
- DSZJ16: CJNE A,DSZJ,DSZJ17 ;是逆時針反轉,當前“分”是否等于或大于DSZJ處的“增(減)值”
- DSZJ17: JC DSZJ20 ;小于就轉移
- SUBB A,DSZJ ;等于或大于,定時時間(分)減“增(減)值”
- MOV DSSJF,A ;把計算結果放入定時時間(分)
- JZ DSZJ18 ;如果“分”為0就轉移
- RET
- DSZJ18: CJNE A,DSSJS,DSZJ19 ;如果“時”不為0就轉移
- MOV DSSJM,A ;“時、分”都為0,“秒”也清零
- DSZJ19: RET
- DSZJ20: MOV A,DSZJ ;“分”小于“增(減)值”,裝入DSZJ處的“增(減)值”
- CLR C ;進位標志清0
- SUBB A,DSSJF ;“增(減)值”減“定時時間(分)”
- MOV DSSJF,A ;減完后的結果暫時放入DSSJF
- MOV A,#60
- SUBB A,DSSJF ;60減上面的計算結果,得出定時時間(分),然后小時減1
- MOV DSSJF,A ;得出的數放入定時時間(分)
- MOV A,DSSJS ;裝入定時時間(時)
- JZ DSSJQL ;如果“時”為0就轉移(不夠減了,把定時時間清零)
- DEC DSSJS ;“時”不為0,減1
- RET
- DSSJQL: CLR A
- MOV DSSJS,A ;定時時間清零
- MOV DSSJF,A ;定時時間清零
- MOV DSSJM,A ;定時時間清零
- RET
- ;----------------------------------------------------------------------------------------
- ;設置自然風通斷電周期時長,5~30秒
- ;----------------------------------------------------------------------------------------
- ZQSZ: MOV XXSZ,#5 ;下限為5秒
- MOV SXSZ,#30 ;上限為30秒
- LJMP LDSZ1
- ;----------------------------------------------------------------------------------------
- ;設置自然風時電機通電時長,最短為2秒;最長為上一項(自然風通斷電周期)所設的周期減3秒
- ;----------------------------------------------------------------------------------------
- TDSC: MOV A,ZRFZQ ;裝入“自然風通斷電周期”
- SUBB A,#3 ;減3秒
- MOV SXSZ,A ;放入上限值
- MOV XXSZ,#2 ;下限為2秒
- LJMP LDSZ1
- ;----------------------------------------------------------------------------------------
- ;設置2小時以下定時調整時,編碼器每轉動一小格的增(減)值,5、10、15、20、25、30分鐘
- ;----------------------------------------------------------------------------------------
- BMQZJZ: MOV XXSZ,#5 ;下限為5
- MOV SXSZ,#30 ;上限為30
- MOV R4,#5 ;調整時的加減步長值
- LJMP SZTZ
- ;----------------------------------------------------------------------------------------
- ;設置插電就自動填入的定時時間,0~30小時
- ;----------------------------------------------------------------------------------------
- SDDSSJ: MOV XXSZ,#0 ;下限為0小時
- MOV SXSZ,#30 ;上限為30小時
- LJMP LDSZ1
- ;----------------------------------------------------------------------------------------
- ;設置數碼管亮度,1~8級,8級亮度最高
- ;----------------------------------------------------------------------------------------
- LDSZ: MOV XXSZ,#1 ;下限為1
- MOV SXSZ,#8 ;上限為8
- LDSZ1: MOV R4,#1 ;調整時的加減步長值
- LJMP SZTZ
- ;----------------------------------------------------------------------------------------
- ;子程序:根據XXSZ、SXSZ設定的上下限范圍、編碼器旋轉方向,調整DISPL指向的對象。
- ;無操作10秒后開始閃爍顯示,15秒自動保存并退出;有按鍵動作就保存并退出
- ;入口參數:下限值放入XXSZ;上限值放入SXSZ;R4=加、減步長值
- ;出口參數:15秒無操作自動保存退出A=0;按編碼器按鍵開關保存退出A=1
- ;----------------------------------------------------------------------------------------
- SZTZ: MOV MJS,#15 ;放入15秒
- CLR 03H ;位地址03H置為0,允許檢查剩余時間
- SZTZ1: LCALL SKEY ;掃描編碼器按鍵開關
- JNC SZTZ2 ;沒有按鍵動作(C=0)就轉移
- CLR 04H ;有按鍵動作,把位地址04H置為0,不閃爍顯示
- LCALL WSET ;保存設置
- LCALL KEYEX ;等待按鍵松開
- LCALL SKEY1 ;延時10毫秒
- LCALL SKEY1 ;
- LCALL SKEY1 ;共延時30毫秒
- MOV A,#1 ;按編碼器按鍵開關保存退出A=1
- RET
- SZTZ2: JB 00H,SZTZ4 ;如果位地址00H為1(編碼器已經轉動)就轉移
- MOV A,MJS ;沒有轉動,裝入秒計數到寄存器A
- JZ SZTZ3 ;如果秒計數為0(15秒無操作)就轉移
- JB 03H,SZTZ1 ;不為0,如果位地址03H為1就轉移,不檢查剩余時間
- CJNE A,#5,SZTZ1 ;檢查剩余時間,如果不是5秒就轉移,繼續掃描編碼器
- SETB 04H ;還剩5秒,把位地址04H置為1,設置為閃爍顯示
- MOV SSSC,A ;閃爍時長5秒放入SSSC
- SETB 03H ;位地址03H置為1,禁止檢查剩余時間
- LJMP SZTZ1
- SZTZ3: CLR 04H ;15秒時間到,把位地址04H置為0,不閃爍顯示
- LCALL WSET ;保存設置
- CLR A ;15秒無操作自動保存退出A=0
- RET
- SZTZ4: CLR 04H ;編碼器已經轉動,把位地址04H置為0,不閃爍顯示
- SETB EC11A ;拉高編碼器A引腳電平
- SETB EC11B ;拉高編碼器B引腳電平
- JNB EC11A,SZTZ ;如果仍為0(低電平)就轉移,說明還沒有旋轉到卡點位置
- JNB EC11B,SZTZ ;如果仍為0(低電平)就轉移,說明還沒有旋轉到卡點位置
- MOV A,DISPL ;AB引腳都為高電平,已經旋轉到卡點位置了,裝入要設置的目標項
- DEC A ;減1
- ADD A,#ZRFZQ ;加上各項設置的起始地址
- MOV R0,A ;把得出的具體地址放入R0
- JB 01H,SZTZ7 ;如果位地址01H為1(順時針正轉)就轉移
- MOV A,XXSZ ;是反轉,裝入下限數值到A寄存器
- ADD A,R4 ;加步長值
- MOV MJS,A ;把下限值+步長值的結果暫時放入MJS
- MOV A,@R0 ;裝入R0指向的RAM地址的調整對象數值
- CJNE A,MJS,SZTZ5 ;調整對象數值與“下限值+步長值”比較
- SZTZ5: JC SZTZ6 ;如果調整對象數值小于“下限值+步長值”(不夠減)就轉移
- SUBB A,R4 ;等于或大于,減步長值
- MOV @R0,A ;把計算結果放回去
- LJMP SZTZ10
- SZTZ6: MOV @R0,XXSZ ;不夠減了,直接放入下限值
- LJMP SZTZ10
- SZTZ7: MOV A,@R0 ;是正轉,裝入R0指向的RAM地址的調整對象數值
- ADD A,R4 ;加步長值
- CJNE A,SXSZ,SZTZ8 ;加完后與上限數值比較
- SZTZ8: JC SZTZ9 ;如果小于就轉移
- MOV @R0,SXSZ ;等于或大于,直接放入上限值
- LJMP SZTZ10
- SZTZ9: MOV @R0,A ;小于上限數值,把計算結果放回去
- SZTZ10: CLR 00H ;把位地址00H置為0,表示已經處理編碼器旋轉動作
- LJMP SZTZ
- ;----------------------------------------------------------------------------------------
- ;子程序:編碼器按鍵開關處理
- ;出口參數:A=1(按了1次);A=2(按了2次);A=3長按達到了15秒;A=4長按達到了5秒
- ;----------------------------------------------------------------------------------------
- KEY: MOV MJS,#15 ;放入等待時間,15秒
- KEY1: MOV A,MJS ;裝入等待時間
- JNZ KEY2 ;如果不為0就轉移,時間未到
- MOV A,#3 ;為0,時間到了,放入3到A寄存器,長按達到了15秒
- RET
- KEY2: LCALL SKEY ;掃描按鍵
- JC KEY1 ;如果C=1(按鍵還沒松開),就繼續掃描
- CJNE A,#10,KEY3 ;按鍵松開了,剩余時間與10比較,不等于就轉移
- LJMP KEY4 ;等于10,長按時間達到了5秒(15-10=5)
- KEY3: JNC KEY5 ;大于10就轉移
- KEY4: MOV A,#4 ;等于或小于10,放入4到A寄存器,長按時間達到了5秒以上
- RET
- KEY5: LCALL KEYA ;大于10,按下的時間小于5秒,掃描按鍵600毫秒
- JZ KEY6 ;如果600毫秒內有按鍵動作就轉移
- RET ;600毫秒內沒有按鍵動作,這時A=1(按了1次),退出
- KEY6: LCALL KEYEX ;等待第二次按鍵松開
- MOV A,#2 ;按鍵松開了,A=2(按了2次)
- RET
- ;------------------ 掃描按鍵開關600毫秒,有按鍵動作A=0,無按鍵動作A=1 ------------------
- KEYA: PUSH 03H
- MOV 03H,#60 ;等待600毫秒,10*60=600毫秒
- KEYB: MOV A,SJJS ;裝入(10)毫秒計數
- KEYC: CJNE A,SJJS,KEYD ;如果不相同就轉移,說明時間已經過了10毫秒
- LCALL SKEY ;掃描按鍵
- JC KEYE ;如果有按鍵動作(C=1)就轉移
- LJMP KEYC
- KEYD: DJNZ 03H,KEYB ;03H減1,不為0就轉移,繼續掃描
- POP 03H
- MOV A,#1 ;600毫秒等待時間已到,A=1沒有按鍵動作
- RET
- KEYE: POP 03H
- CLR A ;600毫秒內有按鍵動作A=0
- RET
- ;------------------ 等待按鍵松開 ------------------
- KEYEX: LCALL SKEY ;掃描按鍵
- JC KEYEX ;如果C=1(按鍵還沒松開),就繼續掃描
- RET
- ;------------------ 按鍵開關掃描,未按C=0,已按下C=1 ------------------
- SKEY: SETB EC11K ;按鍵開關設為高電平
- JNB EC11K,SKEY1 ;為0(低電平)就轉移,表示按鍵開關已經被按下
- SKEY0: CLR C ;為1(高電平),C置為0,沒有按鍵動作
- LCALL WG ;喂狗
- RET
- SKEY1: PUSH 00H ;按鍵已被按下,延時10毫秒
- PUSH 01H ;延時10毫秒
- MOV 00H,#87 ;延時10毫秒
- MOV 01H,#10 ;延時10毫秒
- SKEY2: DJNZ 01H,SKEY2 ;延時10毫秒
- DJNZ 00H,SKEY2 ;延時10毫秒
- POP 01H ;延時10毫秒
- POP 00H ;延時10毫秒
- SETB EC11K ;延時結束后再次把按鍵開關設為高電平
- JB EC11K,SKEY0 ;為1就轉移,按鍵開關未被有效按下
- SETB C ;為1,按鍵動作有效,置C為1
- LCALL WG ;喂狗
- RET
- ;*************************** 以下為EEPROM操作子程序 **********************************
- ;STC89C51RC有4K字節的EEPROM,由8個扇區組成,每個扇區512字節,地址2000H-2FFFH
- ;第1扇區:2000H~21FFH,第2扇區:2200H~23FFH……第8扇區:2E00H~2FFFH
- ;-------------------------------------------
- ;讀一字節,A=讀出的數據
- Byte_Read:
- MOV IAP_CONTR,#ENABLE_IAP ;打開IAP功能,設置Flash操作等待時間(83H)
- MOV IAP_CMD,#01 ;設置為IAP/ISP/EEPROM字節讀模式命令(1)
- MOV IAP_TRIG,#46H ;先送46H
- MOV IAP_TRIG,#0B9H ;再送B9H,ISP/IAP命令立即被觸發起動
- NOP
- MOV A,IAP_DATA ;讀出的數據在IAP_DATA單元中,送入累加器A
- RET
- ;-------------------------------------------
- ;字節編程,A=需寫入的數據
- Byte_Program:
- MOV IAP_CONTR,#ENABLE_IAP ;打開IAP功能,設置Flash操作等待時間(83H)
- MOV IAP_CMD,#02 ;設置為IAP/ISP/EEPROM字節編程模式命令(2)
- MOV IAP_DATA,A ;要編程的數據先送進IAP_DATA寄存器
- MOV IAP_TRIG,#46H ;先送46H
- MOV IAP_TRIG,#0B9H ;再送B9H,ISP/IAP命令立即被觸發起動
- RET
- ;-------------------------------------------
- ;擦除扇區
- Sector_Erase:
- MOV IAP_CONTR,#ENABLE_IAP ;打開IAP功能,設置Flash操作等待時間(83H)
- MOV IAP_CMD,#03 ;設置為IAP/ISP/EEPROM扇區擦除模式命令(3)
- MOV IAP_TRIG,#46H ;先送46H
- MOV IAP_TRIG,#0B9H ;再送B9H,ISP/IAP命令立即被觸發起動
- NOP
- RET
- ;---------- 讀EEPROM保存的各項設置,如果沒有就設置為默認值并保存 ------------
- REEP: LCALL RE00 ;讀EEPROM保存的各項設置
- MOV A,SDDS ;裝入“上電就自動設定的定時時間(小時)”
- JZ REEP0 ;如果是0就轉移,退出
- MOV DSSJS,A ;放入“定時時間(小時)”
- MOV DSSJM,#59 ;放入59到“定時時間(秒)”
- REEP0: RET
- RE00: MOV IAP_ADDRH,#020H ;從第一個扇區開始搜索,地址的高8位
- RE01: MOV IAP_ADDRL,#0 ;從第一個扇區開始搜索,地址的低8位
- LCALL Byte_Read ;讀第一個字節,返回:A=讀出的數據
- CJNE A,FWBZ1,RE03 ;是否保存在當前扇區,不是就轉移到RE03
- INC IAP_ADDRL ;EEPROM字節地址增1
- LCALL Byte_Read ;讀第二個字節
- CJNE A,FWBZ2,RE03 ;第二個字節是否相符
- MOV R1,#ZRFZQ ;相符,從ZRFZQ開始放置讀出的設置值
- MOV R2,#5 ;總共5個字節
- RE02: INC IAP_ADDRL ;EEPROM字節地址增1
- LCALL Byte_Read ;讀一個字節,返回:A=讀出的數據
- MOV @R1,A ;放到R1指向的RAM地址
- INC R1 ;RAM地址增1
- DJNZ R2,RE02 ;未讀完就繼續
- RET ;讀完了,退出
- RE03: MOV A,IAP_ADDRH ;裝入扇區地址的高8位
- ADD A,#2 ;扇區增1
- MOV IAP_ADDRH,A ;放入IAP_ADDRH
- CJNE A,#30H,RE01 ;如果未搜索完最后一個扇區+2(2EH+2=30H)就轉移,繼續搜索
- LCALL SZMRZ ;已經搜索全部八個扇區,未找到保存的內容,設置為默認值
- MOV R0,#8 ;總扇區數量,共8個扇區
- LJMP WSET3 ;跳轉到WSET3保存設置
- ;------------------ 保存設置,不固定保存到某個扇區,各扇區輪流使用 ------------------
- WSET: MOV R0,#8 ;扇區總數量,共8個扇區
- MOV IAP_ADDRH,#020H ;從第一個扇區開始搜索上次保存的設置
- WSET1: MOV IAP_ADDRL,#0 ;地址低位指向第一個字節
- LCALL Byte_Read ;讀第一個字節,返回:A=讀出的數據
- CJNE A,FWBZ1,WSET7 ;如果與EEPROM數據判斷標志1不相同就轉移
- INC IAP_ADDRL ;第一個字節相同,EEPROM字節地址增1
- LCALL Byte_Read ;讀第二個字節
- CJNE A,FWBZ2,WSET7 ;如果與EEPROM數據判斷標志2不相同就轉移
- MOV IAP_ADDRL,#0 ;是在當前扇區,地址指向扇區第一個字節
- LCALL Sector_Erase ;擦除當前扇區,另換一個扇區保存
- WSET2: MOV A,IAP_ADDRH ;裝入扇區地址高位到寄存器A
- CJNE A,#020H,WSET3 ;當前扇區地址高位如果不是20H(第一個扇區)就轉移
- MOV IAP_ADDRH,#30H ;是20H,把IAP_ADDRH設置為最后一個扇區+2(2EH+2=30H)
- WSET3: DEC IAP_ADDRH ;減1
- DEC IAP_ADDRH ;再減1,指向上一個扇區首址
- MOV IAP_ADDRL,#0 ;低8位指向扇區第一個字節
- LCALL Sector_Erase ;擦除整個扇區
- MOV R1,#FWBZ1 ;要保存的內容始址
- MOV R2,#7 ;共7個字節
- WSET4: MOV A,@R1 ;裝入R1指向的RAM地址的內容到A
- LCALL Byte_Program ;字節編程(寫入EEPROM)
- INC IAP_ADDRL ;EEPROM地址加1
- INC R1 ;RAM地址增1
- DJNZ R2,WSET4 ;未保存完就繼續
- MOV IAP_ADDRL,#0 ;保存完了,扇區地址低位指向0(當前扇區首址)
- LCALL Byte_Read ;讀出來檢查看是否寫入成功
- CJNE A,FWBZ1,WSET5 ;如果與EEPROM數據判斷標志1不相同就轉移
- INC IAP_ADDRL ;EEPROM地址加1
- LCALL Byte_Read ;讀第二個字節
- CJNE A,FWBZ2,WSET5 ;如果與EEPROM數據判斷標志2不相同就轉移
- RET ;成功了,退出
- WSET5: DJNZ R0,WSET2 ;如果未試完8個扇區就轉移到WSET2繼續往前一個扇區寫
- SETB 07H ;已經試完8個扇區,都失敗了,位地址07H置為1
- MOV SSSC,#5 ;顯示E1五秒
- MOV ZXM1,#0 ;消隱碼
- MOV ZXM2,#079H ;E
- MOV ZXM3,#006H ;1
- MOV ZXM4,#0 ;消隱碼
- LCALL DISP ;顯示
- WSET6: MOV A,SSSC
- LCALL WG ;喂狗
- JNZ WSET6 ;等待SSSC為0秒
- CLR 07H ;顯示結束,位地址07H置為0
- RET
- WSET7: MOV A,IAP_ADDRH ;裝入扇區地址高位
- ADD A,#2 ;加2,指向下一個扇區首址
- MOV IAP_ADDRH,A ;放回IAP_ADDRH
- CJNE A,#30H,WSET1 ;如果未到最后一個扇區地址高位+2(2EH+2=30H)就轉移到WSET1繼續搜索
- LJMP WSET3 ;是30H,已經搜索完所有扇區,未找到上次保存的數據,跳轉到WSET3保存當前設置
- ;***************************************** 以上為EEPROM操作子程序 ********************************************
- ;------------------------------------------------------------------------------------------
- ;子程序:T0中斷調用,時間計數及倒計時處理
- ;------------------------------------------------------------------------------------------
- TIME: MOV A,SJJS ;裝入(10)毫秒時間計數
- JZ TIME2 ;如果是0就轉移
- DEC SJJS ;不是0,減1
- CJNE A,#50,TIME1 ;如果不是50就轉移退出
- CPL 05H ;位地址第05位取反,數字及冒號閃爍時用,每0.5秒取反一次
- TIME1: RET
- TIME2: CPL 05H ;是0,位地址第05位取反,數字及冒號閃爍時用,每0.5秒取反一次
- MOV DPTR,#HMJS ;把定義的時間計數值地址裝入數據指針DPTR
- MOVC A,@A+DPTR ;從程序存儲區裝入時間計數值到A寄存器
- MOV SJJS,A ;時間計數值放入SJJS,重新計數
- MOV A,MJS ;裝入秒計數
- JZ TIME20 ;如果是0就轉移
- DEC MJS ;不是0,減1秒
- TIME20: MOV A,SSSC ;裝入閃爍時長秒計數
- JZ TIME3 ;如果是0就轉移
- DEC SSSC ;不是0,減1秒
- TIME3: MOV A,SJ ;裝入自然風時電機通電時長到寄存器A
- JZ TIME4 ;如果是0就轉移
- DEC SJ ;不是0,減1秒
- TIME4: MOV A,ZQ ;裝入自然風變化周期時長到寄存器A
- DEC ZQ ;先減1
- JNZ TIME5 ;如果不是0就轉移
- MOV ZQ,ZRFZQ ;是0,重新裝入設置值
- MOV SJ,ZRFSJ ;是0,重新裝入設置值
- TIME5: MOV A,DSSJM ;裝入定時時間(秒)到寄存器A
- JZ TIME7 ;如果是0就轉移
- CJNE A,#59,TIME6 ;如果不是59秒就轉移
- MOV A,DSSJF ;是59秒,檢查“時”
- JNZ TIME6 ;不是0就轉移
- MOV A,DSSJS ;檢查“分”
- JNZ TIME6 ;不是0就轉移
- MOV DSSJM,A ;“時、分”都是0,把“秒”也清零
- RET
- TIME6: DEC DSSJM ;不是0,減1秒
- RET
- TIME7: MOV A,DSSJF ;裝入定時時間(分)到寄存器A
- JZ TIME8 ;如果是0就轉移
- DEC DSSJF ;不是0,減1分
- MOV DSSJM,#59 ;把59放入定時時間(秒)
- RET
- TIME8: MOV A,DSSJS ;裝入定時時間(時)到寄存器A
- JZ TIME9 ;如果是0就轉移,退出
- DEC DSSJS ;不是0,小時減1
- MOV DSSJM,#59 ;把59放入定時時間(秒)
- MOV DSSJF,#59 ;把59放入定時時間(分)
- TIME9: RET
- ;---------------------------------------------------------------------------------------------
- ;子程序:T0中斷調用,根據條件控制自然風狀態LED指示燈和可控硅
- ;---------------------------------------------------------------------------------------------
- Control:SETB LED ;先熄滅自然風LED指示燈
- JNB 02H,CTL00 ;如果位地址02H(正常/自然風切換)為0(正常)就轉移,保持熄滅狀態
- CLR LED ;為1,自然風狀態,點亮LED指示燈
- CTL00: MOV A,DSSJM ;裝入定時時間(秒)到寄存器A
- JNZ CTL02 ;如果不是0就轉移
- MOV A,DSSJF ;裝入定時時間(分)到寄存器A
- JNZ CTL02 ;如果不是0就轉移
- MOV A,DSSJS ;裝入定時時間(時)到寄存器A
- JNZ CTL02 ;如果不是0就轉移
- CTL01: SETB MOC ;置MOC為高電平,斷電
- RET
- CTL02: JNB 02H,CTL03 ;如果位地址02H(正常/自然風切換)為0(正常)就轉移,通電
- MOV A,SJ ;是自然風狀態,裝入自然風時電機通電時長到寄存器A
- JZ CTL01 ;如果為0(通電倒計時結束)就轉移,斷電
- CTL03: CLR MOC ;置MOC為低電平,通電
- RET
- ;------------------------------------------------------------------------------------------
- ;子程序:T0中斷調用,顯示定時時間及各項設置的內容
- ;------------------------------------------------------------------------------------------
- DISPLAY:JB 06H,DPYSZ1 ;如果位地址06H為1就轉移退出,主程序顯示88:88
- JB 07H,DPYSZ1 ;如果位地址07H為1就轉移退出,主程序顯示E1
- MOV A,DISPL ;裝入要顯示的目標
- JZ DISPL0 ;如果是0(顯示定時時間)就轉移
- DPYSZ: PUSH ACC
- MOV DPTR,#SEGTAB ;查表獲取字形碼
- MOVC A,@A+DPTR ;查表獲取字形碼
- MOV ZXM1,A ;項目編號字形碼放到待發送TM1637區1
- MOV ZXM2,#40H ;放入“-”的字形碼到待發送TM1637區2
- POP ACC
- DEC A ;減1
- PUSH 01H
- MOV R1,#ZRFZQ ;各項設置值始址
- ADD A,R1 ;加上項目號
- MOV R1,A ;得出設置項目的實際地址放入R1
- MOV A,@R1 ;裝入設置值
- POP 01H
- MOV B,A ;放入B寄存器
- CJNE A,XSHC1,DPYSZ3 ;當前設置值與顯示緩存1不相同就轉移,立即顯示
- MOV A,SJJS ;相同,裝入時間計數
- JNZ DPYSZ2 ;不是0就轉移,每半秒(遇到50或0)顯示一次
- LJMP DPYSZ3 ;是0,顯示
- DPYSZ1: RET
- DPYSZ2: CJNE A,#50,DPYSZ1 ;不是50就轉移退出,每半秒(遇到50或0)顯示一次
- DPYSZ3: MOV XSHC1,B ;當前設置值放入顯示緩存1
- JNB 04H,DPYSZ4 ;如果位地址04H為0(不閃爍)就轉移
- JNB 05H,DPYSZ4 ;為1,閃爍顯示,如果位地址05H為0(顯示)就轉移
- CLR A ;為1,處于閃爍顯示中的“不顯示”狀態,放入消隱碼
- MOV ZXM1,A ;放入消隱碼
- MOV ZXM2,A ;放入消隱碼
- MOV ZXM3,A ;放入消隱碼
- MOV ZXM4,A ;放入消隱碼
- LJMP disp ;跳轉到disp,發送4個字節數據到TM1637顯示
- DPYSZ4: MOV A,B ;當前設置值放入A寄存器
- LCALL DISPL6 ;轉換并獲取字形碼放到待發送TM1637區3和4
- LJMP disp ;跳轉到disp,發送4個字節數據到TM1637顯示
- DISPL0: MOV A,DSSJS ;顯示定時時間,裝入定時時間(時)
- CJNE A,XSHC1,DISPL3 ;定時時間(時)與顯示緩存1不相同就轉移,顯示
- MOV A,DSSJF
- CJNE A,XSHC2,DISPL3 ;定時時間(分)與顯示緩存2不相同就轉移,顯示
- MOV A,SJJS ;時、分都相同,裝入(10)毫秒時間計數
- JNZ DISPL2 ;不是0就轉移
- LJMP DISPL3 ;是0,顯示,每半秒(遇到50或0)顯示一次
- DISPL1: RET
- DISPL2: CJNE A,#50,DISPL1 ;不是50就轉移,每半秒(遇到50或0)顯示一次
- DISPL3: MOV XSHC1,DSSJS ;當前時間放入顯示緩存1
- MOV XSHC2,DSSJF ;當前時間放入顯示緩存2
- MOV A,DSSJM ;
- JNZ DISPL4 ;檢查當前定時時間是否全部為0,不是就轉移
- MOV A,DSSJF ;
- JNZ DISPL4 ;檢查當前定時時間是否全部為0,不是就轉移
- MOV A,DSSJS ;
- JNZ DISPL4 ;檢查當前定時時間是否全部為0,不是就轉移
- CLR 05H ;定時時間為0,把位地址05H置為0,冒號不閃爍顯示
- DISPL4: MOV A,DSSJS ;裝入“時”
- MOV B,#10 ;轉換為BCD碼
- DIV AB ;轉換為BCD碼
- MOV DPTR,#SEGTAB ;查表獲取字形碼
- MOVC A,@A+DPTR ;查表獲取字形碼
- MOV ZXM1,A ;字形碼放入待發送TM1637區1
- XCH A,B ;A、B寄存器內容交換
- MOVC A,@A+DPTR ;查表獲取字形碼
- JB 05H,DISPL5 ;如果05H為1就轉移,不顯示冒號
- ORL A,#10000000B ;為0,把最高位置為1,顯示冒號(字形碼的最高位為1就顯示冒號)
- DISPL5: MOV ZXM2,A ;放入待發送TM1637區2
- MOV A,DSSJF ;裝入“分”
- LCALL DISPL6 ;轉換并獲取字形碼放到待發送TM1637區3和4
- LJMP disp ;跳轉到disp,發送4個字節數據到TM1637顯示
- DISPL6: MOV B,#10 ;轉換為BCD碼
- DIV AB ;轉換為BCD碼
- MOV DPTR,#SEGTAB ;查表獲取字形碼
- MOVC A,@A+DPTR ;查表獲取字形碼
- MOV ZXM3,A ;字形碼放入待發送TM1637區3
- XCH A,B ;A、B寄存器內容交換
- MOVC A,@A+DPTR ;查表獲取字形碼
- MOV ZXM4,A ;字形碼放入待發送TM1637區4
- RET
- ;------------------ 發送4個字節數據到TM1637顯示,地址自動加1 ------------------
- disp: LCALL Srt
- MOV A,#040H ;數據命令設置40H:地址自動加1,寫數據到顯示寄存器
- LCALL Writebyte ;發送一個字節
- LCALL Stop
- NOP
- LCALL Srt
- MOV A,#0C0H ;地址命令設置C0H:初始地址為00H
- LCALL Writebyte ;發送一個字節
- PUSH 01H
- PUSH 06H
- MOV 06H,#4 ;發送4個字節數據
- MOV R1,#ZXM1 ;等待發送的字形碼始址
- disp1: MOV A,@R1 ;裝入要發送的字形碼
- LCALL Writebyte ;發送一個字節
- INC R1 ;地址加1
- DJNZ 06H,disp1 ;如果還未發送完就繼續
- POP 06H
- POP 01H
- LCALL Stop
- LCALL Srt
- MOV A,SMGLD ;裝入設置的數碼管亮度(1~8)
- ADD A,#087H ;加上87H后即為對應的亮度控制命令88H~8FH
- LCALL Writebyte ;按設置的亮度開顯示
- LJMP Stop
- ;------------------ 發送8bit(一個字節)數據到TM1637,A=要發送的數據,從低位開始 ------------------
- Writebyte:
- PUSH 00H
- MOV 00H,#8 ;發送8位數據
- WBY1: CLR CLK ;拉低CLK
- JNB ACC.0,WBY2 ;A寄存器的低位(0位)如果為0就轉移
- SETB DIO ;為1,拉高DIO
- SJMP WBY3
- WBY2: CLR DIO ;為0,拉低DIO
- WBY3: NOP
- NOP
- NOP
- NOP
- NOP
- SETB CLK ;拉高CLK
- CLR C ;進位標志清0
- RRC A ;A寄存器內容帶進位循環右移
- DJNZ 00H,WBY1 ;如果還未發送完8bit數據就繼續
- WBY4: CLR CLK ;8位數據發送完了
- NOP
- MOV 00H,#05 ;設置等待應答信號計數值,防止萬一與TM1637通訊失敗而造成死循環
- WBY5: DEC 00H ;減1,正常情況下ACK應答信號很快,第一次減1就會有應答
- MOV A,00H ;裝入計數值到A
- JZ WBY6 ;如果為0就轉移退出,說明與TM1637通訊失敗,或TM1637不存在
- JB DIO,WBY5 ;不為0,判斷TM1637發過來的ACK應答信號,未應答(為1,高電平)就轉移
- WBY6: POP 00H
- NOP
- NOP
- NOP
- SETB CLK
- NOP
- NOP
- NOP
- RET
- ;------------------ Start子程序 ------------------
- Srt: SETB DIO ;拉高DIO
- SETB CLK ;拉高CLK
- NOP
- NOP
- NOP
- NOP
- NOP
- SETB DIO ;拉高DIO
- NOP
- NOP
- NOP
- NOP
- NOP
- CLR DIO ;拉低DIO
- NOP
- NOP
- NOP
- NOP
- NOP
- CLR CLK ;拉低CLK
- RET
- ;------------------ Stop子程序 ------------------
- Stop: CLR CLK
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- CLR DIO
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- SETB CLK
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- SETB DIO
- NOP
- NOP
- NOP
- NOP
- NOP
- CLR CLK
- CLR DIO
- RET
- ;------------------ 字形表 ------------------
- SEGTAB:
- DB 00111111B ;0(3FH)
- DB 00000110B ;1(06H)
- DB 01011011B ;2(5BH)
- DB 01001111B ;3(4FH)
- DB 01100110B ;4(66H)
- DB 01101101B ;5(6DH)
- DB 01111101B ;6(7DH)
- DB 00000111B ;7(07H)
- DB 01111111B ;8(7FH)
- DB 01101111B ;9(6FH)
- DB 01110111B ;A(77H)
- DB 01111100B ;B(7CH)
- DB 00111001B ;C(39H)
- DB 01011110B ;D(5EH)
- DB 01111001B ;E(79H)
- DB 01110001B ;F(71H)
- DB 00000000B ;消隱碼(00)
- ;------------------------------------------------------------------------------------------
- END
-
復制代碼
51hei.png (3.61 KB, 下載次數: 121)
下載附件
2020-7-11 02:23 上傳
以上資料51hei下載地址:
電風扇長定時器.rar
(95.52 KB, 下載次數: 98)
2020-7-10 23:44 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|