Electronic – PIC XC8 arguments redeclard

cmicrocontrollerpicxc8

I'm trying to get to know my PIC with simple 'start-up' projects.
I made a LED flash with a button.
I made a BCD count up from 0 to 9 with a delay.

Now I want to combine those two and also refractor the code a bit. So I want the BCD to increment on each button push. Ideally that would use an interupt, but not necessary for this aplication. Next step would be use the interupt and have two inputs (for up or down) and then swap the buttons for a rortary encoder.

The questions I have are:

  • where should I 'store' the current value on off the BCD? a global var in main?
  • why do I get this type redeclared error and function declared implicit int warning?

The BCD is on PORTA, the input (active low) is on PORTB.RB0
These are the two progams that actually work:

void main(void)
{
    /* Configure the oscillator for the device */
    ConfigureOscillator();

    /* Initialize I/O and Peripherals for application */
    InitApp();

    while(1)
    {
        if (PORTBbits.RB0 == 0){
            PORTAbits.RA2 = 1;
        } else {
            PORTAbits.RA2 = 0;
        }
    }
}

Note that RA2 would be connected to a normal LED.
And for the counter:

void main(void)
{
/* Configure the oscillator for the device */
ConfigureOscillator();

/* Initialize I/O and Peripherals for application */
InitApp();

// lookup table for BCD
const uint8_t pat7seg[10] = {
    // RA0:6 = ABCDEFG
    // RA7:0 = FG-EDCBA
    0b01000000, // 0
    0b11111001, // 1
    0b10000100, // 2
    0b10010000, // 3
    0b00011001, // 4
    0b00010010, // 5
    0b00000010, // 6
    0b11111000, // 7
    0b00000000, // 8
    0b00010000, // 9
};

// current digit
uint8_t digit;
digit = 0;

while(1)
{
    for(digit = 0; digit < 10; digit++){
        PORTA = pat7seg[digit];
        __delay_ms(2000);
    }
}

}

So I tried to 'combine' these like:

void main(void)
{
/* Configure the oscillator for the device */
ConfigureOscillator();

/* Initialize I/O and Peripherals for application */
InitApp();

// current digit
uint8_t digit;
digit = 0;

while(1)
{
    /* TODO <INSERT USER APPLICATION CODE HERE> */
    /*for(digit = 0; digit < 10; digit++){
        PORTA = pat7seg[digit];
        __delay_ms(2000);
    }*/
    if (PORTBbits.RB0 == 0){
        digit = updateBCD(digit);
    }
}

}

uint8_t updateBCD(uint8_t myCount) {

    /* define constant for lookup BCD */
    // common anode so, inverted
    const uint8_t pat7seg[10] = {
        // RA0:6 = ABCDEFG
        // RA7:0 = FG-EDCBA
        0b01000000, // 0
        0b11111001, // 1
        0b10000100, // 2
        0b10010000, // 3
        0b00011001, // 4
        0b00010010, // 5
        0b00000010, // 6
        0b11111000, // 7
        0b00000000, // 8
        0b00010000, // 9
    };

    if (myCount < 9){
        myCount++;
    } else {
        myCount = 0;
    }
    PORTA = pat7seg[myCount];

    return myCount;
}

errors:
(908) exit status = 1
main.c:46: warning: (361) function declared implicit int
make[2]: * [build/XC8_16F628/production/main.p1] Error 1
make[1]: *
[.build-conf] Error 2
main.c:52: error: (984) type redeclared
make: * [.build-impl] Error 2
main.c:52: error: (1098) conflicting declarations for variable "updateBCD" (main.c:52)

I use a PIC16F628 and MPLAB X IDE 2.00 with XC8 compiler.

Hope you can help.

Best Answer

In C it is best practice to use prototypes. Generally, you want to declare your function prototypes in a header file. For your code perhaps call the header file BCD.h and create it in the 'Header Files' section of MPLAB. The header file code should look something like the following:

#ifndef BCD_H
#define BCD_H

uint8_t updateBCD(uint8_t);

#endif 

then add the following line to main.c

#include "BCD.h"

Explanation: In your code when the compiler encounters the line "digit = updateBCD(digit)" the compiler does not yet know about the function updateBCD. This is the implicit declaration. Moving the declaration of updateBCD to before main helps in that the complier knows about updateBCD before it encounters "digit = updateBCD".

From a programming stand point this is still somewhat undesirable because then you have to worry about in which order to declare your functions. Aside from being annoying to the coder, it can also make the code more difficult for others to read and interpret. Using functions prototypes in header files alleviates these issues.