PIC16F1829 UART RX interrupt does not work using MPLABX and XC8 compiler

I am new to writing firmware for 8-bit PICs and can use some help with my code. I am using PIC16F1829 for an LED module that receives RX commands. I'm just trying to set up the basics of how to turn on the LEDs when a certain value is received at the RX pin, but can't even get it.

I would like to make UART work through interrupts, but I can’t even make it work with polling in the main loop. My interrupt vector is commented out in the code below.

RX pin: RC5

TX pin: RB7

Turning On / Off Indicators On / Off: RA5

Pin RA5 works great to turn LEDs on and off. The TX contact works, although I did not confirm that the TXIF interrupt also does not work, as RCIF does not work.

I tried reading RCIF and PIR1bits.RCIF. Both are compiled. None of them worked. I tried this on two different PICs on two different LED modules. They turn on, but reading the RX pin does not work either.

The RXIN variable is initially defined as 3 and, therefore, due to the RXIN cycle-- in the main loop, the indicators flash 3 times at startup, so I know that it enters the main loop. But as far as I can tell, the RCIF interrupt does not work when it receives on the RX pin.

, RX TX- , , (300 , 8N1.) , RX 5V . RCIF . - , , .

:

#include <stdio.h>
#include <stdlib.h>
#include <xc.h>

// This is for 300 baud rate
#define _BAUD_PRESCALER_LOW_ 0x2A
#define _BAUD_PRESCALER_HIGH_ 0x68
#define _XTAL_FREQ 32000000

#pragma config FOSC = INTOSC    // Oscillator Selection->INTOSC oscillator: I/O function on CLKIN pin
#pragma config WDTE = OFF    // Watchdog Timer Enable->WDT enabled
#pragma config PWRTE = OFF    // Power-up Timer Enable->PWRT disabled
#pragma config MCLRE = OFF    // MCLR Pin Function Select->MCLR/VPP pin function is digital input
#pragma config CP = OFF    // Flash Program Memory Code Protection->Program memory code protection is disabled
#pragma config CPD = OFF    // Data Memory Code Protection->Data memory code protection is disabled
#pragma config BOREN = ON    // Brown-out Reset Enable->Brown-out Reset enabled
#pragma config CLKOUTEN = OFF    // Clock Out Enable->CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin
#pragma config IESO = OFF    // Internal/External Switchover->Internal/External Switchover mode is disabled
#pragma config FCMEN = OFF    // Fail-Safe Clock Monitor Enable->Fail-Safe Clock Monitor is disabled

// CONFIG2
#pragma config WRT = OFF    // Flash Memory Self-Write Protection->Write protection off
#pragma config PLLEN = ON    // PLL Enable->4x PLL enabled
#pragma config STVREN = ON    // Stack Overflow/Underflow Reset Enable->Qaru or Underflow will cause a Reset
#pragma config BORV = LO    // Brown-out Reset Voltage Selection->Brown-out Reset Voltage (Vbor), low trip point selected.
#pragma config LVP = OFF

int flagRXFramingError = 0;
int flagRXOverrunError = 0;
volatile unsigned char RXIN = 3;

unsigned char UARTRead(){
    return RCREG;
}

void writeRXIN(unsigned char a){
    RXIN = a;
}

void TX(unsigned char a){
    while(!TXIF){}
    TXREG = a;
}

