本帖最后由 高高的白楊 于 2021-1-10 21:38 編輯
退休在家自學51單片機,學到定時器部分時聯想到無線電早期時使用的MORSE電報碼,便產生了用自己焊接的洞洞板51最小系統的時鐘控制MORSE碼來驗證自學成果的想法,在此與各位初學者共師兄習。
第一次發貼,如有不當,請各位斧正。
電路板圖是用Sprint-Layout 6.0 綠色漢化版畫的。
圖1:電路板圖
STC15W408洞洞電路板.PNG (78.16 KB, 下載次數: 96)
下載附件
2021-1-10 15:53 上傳
洞洞板正面,左側為STC15W408AS-DIP20 MPU及P5.5引腳所接紅色LED組成的51最小系統,右側為MAX232CPE組成的RS232電平轉換電路。板上LED為幾十年前的早期產品,其亮度明顯不如現在的貼片LED。
圖2:洞洞板正面照片
洞洞板正面.jpg (93.04 KB, 下載次數: 87)
下載附件
2021-1-10 15:56 上傳
洞洞板背面,第一次焊洞洞板,水平有限,未能全部走錫。
圖3:洞洞板背面照片
洞洞板背面.jpg (226.39 KB, 下載次數: 95)
下載附件
2021-1-10 16:01 上傳
因系統功能簡單,故程序用匯編書寫,其長度不足200行,并有較詳盡的語句注釋。
程序如下:
- ;===========莫爾斯電碼單LED實時時鐘,經洞洞板搭建最小系統驗證無誤====================================
- ;===========STC15W408AS-DIP20,fosc=12MHz=============================================================
- ;===========T0為模式0,16位自動重裝,,用于基礎時鐘(中斷優先級為高)
- ;===========T2為模式0,16位自動重裝,用于MORSE電碼的編碼時長計時(中斷優先級為低)
- ;===========P5.5端口單個LED輸出莫爾斯電碼============================================================
- ;===========LED負極接P5.5端口,LED正極接+5V==========================================================
- ;===========整分鐘時LED依次以莫爾斯電碼顯示當前小時十位數、個位數,分鐘十位數、個位數================
- ;===========莫爾斯電碼時長:點1t=250ms,劃3t=750ms,點或劃間隔2t=500ms,數字之間間隔7t=1750ms=========
- //I/O 口特殊功能寄存器 // 復位值 描述
- P5 EQU 0C8H; //xxxx,1111 端口5
- AUXR EQU 08EH; //0000,0001 輔助寄存器
- IE2 EQU 0AFH; //0000,0000 中斷允許就寄存器
- T2H EQU 0D6H; //0000,0000 定時器2高8位寄存器
- T2L EQU 0D7H; //0000,0000 定時器2低8位寄存器
- //define constants
- MIN_MARK BIT 00H ;整分鐘標志位
- MORSE_LED BIT P5.5 ;LED輸出莫爾斯電碼
-
- HOUR EQU R0
- MIN EQU R1
- SEC EQU R2
- ;===========STC15W408AS-DIP20,fosc=12MHz=========================
- ORG 0000H
- RESET:
- AJMP MAIN ;復位入口
- ORG 000BH
- AJMP T0_ISR ;T0中斷服務入口
- ORG 0063H
- AJMP T2_ISR ;T2中斷服務入口
- ORG 00B3H ;STC15W408AS中斷向量區后面第一個可用地址
- MAIN:
- MOV SP,#0DFH ;堆棧指針初值,堆棧空間為32字節
- CLR A ;Clera A
- MOV R0,A ;小時清零
- MOV R1,A ;分清零
- MOV R2,A ;秒清零
- MOV R3,#20 ;T0每秒中斷次數暫存地址
-
- ACALL TIME_INIT ;調用T0,T2初始化子程序
-
- LOOP:
- JNB MIN_MARK,$ ;非整分鐘則原地等待
- CLR MIN_MARK ;整分鐘標志位清零
- ACALL TIME_NUM ;調用分離當前時間十位及個位數字子程序
- SJMP LOOP
- ;===========T0、T2初始化子程序====================================
- TIME_INIT:
- ANL AUXR,#00000000B ;定時器T0及T2設置為時鐘12T模式,不允許T2工作
- ;允許使用擴展RAM,T1作為UART1波特率發生器(釋放T2作為獨立定時器)
- ANL TMOD,#11110000B ;設置定時器T0模式為模式0,STC15W為16位自動重裝
- MOV TL0,#0B0H ;設置T0初值(低8位50ms@12MHz)
- MOV TH0,#3CH ;設置T0初值(高8位50ms@12MHz)
- CLR TF0 ;清除TF0標志
- SETB TR0 ;T0開始計時
- SETB ET0 ;允許T0中斷
-
- MOV T2L,#0B0H ;設置T2初值(低8位50ms@12MHz)
- MOV T2H,#03CH ;設置T2初值(高8位50ms@12MHz)
-
- SETB EA ;CPU檢測中斷源(開總中斷)
- RET
- ;===========分離當前時間十位及個位數字子程序====================
- TIME_NUM:
- MOV B,#10 ;除數10
- MOV A,HOUR ;當前小時數
- DIV AB ;
- MOV R4,A ;商(十位數)放在R4
- MOV 41H,B ;余數(個位數)放在41H
- ACALL MORSE_CODE ;調用莫爾斯字符取模子程序,傳遞參數在R4,顯示小時的十位數
- MOV R4,41H ;將個位數傳給R4
- ACALL MORSE_CODE ;調用莫爾斯字符取模子程序,傳遞參數在R4,顯示小時的個位數
-
- MOV B,#10 ;除數10
- MOV A,MIN ;當前分鐘數
- DIV AB ;
- MOV R4,A ;商(十位數)放在R4
- MOV 41H,B ;余數(個位數)放在41H
- ACALL MORSE_CODE ;調用莫爾斯字符取模子程序,傳遞參數在R4,顯示分鐘的十位數
- MOV R4,41H ;將個位數傳給R4
- ACALL MORSE_CODE ;調用莫爾斯字符取模子程序,傳遞參數在R4,顯示分鐘的個位數
-
- RET
- ;===========莫爾斯字符取模子程序=================================
- MORSE_CODE:
- MOV DPTR,#MORSE_TABLE ;莫爾斯電碼數字轉換表首地址
- MOV R7,#05H ;莫爾斯電碼單個數字的信號個數
- MOV A,R4 ;將需取模的單位數字(存于R4)送入累加器A
- MOV B,#05H ;莫爾斯電碼單個數字的信號個數
- MUL AB ;要顯示的莫爾斯電碼數字查表地址偏移量
- MOV 40H,A ;地址偏移量暫存40H
- CATCH:
- MOVC A,@A+DPTR ;要顯示的莫爾斯電碼數字的第i(i=1~5)個點或劃的單位長度
- MOV B,#05H ;單位長度1t對應T2中斷信號的倍數5
- MUL AB ;要顯示的莫爾斯電碼數字的第i個點或劃對應T2中斷響應的次數
- MOV R6,A ;將電碼間隔時長對應的中斷次數送入R6
- ACALL DISPLAY ;調用LED莫爾斯電碼點或劃顯示子程序
- INC 40H ;下一個莫爾斯電碼點或劃的地址偏移量
- MOV A,40H ;送地址偏移量至變址寄存器A
- DJNZ R7,CATCH ;一個莫爾斯電碼數字5個點或劃是否完整取模,不滿5次則繼續
- ACALL SEVEN_DOT ;調用數字之間間隔7t,在DISPLAY最后有1t,實際發6t
-
- RET
-
- ;===========LED莫爾斯電碼顯示子程序============================
- DISPLAY:
- CLR MORSE_LED ;P5.5為低電平,LED導通點亮
-
- ORL IE2,#00000100B ;T2開中斷
- ORL AUXR,#00010000B ;T2開始工作
-
- CJNE R6,#00H,$ ;T2中斷數不足對應的電碼要求時,原地等待
-
- ANL IE2,#11111011B ;T2關中斷
- ANL AUXR,#11101111B ;T2停止工作
-
- SETB MORSE_LED ;LED關斷熄滅
- MOV R6,#10H ;將電碼點或劃之間間隔時長2t(2*250ms=10*50ms)對應的中斷次數10送入R6
-
- ORL IE2,#04H ;T2開中斷
- ORL AUXR,#00010000B ;T2開始工作
-
- CJNE R6,#00H,$ ;T2中斷數不足對應的電碼要求時,原地等待
-
- ANL IE2,#0FBH ;T2關中斷
- ANL AUXR,#11101111B ;T2停止工作
-
- RET
- ;===========LED熄滅6t時長子程序=================================
- SEVEN_DOT:
- SETB MORSE_LED ;LED關斷熄滅
- MOV R6,#30 ;將數字之間間隔7t-1t(6*250ms=30*50ms)對應的中斷次數30送入R6
-
- ORL IE2,#04H ;T2開中斷
- ORL AUXR,#00010000B ;T2開始工作
-
- CJNE R6,#00H,$ ;T2中斷數不足對應的電碼要求時,原地等待
-
- ANL IE2,#0FBH ;T2關中斷
- ANL AUXR,#11101111B ;T2停止工作
-
- RET
-
- ;===========T0中斷服務程序(基礎時鐘)============================
- T0_ISR:
- PUSH PSW ;保護現場
- PUSH ACC ;
-
- DJNZ R3,RETURN ;T0中斷計數是否到20次,未到則返回
- MOV R3,#20 ;重新裝入T0計數基值(每秒T0中斷次數)
-
- INC SEC ;“second”單元增1
- CJNE SEC,#60,RETURN ;是否到60秒,未到則返回
- SETB MIN_MARK ;整分鐘標志置1
- MOV SEC,#00H ;計滿60“秒”,“秒”單元清零
-
- INC MIN ;“minute”單元增1
- CJNE MIN,#60,RETURN ;是否到60分,未到則返回
- MOV MIN,#00H ;計滿60“分”,“分”單元清零
-
- INC HOUR ;“hour”單元增1
- CJNE HOUR,#24,RETURN ;是否到24hour,未到則返回
- MOV HOUR,#00H ;計滿24hour,“hour”單元清零
- RETURN:
- POP ACC ;恢復現場
- POP PSW
-
- RETI
- ;===========T2中斷服務程序(莫爾斯碼時長控制)=========================
- T2_ISR:
- PUSH PSW ;保護現場
- PUSH ACC ;
-
- DEC R6 ;T2中斷數減一
-
- POP ACC ;恢復現場
- POP PSW
- RETI
-
- ;===========莫爾斯電碼/數字0~9轉換表==================================
- ORG 01A0H
- MORSE_TABLE:
- DB 3,3,3,3,3,1,3,3,3,3,1,1,3,3,3,1,1,1,3,3,1,1,1,1,3
- DB 1,1,1,1,1,3,1,1,1,1,3,3,1,1,1,3,3,3,1,1,3,3,3,3,1
- END
復制代碼
用Keil 5編輯、編譯、鏈接程序;用STC-ISP下載程序至洞洞板,并上電運行驗證,程序運行無誤。
LED顯示的MORSE碼與時鐘對應的數字無誤,即MORSE_TABLE取碼正確。
系統電源由一節18650鋰電池提供,LED熄滅實測電流為8.3mA,LED點亮實測電流為10.5mA。
MORSE碼表的數字部分:
數字 MORSE碼
1 . _ _ _ _
2 . . _ _ _
3 . . . _ _
4 . . . . _
5 . . . . .
6 _ . . . .
7 _ _ . . .
8 _ _ _ . .
9 _ _ _ _ .
0 _ _ _ _ _
其中:
. 點,一個時長基本單位t=250ms。
_ 劃,3t=750ms。
一個數字內部的點或劃之間的時間間隔2t=500ms。
數字與數字之間的時間間隔為7t=1750ms。
|