;-----Timer 2 做波特率发生器 -------------------------
;定义特殊功能寄存器
;与 RS232 口、TIMER2 有关的特殊功能寄存器
T2CON EQU 0C8H
TR2 EQU T2CON.2 ;TR2 是 T2CON 特殊功能寄存器的第 2 位
RCAP2L EQU 0CAH
RCAP2H EQU 0CBH
TH2 EQU 0CDH
TL2 EQU 0CCH
;------------------------------------------------
;设置波特率自动重装数
RELOAD_COUNT_HIGH EQU 0FFH
;使用以下参数必须将 RELOAD_COUNT_HIGH 设置为 0FFH
;RELOAD_COUNT_LOW EQU 0FAH ;Fosc = 22.1184MHz, Baud = 115200
;RELOAD_COUNT_LOW EQU 0EEH ;Fosc = 22.1184MHz, Baud = 38400
;RELOAD_COUNT_LOW EQU 0F0H ;Fosc = 20.000MHz, Baud = 38400
;RELOAD_COUNT_LOW EQU 0F6H ;Fosc = 12.000MHz, Baud = 38400
;RELOAD_COUNT_LOW EQU 0FDH ;Fosc = 11.059MHz, Baud = 115200
;RELOAD_COUNT_LOW EQU 0F7H ;Fosc = 11.059MHz, Baud = 38400
;RELOAD_COUNT_LOW EQU 0F8H ;Fosc = 10.000MHz, Baud = 38400
;RELOAD_COUNT_LOW EQU 0FBH ;Fosc = 6.000MHz, Baud = 38400
;RELOAD_COUNT_LOW EQU 0FCH ;Fosc = 5.000MHz, Baud = 38400
;RELOAD_COUNT_LOW EQU 070H ;Fosc = 11.059MHz, Baud = 2400
;--------------
;计算自动重装数:
;--------------
;晶体频率: Fosc
;波特率: Baud
;自动重装数: RELOAD = INT(Fosc/Baud/32 + 0.5), INT 表示取整运算(舍去小数)
;将自动重装数转换成 16 进制, 用 10000H 减自动重装数, 存入 RCAP2H, RCAP2L
;计算实际的波特率: Baud = Fosc/RELOAD/32, 如果误差>3.5 要更改波特率.
;例: Fosc = 22.1184MHz, Baud = 115200
; RELOAD = INT( 22118400/115200/32 + 0.5)
; = INT( 6.5 )
; = 6
; = 0006H
; 10000H - 0006H = FFFAH
;
; MOV RCAP2H, #0FFH
; MOV RCAP2L, #0FAH
;例: Fosc = 20.MHz, Baud = 57600 (Baud=115200 时误差太大)
; RELOAD = INT( 20000000/57600/32 + 0.5)
; = INT( 10.85 + 0.5 )
; = INT( 11.35 )
; = 11
; = 000BH
; 10000H - 000BH = FFF5H
;
; MOV RCAP2H, #0FFH
; MOV RCAP2L, #0F5H
;--------------------------------------------
ORG 0000H
AJMP MAIN
;--------------------------------------------
ORG 0023H ;RS232 串口中断
AJMP UART
NOP
NOP
;--------------------------------------------
MAIN:
MOV SP, #0E0H
ACALL Initial_UART ;初始化串口
MOV R0, #30H ;发送 10 个字符 ‘0123456789'
MOV R2, #10
LOOP:
MOV A, R0
ACALL Send_One_Byte ;发送一个字节
INC R0
DJNZ R2, LOOP
WAIT1:
SJMP WAIT1 ;跳转到本行, 无限循环
;------------------------------------------------
UART: ;串口中断服务程序
JBC RI, UART_1
RETI ;发送时使用的是查询方式,不使用中断
UART_1: ;接收一个字节. 此时 RI 已被清0
PUSH ACC
MOV A, SBUF ;取接收到的字节
ACALL Send_One_Byte ;回发收到的字节
POP ACC
RETI
;------------------------------------------------
Initial_UART: ;初始化串口
; Bit: 7 6 5 4 3 2 1 0
; SCON SM0/FE SM1 SM2 REN TB8 RB8 Tl Rl
MOV SCON, #50H ; 0101,0000 8 位可变波特率, 无奇偶校验
Init_RS232_1:
MOV A, #RELOAD_COUNT_HIGH ;波特率自动重装数
MOV RCAP2H, A
TH2, A
MOV A, #RELOAD_COUNT_LOW
MOV RCAP2L, A
MOV TL2, A
MOV T2CON, #0x34 ;使用 T2 作波特率发生器
SETB ES ;允许串口中断
SETB EA ;开总中断
RET
;------------------------------------------------
Send_One_Byte: ;发送一个字节
CLR ES
CLR TI ;清零串口发送中断标志
MOV SBUF, A
WAIT2:
JNB TI, WAIT2 ;等待发送完毕
CLR TI ;清零串口发送中断标志
SETB ES
RET
;------------------------------------------------
END |