int main(int argc, char** argv) {

    // SCS FOSC; SPLLEN disabled; IRCF 8MHz_HF; 
    OSCCON = 0xF0;
    // TUN 0; 
    OSCTUNE = 0x00;
    // Set the secondary oscillator
    // Wait for PLL to stabilize
    while(PLLR == 0)
    {
    }

    // WDTPS 1:65536; SWDTEN OFF; 
    WDTCON = 0x16;
    __delay_ms(5);

    GIE = 1; // Global interrupts enabled
    __delay_ms(5);
    PEIE = 1; // Active peripheral interrupts enabled
    __delay_ms(5);
    RCIE = 1; // Enable USART Receive interrupt
    __delay_ms(5);
    TXIE = 1; // Enable USART Transmitter interrupt
    __delay_ms(5);
    ADIE = 1; // Enable ADC interrupts
    __delay_ms(5);
    RXDTSEL = 0; // RX is on RC5 pin
    __delay_ms(5);
    TXCKSEL = 0; // TX is on RB7 pin
    __delay_ms(5);

    TRISC5 = 1; // RX pin set as input
    __delay_ms(5);

    SPEN = 1; // Serial Port Enabled
    __delay_ms(5);
    SYNC = 0; // Asynchronous mode
    __delay_ms(5);
    RX9 = 0; // 8 bit reception
    __delay_ms(5);
    TX9 = 0; // 8-bit transmission
    __delay_ms(5);
    CREN = 1; // Receiver enabled
    __delay_ms(5);
    TXEN = 1; // Transmitter enabled 
   __delay_ms(5);
    BRG16 = 1; // 16-bit baud generation
    __delay_ms(5);
    BRGH = 1; // High baud rate enabled
    __delay_ms(5);
    ABDEN = 0; // Auto baud detect disabled
    __delay_ms(5);

    // Baud prescaler n = [Fosc/(D*BR)] - 1

    SPBRGH = _BAUD_PRESCALER_HIGH_;
    __delay_ms(5);
    SPBRGL = _BAUD_PRESCALER_LOW_;
    __delay_ms(5);

    TRISC6 = 0; // IadjPWM pin configured as output
    __delay_ms(5);
    ANSC6 = 0; // IadjPWM pin not analog input
    __delay_ms(5);
    TRISA5 = 0; // DimPWM pin configured as output
    __delay_ms(5);

    LATC6 = 1; // Max current for now until PWM written
    __delay_ms(5);

    while(1){

    // Inline assembly code to clear watchdog timer
    //asm("CLRWDT");

    /*if(RXIN == 5){
        RA5 = 1;
    }
    else{
        RA5 = 0;
    }*/

        if(PIR1bits.RCIF){
            writeRXIN(UARTRead());
            //RA5 = 0;
            TX(RXIN);
        } // end if RCIF

        while(RXIN > 0){
            RA5 = 1;
            __delay_ms(100);
            RA5 = 0;
            __delay_ms(100);
            RXIN--;
        }

    } 
    // infinite loop
    // never leave this loop

    RA5 = 1;
    return (EXIT_SUCCESS);
} // end main

/*void interrupt ISR(void){
    if(RCIF){// if USART Receive interrupt flag
        RA5 = 1;

        if(FERR){
            flagRXFramingError = 1;
            SPEN = 0;
            SPEN = 1;

        }
        if(OERR){
            flagRXOverrunError = 1;
            CREN = 0;
            CREN = 1;
        }

        while(RCIF){ // RCIF high as long as there is data in FIFO register. Read RCREG to clear RCIF flag
            writeRXIN(UARTRead());
        }

        RA5 = 0;
    }

    if (TXIF){// if USART Transmit interrupt
        TXIF = 0; // Clear interrupt flag
    }
} // end ISRs*/
+6
2

, , , , .

  • TXIE. TXIF , . TX-, . , TX TXIF , ?

  • , . , , , PEIE , , GIE.

  • FERR OERR , .

RXDTSEL . . , , RX , .

#include <stdio.h>
#include <stdlib.h>
#include <xc.h>

// This is for 300 baud rate
#define _BAUD_PRESCALER_LOW_ 0x2A
#define _BAUD_PRESCALER_HIGH_ 0x68
#define _XTAL_FREQ 32000000
#define _PIN_DIMPWMPIN_ RA5

#pragma config FOSC = INTOSC    // Oscillator Selection->INTOSC oscillator: I/O function on CLKIN pin
#pragma config WDTE = OFF    // Watchdog Timer Enable->WDT enabled
#pragma config PWRTE = OFF    // Power-up Timer Enable->PWRT disabled
#pragma config MCLRE = OFF    // MCLR Pin Function Select->MCLR/VPP pin function is digital input
#pragma config CP = OFF    // Flash Program Memory Code Protection->Program memory code protection is disabled
#pragma config CPD = OFF    // Data Memory Code Protection->Data memory code protection is disabled
#pragma config BOREN = ON    // Brown-out Reset Enable->Brown-out Reset enabled
#pragma config CLKOUTEN = OFF    // Clock Out Enable->CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin
#pragma config IESO = OFF    // Internal/External Switchover->Internal/External Switchover mode is disabled
#pragma config FCMEN = OFF    // Fail-Safe Clock Monitor Enable->Fail-Safe Clock Monitor is disabled

