• AVR Freaks

Hot!EUSART Help

Author
walkev
New Member
  • Total Posts : 6
  • Reward points : 0
  • Joined: 2020/06/14 11:04:21
  • Location: 0
  • Status: offline
2020/07/12 12:24:48 (permalink)
0

EUSART Help

Greetings,
I have been trying to establish a simple one-way USART communication between two PIC16 devices(PIC16f887 - sender and PIC16f18877 - receiver), but keep receiving a Framing Error.
 
I have done the following:
- interrupt routines for each device that contain the main transmitting/receiving schemes.
- set up a BAUD rate of 9600 in each by placing 25 in the SPBRGL reg and 0 in the SPBRGH register, with BAUDH high and BAUD16 low.
- set up a 4Mhz internal oscillator in each device, where my multimeter measures a maximum of 1.003 Mhz in the receiver(16f18877) and minimum of 0.998 Mhz in the sender(16f887). Also, I have cleared the OSCTUNE register in the 18877 to minimize the frequency. There is no such oscillator adjustment in the 887.
 
The data to be transmitted in stored in addresses starting at 70h, and the received data should be stored in the same addresses.
 
I do understand that a framing error is caused due to the lack of a "stop" bit, but I do not understand why this is an issue in my code(attached below).
 
;******************************************************************************
; RECEIVER
; Microcontroller: PIC 16f18877
; Creator: Vedhas Walke
;******************************************************************************



; PIC16F18877 Configuration Bit Settings

; Assembly source line config statements


#include "p16f18877.inc"


; CONFIG1
; __config 0x1E8C
 __CONFIG _CONFIG1, _FEXTOSC_OFF & _RSTOSC_HFINT32 & _CLKOUTEN_ON & _CSWEN_ON & _FCMEN_OFF
; CONFIG2
; __config 0x2F3F
 __CONFIG _CONFIG2, _MCLRE_ON & _PWRTE_OFF & _LPBOREN_OFF & _BOREN_OFF & _BORV_LO & _ZCD_OFF & _PPS1WAY_ON & _STVREN_OFF
; CONFIG3
; __config 0x3F9F
 __CONFIG _CONFIG3, _WDTCPS_WDTCPS_31 & _WDTE_OFF & _WDTCWS_WDTCWS_7 & _WDTCCS_SC
; CONFIG4
; __config 0xFFF
 __CONFIG _CONFIG4, _WRT_OFF & _SCANE_not_available & _LVP_OFF
; CONFIG5
; __config 0x3FFF
 __CONFIG _CONFIG5, _CP_OFF & _CPD_OFF





   
    list p=16f18877
   

FIRST_MESSAGE_ADR EQU 0x70
LAST_CHAR EQU "/"


    ORG 0x00
    GOTO SETUP
    ORG 0x04
    GOTO ISR




;******************************************************************************

ISR


    BANKSEL PIR3
    BTFSC PIR3, 5
    GOTO RECEIVE_ROUTINE
    RETFIE
   
RECEIVE_ROUTINE
   
    ; check for errors
    CLRF WREG
    BANKSEL RC1STA
    BTFSC RC1STA, 2
    BSF WREG, 0
    BTFSC RC1STA, 1
    BSF WREG, 1
    BANKSEL LATA
    MOVWF LATA ; error signal on PORTA
   
   
    ; send received data to current FSR position
    BANKSEL RC1REG
    MOVFW RC1REG
    MOVWF INDF0
   
    INCF FSR0, 1
   
   
   
    RETFIE

;******************************************************************************




SETUP
    ; oscillator
    BANKSEL OSCFRQ
    MOVLW B'00000010'
    MOVWF OSCFRQ
   
    BANKSEL OSCTUNE
    CLRF OSCTUNE
   
   
    ; digital vs analog
    BANKSEL ANSELA
    CLRF ANSELA ; error
    CLRF ANSELB ; sender enable
    CLRF ANSELC ; USART's rx pin
    CLRF ANSELD ; output one received character
   
   
    ; input vs output
    BANKSEL TRISA
    CLRF TRISA
    CLRF TRISB
    CLRF TRISC
    COMF TRISC ; input for USART receive
    CLRF TRISD
   
    ; preconditions for ports
    BANKSEL LATA
    CLRF LATA ; RA0 is error flag
    CLRF LATB ; RB0 to tell sender to begin sending
    CLRF LATC
    CLRF LATD ; output specified character to check for accuracy of transmission & reception

    ; preconditions for GPRs
   
   
    ; USART transmit setup
    BANKSEL RC1STA
    BSF RC1STA, 7
    BCF TX1STA, 4

; Baud Rate
    BANKSEL SP1BRG
    MOVLW D'25'
    MOVWF SP1BRGL
    CLRF SP1BRGH
    BANKSEL TX1STA
    BSF TX1STA, 2
   
   
; interrupt
    BANKSEL PIE3
    BSF PIE3, 5
    BSF INTCON, 6
   
   
; first location for storage
    MOVLW FIRST_MESSAGE_ADR
    MOVWF FSR0

    BANKSEL RC1STA
    BSF RC1STA, 4
    BSF INTCON, 7
   
   
;******************************************************************************

 


   
    BANKSEL LATB
MAIN
   
    MOVFW 0x73
    MOVWF LATD
   
    GOTO MAIN
   
   
   
   
   
   

   
 
   
   
    end

 
;******************************************************************************
; SENDER
; Microcontroller: PIC 16f887
; Creator: Vedhas Walke
;******************************************************************************


    #include "p16f887.inc"

; CONFIG1
; __config 0x23E5
 __CONFIG _CONFIG1, _FOSC_INTRC_CLKOUT & _WDTE_OFF & _PWRTE_ON & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_ON & _IESO_OFF & _FCMEN_OFF & _LVP_OFF
; CONFIG2
; __config 0x3FFF
 __CONFIG _CONFIG2, _BOR4V_BOR40V & _WRT_OFF

   
    list p=16f887
   
   
MESSAGE1A EQU 0x70
MESSAGE1B EQU 0x71
MESSAGE1C EQU 0x72
MESSAGE1D EQU 0x73
MESSAGE1E EQU 0x74
MESSAGE1F EQU 0x75
LAST_MESSAGE_ADR EQU 0x71 ; This is the adress of the final message PLUS ONE


    ORG 0x00
    GOTO SETUP
    ORG 0x04
    GOTO ISR




;******************************************************************************

ISR
    
    BANKSEL PIR1
    BTFSC PIR1, 4
    GOTO TRANSMIT_ROUTINE
    RETFIE
   
TRANSMIT_ROUTINE
   
    BANKSEL TXREG ;{
    MOVFW INDF
    MOVWF TXREG ;}^ current message transmitted
   
    BANKSEL PIE1 ;{
    INCF FSR, 1
    MOVLW LAST_MESSAGE_ADR
    SUBWF FSR, 0
    BTFSC STATUS, 2
    BCF PIE1, 4 ;}^ is there another message to be sent?
   
    BCF STATUS, 5 ; PORTA BANKSEL
    BTFSC STATUS, 2
    BSF PORTA, 7 ; transmission has ended
   
    ; Padding {
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    ; }
   
    RETFIE

;******************************************************************************






SETUP
    ; digital vs analog
    BANKSEL ANSEL
    CLRF ANSEL
    CLRF ANSELH
   
   
    ; input vs output
    BANKSEL TRISA
    CLRF TRISC
    CLRF TRISA
   
    ; preconditions for ports
    BANKSEL PORTA
    CLRF PORTC
    CLRF PORTA


    ; preconditions for GPRs
   
   
    ; USART transmit setup
    BANKSEL TXSTA
    BCF TXSTA, 4
   
    BANKSEL RCSTA
    BSF RCSTA, 7
   
    ; USART transmit setup
    MOVLW "a"
    MOVWF MESSAGE1A
    MOVLW "m"
    MOVWF MESSAGE1B
    MOVLW "p"
    MOVWF MESSAGE1C
    MOVLW "l"
    MOVWF MESSAGE1D
    MOVLW "e"
    MOVWF MESSAGE1E
    MOVLW "/"
    MOVWF MESSAGE1F

