Reputation: 21
For starters, I don't have a lot of experience using C. For a small sensor project I've been busy programming a PIC micro-controller however I've now run into the following "problem".
To make the code more readable I want to combine certain values from the PIC library into a couple of structures. To me a proper code structure would seem that I will typedef the structure I want and initialize it in a separate file from the main program and then import this into the main file. This would prevent the main code file from being cluttered with these initializations which I think is desirable.
Some pseudo code to clarify. pin_A and RESULT_A are from the PIC library:
sensor.h
// Define the structures for the individual sensor pads and the sensors.
typedef struct{
int pin;
unsigned int result;
}PAD;
typedef struct{
PAD A;
PAD B;
}SENSOR;
sensor.c
(I use sensor.c as an example here because I assume that is where the initialization should happen, but please correct me if I'm wrong.)
#include "sensor.h"
PAD PAD_A = {.pin=pin_A, .result=RESULT_A};
PAD PAD_B = {.pin=pin_B, .result=RESULT_B};
SENSOR sens = {.A=PAD_A, .B=PAD_B}
main.c
#include ... something
void main(){
// call a constructor or something
while(1){
printf(sens.A.pin); // I don't really want to print however this is an example of course.
};
To me something like this should be very common in coding however I've been unable to find helpful information on how to approach this. I assume I'm missing something obvious so please point it out.
My current workaround is to include the sensor.h file in main.c and do all the initialization there. However this makes for very cluttered and non portable code to I can't imagine that is how it should be done.
Regards,
----------------------------- Edit ------------------------------------
Because the question appears to be unclear I will try and add to it. The core of my confusion was that I was unable to define, and initialize e.t.c., certain variables when using multiple files. One method I imagine will work (though not it's not popular among many) is the use of global variables. My problem was that nearly all examples that I could find that do this provide code only in a single file and don't use header files that I believe are required to provide structure to a larger project.
For future references, in the end I have settled on the use of a constructor function as opposed to global variables. This was based on the post referenced by jonathan leffler in the comments below. I'll add the code I'm currently using pertaining to this question as an example to others. Though it is likely not the most optimized and will contain some style errors it is functional.
padDefinitions.h
/* As provided by microchip but renamed for convenience */
#define PIN_A 17
#define PIN_B 12
#define PIN_C 18
#define PIN_D 16
#define PIN_E 15
#define PIN_F 13
#define PIN_G 5
#define PIN_H 1
#define PIN_I 0
#define PIN_J 11
#define PIN_K 10
#define PIN_L 9
#define PIN_GUARD 14
#define RESULT_A &ADC1BUF17
#define RESULT_B &ADC1BUF12
#define RESULT_C &ADC1BUF18
#define RESULT_D &ADC1BUF16
#define RESULT_E &ADC1BUF15
#define RESULT_F &ADC1BUF13
#define RESULT_G &ADC1BUF5
#define RESULT_H &ADC1BUF1
#define RESULT_I &ADC1BUF0
#define RESULT_J &ADC1BUF11
#define RESULT_K &ADC1BUF10
#define RESULT_L &ADC1BUF9
#define RESULT_GUARD &ADC1BUF14
sensordef.h
/* Defines structures for the sensor pads and the sensor (which is a combination of pads) */
typedef struct PAD{
int pin; // The pin on the device the pad is connected to
volatile unsigned int current_value; // The current value of the pad
unsigned int calculated_value; // Storage for calculated (iir) value
}PAD;
typedef struct SENSOR{
PAD A;
PAD B;
PAD C;
PAD D;
PAD E;
PAD F;
PAD G;
PAD H;
PAD I;
PAD J;
PAD K;
PAD L;
}SENSOR;
/* Declare the constructor functions */
PAD PadConstructor();
SENSOR SensorConstructor();
sensordef.c
#include "sensordef.h"
#include "padDefinitions.h"
SENSOR SensorConstructor(){
/* Initialize the pads and sensor variables */
// Define all the pads
PAD PAD_A = {.pin=PIN_A, .current_value=*RESULT_A};
PAD PAD_B = {.pin=PIN_B, .current_value=*RESULT_B};
PAD PAD_C = {.pin=PIN_C, .current_value=*RESULT_C};
PAD PAD_D = {.pin=PIN_D, .current_value=*RESULT_D};
PAD PAD_E = {.pin=PIN_E, .current_value=*RESULT_E};
PAD PAD_F = {.pin=PIN_F, .current_value=*RESULT_F};
PAD PAD_G = {.pin=PIN_G, .current_value=*RESULT_G};
PAD PAD_H = {.pin=PIN_H, .current_value=*RESULT_H};
PAD PAD_I = {.pin=PIN_I, .current_value=*RESULT_I};
PAD PAD_J = {.pin=PIN_J, .current_value=*RESULT_J};
PAD PAD_K = {.pin=PIN_K, .current_value=*RESULT_K};
PAD PAD_L = {.pin=PIN_L, .current_value=*RESULT_L};
// Define a variable for the sensor
SENSOR sensor = {
.A=PAD_A, .B=PAD_B, .C=PAD_C,
.D=PAD_D, .E=PAD_E, .F=PAD_F,
.G=PAD_G, .H=PAD_H, .I=PAD_I,
.J=PAD_J, .K=PAD_K, .L=PAD_L,
};
return sensor;
}
main.c
int16_t main(void){
#include "sensordef.h"
/* ... Initialization code for the PIC ... */
SENSOR sensor;
sensor = SensorConstructor();
while(1)
{
/* ... Perform measurements ... */
}
}
Upvotes: 0
Views: 3361
Reputation: 21
As jonathan leffler pointed out in the comments. How do I use extern to share variables between source files in C? provides ample information on regarding my question. It provides a clear, and very lengthy, example of how to use multiple files for declaration and definition of variables.
Thank you Jonathan. (+1 from me if I had the reputation to do so)
Upvotes: 1
Reputation: 211278
You can write an extern
variable declaration into your sensor.h
file:
sensor.h
…other definitions…
typedef struct{
PAD A;
PAD B;
} SENSOR;
extern SENSOR sens;
main.c
#include "sensor.h"
Now the compiler knows that there is a global variable sens
with type SENSOR
.
Upvotes: 1