XC8 programming - #define literal constants across different source files? - Page 1
Forum section: electronics / general

author: Delta
author_rank: Super Contributor
timestamp: November 06, 2015, 12:25:19 pm
content: First off, thanks to everyone who gave me advice about getting back into MCUs and using C. I've now got two glorious LEDs flashing away (one even using a timer and interrupts!)I have my code in several files (ie main.c, isr.c, inputs.c) to try to stop main getting unwieldly (all my old ASM projects were in one huge file!), but the compiler doesn't recognise literal constants (is that the right terminology?) across different files.For example, in main.c there isCode:#define SW1_PIN RA7but if I try to useCode:if (SW1_PIN)or suchlike in inputs.c, the compiler gives a error: (192) undefined identifier "SW1_PIN"How can I get the #defines to work across multiple files. Some kind of #include cross referencing or something? The whole reason of me wanting to use such labels is that is the physical connections to the PIC change, then I only have to change it in one place in the code, so #define-ing in every file seems daft...PS. I have no training in C, so please go easy on me!

author: spudboy488
author_rank: Regular Contributor
timestamp: November 06, 2015, 12:27:09 pm
content: Yes. Have an #include file that has all the definitions. Then include the file in each source that needs those definitions.

author: Ian.M
author_rank: Super Contributor
timestamp: November 06, 2015, 12:38:25 pm
content: *MUST* read if you are new to multi-file projects in C:http://www.gamedev.net/page/resources/_/technical/general-programming/organizing-code-files-in-c-and-c-r1798Don't bother with the newer version of the article if you use XC8 as XC8 is an ANSI C89/ISO C90 compiler (with a few C99 extensions), and the newer article is far more C++ and C99 oriented.

author: Delta
author_rank: Super Contributor
timestamp: November 06, 2015, 01:07:02 pm
content: Cheers for the tips!But it's getting even more frustrating than thatI gave up on the #defines for now, but XC8 won't even address a port pin now!It's happy with addressing the Latch bits (example "LA7" for bit 7 of LATA), but throws a wobbler if I try to use RA7. (please see screenshot)What am I doing wrong? I think I might just go back to assembler...

author: Ian.M
author_rank: Super Contributor
timestamp: November 06, 2015, 01:14:38 pm
content: Your screenshot didn't make it here!The short form SFR bit names are being depreciated and may not exist for newer devices.UsePORTAbits.RA7for bit 7 of port A,TRISAbits.TRISA7for its Tris bit, andLATAbits.LATA7for its Lat bit. The names for other bits and other ports follow the same pattern.Its more verbose, but as you should be defining a meaningful name for each pin (as you were attempting to earlier) that doesn't really matter.

author: Delta
author_rank: Super Contributor
timestamp: November 06, 2015, 01:34:19 pm
content: Spudboy - thanks mate, I've done that and it works a treat, cheers. I had tried before, but hadn't realised I needed to put the filename in quotes so the compiler could find it.Ian - cheers for the link, it's a bit over my head but I'll keep reading.Your suggestion works fine for the port pins, but it's just confusing that "LAx" works fine, but not "RAx"(screenshots added this time)

author: Ian.M
author_rank: Super Contributor
timestamp: November 06, 2015, 01:59:18 pm
content: I think the legacy name would be 'LATA7' not 'LA7', however *PLEASE* get used to the new naming convention, it will save you a lot of trouble in the future.Under XC8 you should declare main as:Code:void main(void){That should get rid of the function declared as implicit int warning.Please post code and compiler error messages in CODE tags (the [ # ] button in the full forum editor, rather than using screenshots, unless you need to show something like the red error hiliting. Just paste it between the ][ of the tage the # button gives you. Its much easier for us and you!However it can be a little difficult to match up the line numbers from the error messages with code in CODE tags for longer programs, so please tag the line(s) of code you are asking about with their line number (e.g. add// LINE nnmanually) after pasting it.O.T. I wish the programmers that write forum software would consider other programmers. Wouldn't it be nice if you could put the starting line number and filename in the opening code tag? e.g. [code=main.c,100] would display the code after it with line numbers starting from 100 and with a header 'main.c' on the code box. This forum displays a filename OK but doesn't know how to display line numbers.

author: Delta
author_rank: Super Contributor
timestamp: November 06, 2015, 03:13:33 pm
content: I shall use code tags in the future, there will be plenty of times I'm sure!Main is declared exactly as you say, but it still give the warning...!

author: Delta
author_rank: Super Contributor
timestamp: November 06, 2015, 04:11:48 pm
content: Right then, i've found what's causing theCode:main.c:20: warning: (361) function declared implicit intIt is not main(). It's the function configureSFRs() that main() is calling....The file named config.c contains the following after all the #pragma config stuffCode:void configureSFRs(void){// Setup pish ######OSCCON = 0b11010000 ; // Idle mode, INSOC=4MHz, R,R, system clock = primary// Don't think we need OSCCON2, as that's just for PLL shit (?)ANSELA = 0b00000000 ; // Port A all DIO (nae analogue)ANSELB = 0b00000000 ; // and again....ANSELC = 0b00000000 ; // duhTRISA = 0b10000000 ; // RA7 input, rest outputTRISB = 0 ;TRISC = 0 ;....blah blah...Then in main.c, main() calls that function first thing:Code:#include <xc.h>#include "defines.h"volatile unsigned long int tick_1ms =0xfffff000;volatile bit pb1, pb1_edge ; // testing the switch reading stuff// volatile bit lights_volatile unsigned char debounce_timer ;volatile unsigned long int lights_off_time ;void main(void){configureSFRs() ;static unsigned int mainloopcounter = 0 ;while(1) // MAIN LOOP{....................blah blah.......The compiler is generating the warning for the line where main()callsconfigureSFRs....The function DOES run. Do I need to declare (define?) a prototype or something somewhere?I think my complete lack of C knowledge is showing here....!

author: Delta
author_rank: Super Contributor
timestamp: November 06, 2015, 04:38:45 pm
content: To answer my own question, yes I needed to stick a prototype of configureSFRs() in main.c before main().I'm blundering my way through quite nicely!

author: Ian.M
author_rank: Super Contributor
timestamp: November 06, 2015, 05:31:28 pm
content: Good work. However prototypes are often better put in a project header or module specific header you #include. Read that link again slowly! Its also a good place to thoroughly comment what the function does and how to call it as the header(s) then act as a summary description of the program.If you don't want to bother with prototypes, the simplest way is to put the lowest level functions first in the .c file with main() and any ISRs at the end.