• Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

PIC UART Check OERR

Status
Not open for further replies.

Suraj143

Active Member
Guys I'm receiving AT commands from a GSM modem & reading it from a PIC 16F628A.

The problem is the receiving buffer gets stuck when receiving responses from GSM modem.

After adding the OERR bit test loop the problem solved.

I need to know where is the best place to place this error check in code? For now I placed them in the main loop.Is it ok?

What about placing in the ISR?

Do I also need to check framing errors as well?

Code:
        org    0x0004
ISR_Enter    ----
        ----
        btfss    PIR1,RCIF
        goto    ISR_Exit
        movf    RCREG,W            ; save the new character
        movwf    RC_Buffer
        ----
        ----

ISR_Exit

Main_Loop    btfss    RCSTA,OERR        ;check for overun errors
        goto    Continue_Main
        movf    RCREG,W            ; reset OERR
        movf    RCREG,W
        bcf    RCSTA,CREN
        bsf    RCSTA,CREN
 

Pommie

Well-Known Member
Most Helpful Member
The problem is that if you're getting OERRs then you are loosing bytes. Why not setup an IRQ and a fifo buffer to prevent overflow errors? If you need code for a fifo then let me know.

Mike.
 

Pommie

Well-Known Member
Most Helpful Member
Here you go, add the variables to your variable, add an interrupt and put the first bit of code.
To use it, just call GetFifo and if the Zero flag is set then W has the received byte.
Note, FifoLength must be a either 16,32,64 etc.
Code:
FifoLength        equ        10h

                cblock        020h        ;must be on 16 byte boundary
FifoBuffer:FifoLength                ;16 byte input buffer
FifoStart
FifoEnd
                endc

;code for in ISR               
;no test for fifo full.
                btfss        PIR1,RCIF        ;cleared automatically
                goto         NoReceive1
                movfw        FifoEnd
                addlw        low(FifoBuffer)
                movwf        FSR                ;indirect addr
                movfw        RCREG
                movwf        INDF
                movfw        FifoEnd
                addlw        1
                andlw        FifoLength-1        ;make wrap
                movwf        FifoEnd
NoReceive        ;rest of ISR
              
;check if byte available               
;returns with zero flag set if empty
;else has value in W
GetFifo
                movfw        FifoStart
                subwf        FifoEnd,W
                btfsc        STATUS,Z
                return                        ;zero flag set
                movfw        FifoStart
                addlw        low(FifoBuffer)
                movwf        FSR
                movfw        FifoStart
                addlw        1
                andlw        FifoLength-1
                movwf        FifoStart
                movfw        INDF
                bcf          STATUS,Z
                return
Mike.
 

Suraj143

Active Member
Hi mike.

Can this also called a fifo buffer?
Code:
        movf        S_FSR,W
                movwf       FSR
                movf        RC_Buffer,W
                movwf       INDF
                incf        S_FSR,F
                movf        S_FSR,W
                xorlw       70h
                btfss       STATUS,Z
                goto        ISR_Exit
Reset_Bytes     movlw       50h
                movwf        _FSR
            ;
ISR_Exit
 

Pommie

Well-Known Member
Most Helpful Member
Yes, that is a fifo buffer located at 0x50 and going to 0x6f. The variable S_FSR is the equivalent of my FifoEnd variable. There will have to be additional code to check and remove bytes from the buffer.

Mike.
 

Mosaic

Well-Known Member
I just did a 16F887 processor PIC 2 PIC- RS232, 1 wire , TX - Rx protocol to move 32 digital channels (GPIO) over the RS232 to 'mirror' on the rcvr.

Well, asynchronous RS232 leads to data loss due to non sync'd processor clocks, so I included a check sum to reject bad data. The stock transfer averaged around 75% good data. Usable but it bugged me.

So, I created a slow s'ware PLL to correct and get a 100% data rate. Basically I set the recvr OSCTUNE setpoint a little fast and then used the cumulative data error rate to slowly correct downward until a stable 100% data rate was 'locked' in.
The phase lock takes about 30 seconds as it has to be done slowly to not 'miss' the correct tune point as i didn't want to do a whole PID code for the job. About 12 asm instructions overall.
 

NorthGuy

Well-Known Member
You can detect baud rate by measuring the duration of the data bits, then adjust OSCTUNE accordingly. If you can receive a known character such as 0x55 then it's really easy. Otherwise, it'll take a number of characters to figure out.
 
Status
Not open for further replies.

Latest threads

EE World Online Articles

Loading
Top