📄 uart.asm
字号:
; ************************************
; * Port A (RA0-RA4) bit definitions *
; ************************************
TX EQU 3 ; RA3 is the software UART Transmit pin
RX EQU 4 ; RA4 is the software UART Recieve pin
; *****************************************
; * Define clock speed and baud rate here *
; *****************************************
OSCCLOCK EQU .4000000 ; Define external crystal frequency
BAUDRATE EQU .9600 ; Define desired baud rate here
; * The following assembler calculations determine delays:
; BIT_TIME (uS) =
; (8 + 2 + 4 + NUM_NOPs + 3 * DELAY_VALUE) * PROC_INSTRUCT_CYCLE
;
; BIT_TIME is the time for each bit or half bit = 1/(baud rate)
; PROC_INSTRUCT_CYCLE is processor instruction cyle = (crystal freq)/4
; DELAY_VALUE is integer delay value that is loaded into delay counter
; NUM_NOPs are number of NOPs that have to be added to equal bit time
OVERHEAD EQU .14 ; Number of instructions for routine
INSTPERBIT EQU ((2*OSCCLOCK/(4*BAUDRATE))+1)/2
INSTPERHALFBIT EQU ((2*OSCCLOCK/(8*BAUDRATE))+1)/2
DELAYBAUD EQU (INSTPERBIT-OVERHEAD)/3 ;
NUMBAUDNOPS EQU INSTPERBIT-(3*DELAYBAUD)-OVERHEAD
DELAYHALFBAUD EQU (INSTPERHALFBIT-OVERHEAD)/3 ;
; *******************************************************************
; * Subroutine for delaying one bit time interval. *
; * This is used by both the UartTx and UartRx routines. *
; * Must use MPASM to compile code, otherwise must rewrite routine. *
; *******************************************************************
DelayBit
movlw DELAYBAUD ; Place baud delay value into W
movwf BaudCount ; Move baud delay value into BAUDCOUNT
variable nopcount
nopcount = NUMBAUDNOPS
WHILE nopcount > 0 ; Add correct number of NOPs
NOP ; Delay one additional cycle
nopcount--
ENDW
dlylabels
decfsz BaudCount,F ; Dec baud delay counter,skip when 0
goto dlylabels ; Jump back, delay for count cycle
return ; Done with delay, so return
; *******************************************************************
; * UartTx RS-232 character output routine. *
; * USAGE: *
; * call UartTx *
; * Place ASCII character value into W and call UartTx *
; * Transmits 8 bits no parity and 1 stop bit *
; *******************************************************************
UartTx
movwf Buffer ; Place output character into CHARBUF reg
movlw 09h ; total number of bits to send
movwf BitCount ; move this to BITCOUNT reg
bcf STATUS,C ; start by transmitting the start bit
goto sendstart ; Jump to send the start bit
sendbit
rrf Buffer,F ; place the next bit to be tx into carry
sendstart
btfss STATUS,C ; Skip if next bit is zero
bcf PORTA,TX ; Transmit a 1
btfsc STATUS,C ; Skip if next bit is one
bsf PORTA,TX ; Transmit a 0
movlw DELAYBAUD ; Place baud delay one bit into W
call DelayBit ; delay for one bit time
decfsz BitCount,F ; Decrement bit counter, skip when done
goto sendbit ; Jump back to tranmit next bit
bsf PORTA,TX ; send out the stop bit
movlw DELAYBAUD ; Place baud delay one bit into W
call DelayBit ; delay for one bit time
return ; Done - Return back to the main program
; *******************************************************************
; * uartrx RS-232 character input routine. *
; * USAGE: *
; * call UartRx *
; * receive byte is placed into Buffer *
; * 9600 Baud, 8 bits no parity 1 stop bit *
; *******************************************************************
UartRx
movlw 08h ; set input bit counter
movwf BitCount ; place bit counter into BITCOUNT
getwait
btfsc PORTA,RX ; Skip when we recieve a start bit
goto getwait ; go back and wait for a start bit
movlw DELAYHALFBAUD ; Place baude delay half bit time into W
call DelayBit ; delay for one bit time
btfsc PORTA,RX ; Skip if we still have the start bit
goto getwait ; Maybe noise, go back and wait for start
getloop
movlw DELAYBAUD ; Place baud delay one bit into W
call DelayBit ; delay for one bit time
btfss PORTA,RX ; Skip if the next bit is a one
bcf STATUS,C ; Clear carry bit to shift in zero
btfsc PORTA,RX ; Skip if the next bit is a zero
bsf STATUS,C ; Set the carry bit
rrf Buffer,F ; Shift the next received bit into temp
decfsz BitCount,F ; decrement the bit count, skip when done
goto getloop ; Go back if we still have more bits
movlw DELAYBAUD ; Place baud delay one bit into W
call DelayBit ; delay for one bit time
return
; *******************************************************************
; * inituart RS-232 port initialization routine *
; * USAGE: *
; * CALL inituart *
; *******************************************************************
inituart
movlw b'00011000' ; Place 11 into RA3,2
movwf PORTA ; Init PORTA output latches
movlw b'11110111' ; Set RA3 as an output
bsf STATUS,RP0
movwf TRISA ; Init PORTA tris register
bcf STATUS,RP0
return ; Done, so return!
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -