本帖最后由 高高的白杨 于 2021-1-10 21:38 编辑
退休在家自学51单片机,学到定时器部分时联想到无线电早期时使用的MORSE电报码,便产生了用自己焊接的洞洞板51最小系统的时钟控制MORSE码来验证自学成果的想法,在此与各位初学者共师兄习。
第一次发贴,如有不当,请各位斧正。
电路板图是用Sprint-Layout 6.0 绿色汉化版画的。
图1:电路板图
洞洞板正面,左侧为STC15W408AS-DIP20 MPU及P5.5引脚所接红色LED组成的51最小系统,右侧为MAX232CPE组成的RS232电平转换电路。板上LED为几十年前的早期产品,其亮度明显不如现在的贴片LED。
图2:洞洞板正面照片
洞洞板背面,第一次焊洞洞板,水平有限,未能全部走锡。
图3:洞洞板背面照片
因系统功能简单,故程序用汇编书写,其长度不足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。
|