kkyleyang
kkyleyang

Reputation: 9

How to use UART in PIC16F877A with assembly code?

I am using UART in PIC16F877A with test board HJ-5G. My oscillator is 4MHz (KDS4.000). I tried to receive data from my computer.(Serial Debug Assistant) But I do not receive anything. And I tried to transmit data, but my Serial Debug Assistant can not receive anything. I use MPLAB X IDE v6.20 to run my code.

I have checked SPBRG. But I think I am right. I still don't know where is the problem. My RCREG is alaways 0x00.

INT_VECT:
    movwf W_TEMP
    movf STATUS, W
    movwf STATUS_TEMP
    
    BTFSC PIR1, 5
    call uart_rx_isr
    
    movf STATUS_TEMP, W
    movwf STATUS
    movf W_TEMP, W
    RETFIE

uart_rx_isr:
    movf RCREG, W
    movwf RX_TEMP
    bsf TEST_FLAGS, 0
    bcf PIR1, 5
    return

setup:
    call uart_init
    bsf STATUS, 5 ; select bank 1
    CLRF TRISB
    BSF TRISD, 2
    bcf STATUS, 5 ; select bank 0
    CLRF PORTB
    movlw (1<<7)
    IORWF INTCON
    bcf STATUS, 0 ; clear carry
    bcf INTCON, 0 ; clear int flag
    
    ; Debugging: Send initial status
    movlw 'I'
    movwf TXREG
    call uart_tx_done
    
    call send_debug_info

main:
    ; Reset receiver periodically
    bcf RCSTA, 4 ; Disable receiver
    bsf RCSTA, 4 ; Enable receiver
    
    ; Check for received data
    BTFSS PIR1, 5
    goto main_continue
    
    ; Read received data
    movf RCREG, W
    movwf RX_TEMP
    bsf TEST_FLAGS, 0
    
    ; Echo received data
    movf RX_TEMP, W
    movwf TXREG
    call uart_tx_done
uart_init:
    bsf STATUS, 5 ; select bank 1
    movlw 25    ; Set baud rate to 9600 
    movwf SPBRG
    movlw 0b10000000 ; Set RC6 as output (TX) and RC7 as input (RX)
    movwf TRISC
    bcf STATUS, 5 ; select bank 0
    movlw 0x90 ; Enable serial port and continuous receive
    movwf RCSTA
    bsf RCSTA, 4 ; CREN - Enable continuous receive
    movf RCREG, W ; Clear receiver register
    bsf STATUS, 5 ; select bank 1
    movlw 0x24 ; Enable transmission
    movwf TXSTA
    bsf PIE1, 5   ; Enable receive interrupt
    bsf INTCON, 7 ; Enable global interrupts
    bsf INTCON, 6 ; Enable peripheral interrupts
    bcf STATUS, 5 ; select bank 0
    return

register value while I'm debugging

07/26 Now I simplified my whole code, I still don't know where is the problem. PORTD is connected to the LED.

#include <xc.inc>
    
; CONFIG
CONFIG  FOSC = HS             ; Oscillator Selection bits (HS oscillator)
CONFIG  WDTE = OFF            ; Watchdog Timer Enable bit (WDT disabled)
CONFIG  PWRTE = OFF           ; Power-up Timer Enable bit (PWRT disabled)
CONFIG  BOREN = OFF           ; Brown-out Reset Enable bit (BOR disabled)
CONFIG  LVP = OFF             ; Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
CONFIG  CPD = OFF             ; Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
CONFIG  WRT = OFF             ; Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
CONFIG  CP = OFF              ; Flash Program Memory Code Protection bit (Code protection off)  

DELAY_A equ 0x70
DELAY_B equ 0x71
DELAY_C equ 0x72
W_TEMP equ 0x75
STATUS_TEMP equ 0x76
 
psect   RESET_VECT,class=CODE,delta=2 ; PIC10/12/16
RESET_VECT:
    goto setup
    
psect   INT_VECT,class=CODE,delta=2 ; PIC10/12/16
INT_VECT:
   movwf W_TEMP
   swapf STATUS,W
   movwf STATUS_TEMP
   btfsc PIR1, 5
   call uart_rx_isr
   swapf STATUS_TEMP,W
   movwf STATUS
   movf W_TEMP,W
   retfie

uart_rx_isr:
    movf RCREG,0
    movwf TXREG
    bcf PIR1,5
    return

setup:
    bsf STATUS,5 ; select bank 1
    movlw 25    ; Set baud rate to 9600 (assuming 4 MHz crystal)
    movwf SPBRG
    movlw 0b10000000 ; Set RC6 as output (TX) and RC7 as input (RX)
    movwf TRISC
    bcf STATUS,5 ; select bank 0
    movlw 0x90 ; Enable serial port and continuous receive
    movwf RCSTA
    bsf STATUS,5 ; select bank 1
    movlw 0x24 ; Enable transmission
    movwf TXSTA

    bsf PIE1,5   ; Enable receive interrupt
    bsf INTCON,7 ; Enable global interrupts
    bsf INTCON,6 ; Enable peripheral interrupts
    
    bsf STATUS, 5
    bcf TRISD, 0
    bcf STATUS, 5
     
main:
    bsf PORTD, 0
    goto main


END

This is my all code and values. I can not receive RCREG value and this is related to Stop Bit. So my Serail Debug Assistant is not transmiting data ?

register value Serial Debug Assistant

Upvotes: -1

Views: 99

Answers (1)

kkyleyang
kkyleyang

Reputation: 9

I find the problem. My code and RS232 are right. This test board has something wrong, so that my RCREG is always 0. After I change another test board, my RCREG can receive the data.

Upvotes: 0

Related Questions