// CONFIG2
#pragma config WRT = OFF    // Flash Memory Self-Write Protection->Write protection off
#pragma config PLLEN = ON    // PLL Enable->4x PLL enabled
#pragma config STVREN = ON    // Stack Overflow/Underflow Reset Enable->Qaru or Underflow will cause a Reset
#pragma config BORV = LO    // Brown-out Reset Voltage Selection->Brown-out Reset Voltage (Vbor), low trip point selected.
#pragma config LVP = OFF

int flagRXFramingError = 0;
int flagRXOverrunError = 0;
volatile unsigned char RXIN = 3;

unsigned char RX(){
    return RCREG;
}

void writeRXIN(volatile unsigned char a){
    RXIN = a;
}

void TX(unsigned char a){
    while(!PIR1bits.TXIF); // TXIF is usually 1, only 0 when busy transmitting
    TXREG = a;
}

int main(int argc, char** argv) {

    // SCS FOSC; SPLLEN disabled; IRCF 8MHz_HF; 
    OSCCON = 0xF0;
    // TUN 0; 
    OSCTUNE = 0x00;
    // Set the secondary oscillator
    // Wait for PLL to stabilize
    while(OSCSTATbits.PLLR == 0){}

    ADCON0bits.ADON = 0;
    ANSELA = 0x00;
    ANSELB = 0x00;
    ANSELC = 0x00;
    PIE1bits.ADIE = 0; // Disable ADC interrupts

    TRISCbits.TRISC5 = 1; // RX pin set to input
    TRISCbits.TRISC6 = 0; // IadjPWM pin configured as output
    TRISAbits.TRISA5 = 0; // DimPWM pin configured as output

    LATCbits.LATC6 = 1; // Max current for now until PWM written

    //UART Init
    BAUDCONbits.BRG16 = 1; // 16-bit baud generation
    TXSTAbits.BRGH = 1; // High baud rate enabled
    BAUDCONbits.ABDEN = 0; // Auto baud detect disabled

    // Baud prescaler n = [Fosc/(D*BR)] - 1
    SPBRGH = _BAUD_PRESCALER_HIGH_;
    __delay_ms(1);
    SPBRGL = _BAUD_PRESCALER_LOW_;
    __delay_ms(1);

    APFCON0bits.RXDTSEL = 1; // RX is on RC5 pin
    APFCON0bits.TXCKSEL = 0; // TX is on RB7 pin
    TXSTAbits.SYNC = 0; // Asynchronous mode
    RCSTAbits.SPEN = 1; // Serial Port Enabled
    RCSTAbits.RX9 = 0; // 8 bit reception
    TXSTAbits.TX9 = 0; // 8-bit transmission

    RCSTAbits.CREN = 1; // Receiver enabled
    TXSTAbits.TXEN = 1; // Transmitter enabled 

    PIE1bits.TXIE = 0; // Enable USART Transmitter interrupt
    PIE1bits.RCIE = 1; // Enable USART Receive interrupt
    while(PIR1bits.RCIF){
        writeRXIN(RX());
    }

    INTCONbits.PEIE = 1; // Enable peripheral interrupts
    INTCONbits.GIE = 1; // Enable global interrupts

    while(1){
        while(RXIN > 0){
            TX(RXIN);
            _PIN_DIMPWMPIN_ = 1;
            __delay_ms(100);
            _PIN_DIMPWMPIN_ = 0;
            __delay_ms(100);
            RXIN--;
        }

    } 
    // infinite loop
    // never leave this loop
    return (EXIT_SUCCESS);
} // end main

void interrupt ISR(void){

    if(PIE1bits.RCIE && PIR1bits.RCIF){ // handle RX pin interrupts
        while(PIR1bits.RCIF){
            writeRXIN(RX());
        }
        if(RCSTAbits.FERR){
            flagRXFramingError = 1;
            SPEN = 0;
            SPEN = 1;

        }
        if(RCSTAbits.OERR){
            flagRXOverrunError = 1;
            CREN = 0;
            CREN = 1;
        }
    } // end RX pin interrupt handlers

} // end ISRs*/
0

, - . . UART.

0

All Articles