2
votes

I am using the following:

  • pic18f4550,
  • xc8 compiler,
  • mplab x ide v3.20,
  • a transmitter and receiver module (tested with a main program without any interruptions and works).
  • LED's connected to RD0,RD1 and RD2 (1 = light up)
  • Buttons connected to RB0,RB1 and RB2 (0 = button is pressed)//does not matter at this point

Apparently everything in this code works fine but with interrupts "void interrupt SerialComm(void)"
(I have made a program without interrupt and led lights up).

The main does not even load up; I have put "PORTD = 0x0F",
(line 3 of main program).

So if the led lights up it means that at least the 3rd line of the main program works.
(at least until that line, but the led didn't.)

Is there any register I have to disable first that I missed out for this?
Also, i have followed most tutorials could there be something i have missed?, i have seen many programs with #pragma but i'm not sure if i need then when i am using XC8 compiler.

    /*
 * File:   transmit.c
 * Author: steve 
 *
 * Created on September 25, 2016, 12:36 AM
 */
#define _XTAL_FREQ 48000000

#include <xc.h>
#include <pic18f4550.h>
void DelayMs(int x);
char ButtonsChecker();
char ButtonsCheckValue = 0; //returned value
char data_received = 0;


void main(void) {
    TRISB = 0x0F;
    TRISD = 0b00000000;

    TRISCbits.TRISC2 = 0; //TXD Power
    TRISCbits.TRISC6 = 0; //RC6 
    TRISCbits.TRISC7 = 1; //RC7
    PORTCbits.RC2 = 1;

    RCSTA = 0x90;
    TXSTA = 0x20;
    SPBRG = 77;

    RCREG = 0;
    RCIF = 0;


    PORTDbits.RD0 = 1;
    PORTDbits.RD1 = 1;
    PORTDbits.RD2 = 1;

    RCIE = 1;
    TXIE = 0;

    PEIE = 1;
    GIE = 1;

    while (1) {

        while (ButtonsChecker()) {

            TXREG = ButtonsChecker();
        }


        //while (!TRMT); // waiting for a whole data frame to be ready for a transmission
        //TXREG = PORTB;

        //while (!RCIF); // waiting for a whole data frame to be received
        //PORTD = RCREG;

    }
}

void DelayMs(int x) {
    while (x > 0) {
        __delay_ms(1);
        x--;
    }
}

char ButtonsChecker() {
    if (PORTBbits.RB0 == 0) {
        ButtonsCheckValue = 1;
    } else if (PORTBbits.RB1 == 0) {
        ButtonsCheckValue = 2;
    } else if (PORTBbits.RB2 == 0) {
        ButtonsCheckValue = 4;
    }//else if (PORTBbits.RB3 == 0) {
        // ButtonsCheckValue = 8;}
    else ButtonsCheckValue = 0;

    return (ButtonsCheckValue);
}


void interrupt ReceiveData() {
    if (RCIF == 1) {
        RCIF = 0;
        ~PORTDbits.RD1;
    }
}
1
Did you register the interrupt in the interrupt vector table?Lundin
At start you do PORTD = 0x0F, but sudden later this is overwritten by PORTD = 0x01. What is connected to PORTD.0 (lsb bit)? Check if you find a voltage on that pin (probably you will do, so you main enters the while()).linuxfan says Reinstate Monica
@linuxfan actually there are 3 pins connected to leds if bit 0 = 1 one of the led will light up,bit1 and bit 2 do the same so 0x0F all 3 will light up, but if the main program launch perfectly the 0x0F will be overwrited really fast by the 0x01 in the while loop, so the led in RD0 will light up and the rest off, but instead nothing turns on, so i am assuming it's the interrupt function i have created. //what i think is something is trapping the cpu into the interrupt function i have created, but i don't know whatSteve Quek
@Lundin i have read the XC8 C Compiler manual about writing an interrupt function and there is this one part where they say Code generated by the compiler will be placed at the interrupt vector address which will execute this function after any context switch that is required. are you refering to this?Steve Quek
I don't know this particular part, but almost every microcontroller has an interrupt vector table, which is a chunk of flash where the MCU goes looking for addresses to your ISRs. This chunk of flash can either be programmed automatically by the linker/linker script, or manually by the programmer as an array of function pointers allocated at a given address. If this vector table area is not properly programmed with the address of your ISR, and the interrupt is enabled+triggered, the MCU will attempt to jump at some garbage address, and then anything can happen. This is a very common mistake.Lundin

1 Answers

0
votes

Everything looks O.K. except that you didn't enable TX and RC interrupts. So add at USART initiation:

PIE1bits.RCIE = 1;
PIE1bits.TXIE = 1;

At the end of initiation section also add:

INTCONbits.GIE = 1; 

...to enable global interrupts.