; Baud Rate
    BANKSEL BAUDCTL
    CLRF BAUDCTL
    BANKSEL SPBRG
    MOVLW D'25'
    MOVWF SPBRG
    BANKSEL TXSTA
    BSF TXSTA, 2
   
   
; interrupt
    BANKSEL PIE1
    BSF PIE1, 4
    BANKSEL INTCON
    BSF INTCON, 6
   
   
; first message
    MOVLW MESSAGE1A
    MOVWF FSR

    BANKSEL TXSTA
    BSF TXSTA, 5


; delay loop to ensure that receiver is ready
    MOVLW 0x45
    MOVWF 0x20
DELAY
    DECFSZ 0x20
    GOTO DELAY



    BANKSEL INTCON
    BSF INTCON, 7
;******************************************************************************

 


   

MAIN
    NOP
    GOTO MAIN
   
   
   
   
   
   

   
 
   
   
    end

 
I would really appreciate any help.
 
 
Regards,
Vedhas Walke
#1

8 Replies Related Threads

    davea
    Super Member
    • Total Posts : 270
    • Reward points : 0
    • Joined: 2016/01/28 13:12:13
    • Location: Tampa Bay FL USA
    • Status: offline
    Re: EUSART Help 2020/07/12 13:15:54 (permalink)
    +2 (2)
    I do understand that a framing error is caused due to the lack of a "stop" bit

    more likely incorrect baud rate of send or receive data
    if you have a scope look at bit timing
    or uart on PC then check TX data
    and send chr's to RX data
    one of them is incorect 
    #2
    ric
    Super Member
    • Total Posts : 27929
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: EUSART Help 2020/07/12 13:28:20 (permalink)
    +2 (2)
    [1] Don't use interrupts until you understand how they work. You can just poll the TXIF bit in your non-interrupt code with the TXIE bit cleared. It ius common to use interrupts for receive, but much less common to use them for transmit. It is possible to do it all without interrupts, depending upon what else the code needs to do while waiting to receive characters.
    [2] When you do start using interrupts, read what the datasheet has to say about "context saving". This interrupt code will cause your non-interrupt code to crash if it is anything more than a "do nothing" loop like you have now.
    [3] When you do start using interrupts, do NOT put a "GOTO ISR" at the reset vector. You must not do a GOTO until you have done the context saving, and cleared the PCLATH register.
    [4] When you do start using interrupts, do NOT attempt to send more than one character at a time. The essence of a good ISR is you do the minimum possible to clear the interrupt condition, and get out again ASAP.
     
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #3
    walkev
    New Member
    • Total Posts : 6
    • Reward points : 0
    • Joined: 2020/06/14 11:04:21
    • Location: 0
    • Status: offline
    Re: EUSART Help 2020/07/12 16:44:07 (permalink)
    0
    Hi davea,
    I do not have a scope, but based on the baud rate settings given, shouldn't the baud rates be the same?
     
    Good day ric,
    [1] I will change the sender code to eliminate interrupts. This makes sense. On the other hand, I think that this interrupt scheme is requisite. I am using interrupts to ensure precise timing, which I feel is the lacking aspect here(framing error).
    [2]Thank you for reminding me of the possibility of a crash in the 887 code, because there isn't automatic context saving. I will make sure to add code to manually reset the bank in this ISR. I am still under the impression that the 18877 interrupt is fine as it is, and please correct me if this is incorrect.
    [3] I am afraid I do not understand this point. Can you please elaborate?
    [4] Thanks for this note, I will reduce the receive ISR and eliminate the sender ISR.
     
    I request guidance, though, on the framing error issue that I have been unable to overcome.
     
    Thanks,
    Vedhas Walke
    #4
    ric
    Super Member
    • Total Posts : 27929
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: EUSART Help 2020/07/12 16:58:19 (permalink)
    +2 (2)
    walkev
    [1] I will change the sender code to eliminate interrupts. This makes sense. On the other hand, I think that this interrupt scheme is requisite. I am using interrupts to ensure precise timing, which I feel is the lacking aspect here(framing error).

    I suspect you are wrong.
     

    [2]Thank you for reminding me of the possibility of a crash in the 887 code, because there isn't automatic context saving. I will make sure to add code to manually reset the bank in this ISR. I am still under the impression that the 18877 interrupt is fine as it is, and please correct me if this is incorrect.

    No it is not. Did you follow my advice yet, and read what the PIC16F887 datasheet tells you about "context saving" ?
    (I didn't notice your receiver is a PIC16F18887. That is a much newer device that DOES do an automatic save and restore of several registers during an interrupt service)
     

    [3] I am afraid I do not understand this point. Can you please elaborate?

    As I said. Do NOT put a "GOTO ISR" instruction at location 0x0004. Put the ISR code itself right there.
    You must NOT do a GOTO until the PCLATH register has been saved, and cleared.
    This won't cause a problem until your program grows larger, and starts using multiple banks of program memory.
     
    Do you have access to an oscilloscope to check the waveform coming out the TX pin?
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #5
    walkev
    New Member
    • Total Posts : 6
    • Reward points : 0
    • Joined: 2020/06/14 11:04:21
    • Location: 0
    • Status: offline
    Re: EUSART Help 2020/07/12 17:49:37 (permalink)
    0
    Hello ric,
    Yes, I did read the datasheet, I just did not mention it. This is why I said that the context saving should be ok in the 18877. This is also why I just rewrote the 887 code in accord with your suggestions:
     
     
    ;******************************************************************************
    ; SENDER
    ; Microcontroller: PIC 16f887
    ; Creator: Vedhas Walke
    ;******************************************************************************


        #include "p16f887.inc"

        ; CONFIG1
        ; __config 0x20D4
        __CONFIG _CONFIG1, _FOSC_INTRC_NOCLKOUT & _WDTE_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_OFF & _IESO_OFF & _FCMEN_OFF & _LVP_OFF
        ; CONFIG2
        ; __config 0x3FFF
        __CONFIG _CONFIG2, _BOR4V_BOR40V & _WRT_OFF

        
        list p=16f887
        
        
    MESSAGE1A EQU 0x70
    MESSAGE1B EQU 0x71
    MESSAGE1C EQU 0x72
    MESSAGE1D EQU 0x73
    MESSAGE1E EQU 0x74
    MESSAGE1F EQU 0x75
    LAST_MESSAGE_ADR EQU 0x76 ; This is the adress of the final message PLUS ONE


        ORG 0x00
        GOTO SETUP





    ;******************************************************************************







    SETUP
        ; digital vs analog
        BANKSEL ANSEL
        CLRF ANSEL
        CLRF ANSELH
        
        
        ; input vs output
        BANKSEL TRISA
        CLRF TRISC
        CLRF TRISA
       
        ; preconditions for ports
        BANKSEL PORTA
        CLRF PORTC
        CLRF PORTA


        ; preconditions for GPRs
        
        
        ; USART transmit setup
        BANKSEL TXSTA
        BCF TXSTA, 4
        
        BANKSEL RCSTA
        BSF RCSTA, 7
        
        ; USART transmit setup
        MOVLW "a"
        MOVWF MESSAGE1A
        MOVLW "m"
        MOVWF MESSAGE1B
        MOVLW "p"
        MOVWF MESSAGE1C
        MOVLW "l"
        MOVWF MESSAGE1D
        MOVLW "e"
        MOVWF MESSAGE1E
        MOVLW "/"
        MOVWF MESSAGE1F
     
     ; Baud Rate
     BANKSEL BAUDCTL
     CLRF BAUDCTL
     BANKSEL SPBRG
     MOVLW D'25'
     MOVWF SPBRG
     BANKSEL TXSTA
     BSF TXSTA, 2
        

        
        
     ; first message
     MOVLW MESSAGE1A
     MOVWF FSR
     
     BANKSEL TXSTA
     BSF TXSTA, 5
     
     
     ; delay loop to ensure that receiver is ready
     MOVLW 0x45
     MOVWF 0x20
    DELAY
     DECFSZ 0x20
     GOTO DELAY
     
     
     
    ;******************************************************************************

     
     
    TRANSMIT
        BANKSEL TXREG ;{
        MOVFW INDF
        MOVWF TXREG ;}^ current message transmitted
        
        BANKSEL PIE1 ;{
        INCF FSR, 1
        MOVLW LAST_MESSAGE_ADR
        SUBWF FSR, 0
        BCF STATUS, 5 ; PORTA BANKSEL
        BTFSC STATUS, 2
        BSF PORTA, 7 ; transmission has ended
        
        BANKSEL PIR1
    WAIT
        BTFSS PIR1, 4
        GOTO WAIT
        
        BANKSEL PORTA
        BTFSS PORTA, 7
        GOTO TRANSMIT
       

    MAIN
        NOP
        GOTO MAIN
        
        
        end


     
    Unfortunately, I do not own an oscilloscope; I'm stuck with a multimeter. Nonetheless, if the settings for baud rate are as follows:
     
    For both:
    SPBRG = 25
    BRGH  = 1
    BRG16 = 0
     
    sender fosc ~=0.998*4 = 3.992 Mhz
    receiver fosc ~= 1.003*4 = 4.012 Mhz
     
    True Baud Rate for sender ~= 3.992/(16*(25+1)) = 9596
    Baud Rate error for receiver ~= 4.012/(16*(25+1)) = 9644
     
    Maybe what I am trying to ask is:
    What is the "error threshold" for the baud rate between two devices?
    #6
    upand_at_them
    Super Member
    • Total Posts : 576
    • Reward points : 0
    • Joined: 2005/05/16 07:02:38
    • Location: Pennsylvania
    • Status: online
    Re: EUSART Help 2020/07/12 18:15:54 (permalink)
    +2 (2)
    Your receive routine accesses FSR0, but that register is part of context saving in the PIC16F18877.
    #7
    walkev
    New Member
    • Total Posts : 6
    • Reward points : 0
    • Joined: 2020/06/14 11:04:21
    • Location: 0
    • Status: offline
    Re: EUSART Help 2020/07/12 18:42:08 (permalink)
    0
    hey upand_at_them,
    Nice catch man, you saved me from wasting a few hours trying to figure out why all were being received at location 0x70.
     I added the following lines at the end of the ISR to fix it:
    MOVFW FSR0
    BANKSEL FSR0L_SHAD
    MOVFW FSR0L_SHAD

     
    Unfortunately, I am still stuck on the framing error.
    #8
    walkev
    New Member
    • Total Posts : 6
    • Reward points : 0
    • Joined: 2020/06/14 11:04:21
    • Location: 0
    • Status: offline
    Re: EUSART Help 2020/07/13 10:08:00 (permalink)
    0
    Ok
    So, I adjusted the voltages supplied to each chip by directly connecting power rails and adding small resistors, and it finally seems to half work.
     
    Most of the time, my message sends, but it is preluded by some garbage, which varies in size. If this cannot go away, there is the obvious choice of including a start and end character, but if anyone has any idea of why this issue in present, please let me know.
     
    I feel like the main problem was, in fact, the small difference in baud rate caused by voltage fluctuations. So, when actually implementing this, I will consider an external oscillator.
     
    Vedhas Walke
    post edited by walkev - 2020/07/13 10:10:04
    #9
    Jump to:
    © 2020 APG vNext Commercial Version 4.5