Forum: Mikrocontroller und Digitale Elektronik #define in Header oder *.c-Datei?


von Michael S. (michl-s)


Lesenswert?

Wenn ihr "#define"-Ausdrücke habt, die sich nur auf Funktion in einer
einzigen *.c-Datei beziehen, wo deklariert ihr diese dann? In der
*.c-Datei oder im zugehörigen Header, welcher auch von anderen Funktion
inkludiert wird?
Letzer Fall würde ja bedeuten, dass diese "defines" auch in den
inkludierenden Dateien bekannt wäre.
Und wie sieht das ganze mit (Datei-lokalen) Variablen und Structs aus?
Auch alle direkt in die *.c-Datei?

Danke.

Edit: Ich geb hier mal ein Beispiel:

Datei: hw_LCD.h
1
#ifndef __HW_LCD_H__
2
#define __HW_LCD_H__
3
4
5
/*****************************************/
6
/************** Definitions **************/
7
/*****************************************/
8
// Control Signal Data Pins
9
#define  LCD_RS    LATDbits.LATD8      // LCD RS signal
10
#define LCD_RW    LATDbits.LATD9      // LCD R/W signal
11
#define LCD_1_EN   LATDbits.LATD10    // LCD_1 E signal 
12
#define LCD_2_EN  LATDbits.LATD10   // LCD_1 E signal 
13
#define LCD_3_EN  LATDbits.LATD10      // LCD_1 E signal 
14
15
// LCD Addresses
16
#define  LCD_START_LINE1  0x00  
17
#define  LCD_START_LINE2  0x40
18
#define  LCD_START_LINE3  0x14
19
#define  LCD_START_LINE4  0x54
20
21
// Data Signals and Pin Direction
22
#define LCD_DATA       LATD               // Port for LCD data
23
#define LCD_IO_CNTRL  TRISD
24
25
// LCD Maximum Positions (beginning with 0)
26
#define LCD_MAX_Y    1
27
#define LCD_MAX_X    15
28
29
// Lines (beginning with 0)
30
#define LINE1  0
31
#define LINE2  1
32
#define LINE3  2
33
#define LINE4  3
34
35
// PutStr-Controls
36
#define  CONTINOUS    0
37
#define  LIMITED      1
38
39
// Structure LCD Line
40
typedef struct {
41
  unsigned char X;
42
  unsigned char Y;
43
}TYPE_LCD_CURSORS;
44
45
// Structure LC-Display
46
typedef struct {
47
  TYPE_LCD_CURSORS Cursor;
48
  unsigned int En  :1;
49
  unsigned int ID  :3;
50
  unsigned    :4;
51
}TYPE_LC_DISPLAY;
52
53
54
55
/*****************************************/
56
/*********** Global Variables ************/
57
/*****************************************/
58
59
60
61
/*****************************************/
62
/********** Function Prototypes **********/
63
/*****************************************/
64
65
// Macros
66
/*****  LCD COMMAND FUCNTION PROTOTYPES  *****/
67
#define __hw_LCD_Cursor_R(lcd)      hw_Cmd_LCD (0x0014, lcd)
68
#define __hw_LCD_Cursor_L(lcd)      hw_Cmd_LCD (0x0010, lcd)
69
#define __hw_LCD_Cursor_Invisible(lcd)  hw_Cmd_LCD (0x000C, lcd)
70
#define __hw_LCD_Cursor_Underline(lcd)  hw_Cmd_LCD (0x000E, lcd)
71
#define __hw_LCD_Display_Shift(lcd)    hw_Cmd_LCD (0x001C, lcd)
72
#define __hw_LCD_Display_Blank(lcd)    hw_Cmd_LCD (0x0008, lcd)
73
#define __hw_LCD_Home_Clr(lcd)      hw_Cmd_LCD (0x0001, lcd)
74
#define __hw_LCD_Home_It(lcd)      hw_Cmd_LCD (0x0002, lcd) 
75
#define __hw_LCD_Line_2(lcd)      hw_Cmd_LCD (0x00C0, lcd)
76
#define __hw_LCD_Scroll_R_All(lcd)     hw_Cmd_LCD (0x001E, lcd)
77
#define __hw_LCD_Scroll_L_All(lcd)     hw_Cmd_LCD (0x0018, lcd)
78
#define __hw_LCD_Blinking_Block(lcd)  hw_Cmd_LCD (0x000F, lcd)
79
80
81
// Functions
82
/******  LCD FUNCTION PROTOYPES ******/
83
void hw_Open_LCD         (TYPE_LC_DISPLAY *Lcd);                    // initialize display    
84
void hw_Cmd_LCD       (unsigned int Cmd, TYPE_LC_DISPLAY *Lcd);          // write command to lcd
85
void hw_Data_LCD      (unsigned int Data, TYPE_LC_DISPLAY *Lcd);        // write data to lcd
86
void hw_PutStr_LCD    (unsigned int Op_Mode, unsigned char *Data, unsigned int Chars_to_Put, TYPE_LC_DISPLAY *Lcd);
87
void hw_Enable_LCD    (TYPE_LC_DISPLAY *Lcd);
88
void hw_Disable_LCD      (TYPE_LC_DISPLAY *Lcd);
89
void hw_RegisterID_LCD   (TYPE_LC_DISPLAY *Lcd, unsigned int LCD_Nr);
90
void hw_Gotoxy_LCD     (unsigned char X, unsigned char Y, TYPE_LC_DISPLAY *Lcd);
91
void hw_Clear_LCD     (TYPE_LC_DISPLAY *Lcd);
92
int hw_ReadBusyFlag_LCD (TYPE_LC_DISPLAY *Lcd);
93
94
95
#endif //__HW_LCD_H__

Wäre das struct TYPE_LC_DISPLAY dann auch in allen anderen Dateien 
bekannt, die diese Datei inkludieren?
Eigentlich ja nicht, da hier nur die Typdefinition stattfindet, oder?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Michael S. schrieb:
> Wäre das struct TYPE_LC_DISPLAY dann auch in allen anderen Dateien
> bekannt, die diese Datei inkludieren?

Das ist ein typedef, also nur eine Typdefinitioni, und die ist dann 
überall dort bekannt, wo die Headerdatei eingebunden wird.

Und das muss auch so sein, denn sonst lassen sich die darauffolgenden 
Funktionsprototypen nicht verwenden.

von Karl H. (kbuchegg)


Lesenswert?

Michael S. schrieb:
> Wenn ihr "#define"-Ausdrücke habt, die sich nur auf Funktion in einer
> einzigen *.c-Datei beziehen, wo deklariert ihr diese dann? In der
> *.c-Datei oder im zugehörigen Header, welcher auch von anderen Funktion
> inkludiert wird?

Die Grundregel sollte sein:
Immer im kleinsten Scope (Sichtbarkeitsbereich), der möglich ist. (Mit 
#define machen die meisten insofern eine Ausnahme, dass sie am Anfang 
der Datei zusammengezogen werden)

Wenn eine Struktur ausschliesslich nur in einer Funktion benötigt wird, 
dann kommt sie auch in diese Funktion.

Wenn alle Funktionen eines Moduls dieselbe Struktur benötigen UND alle 
Funktionen in einem *.c File zusammengezogen sind, dann kommt die 
Strukturdefinition an den Anfang dieses *.c Files.

Wenn das nicht geht, weil zb mehrere *.c Files diese Struktur benötigen, 
dann kommt sie in ein Header File.

Aber grundsätzlich möchte man haben, dass die Sichtbarkeit auf das 
allernotwendigste Minimum eingeschränkt wird. Dadurch kann man 
gewährleisten, dass es zu möglichst wenigen unbeabsichtigten 
Nebeneffekten kommt.

Wenn eine Struktur im externen Headerfile benötigt wird, aber nur in der 
Form, dass der Benutzer eines Moduls nur einen Pointer von einer 
Funktion bekommt und andere Funktionen wiederrum mit diesem Pointer 
füttern muss, dann kann man auch mittels einer Forward-Deklaration den 
Compiler insofern zufrieden stellen, dass zwar beim Modulverwender 
bekannt ist, dass es eine Struktur mit einem bestimmten Namen gibt, die 
Details des Strukturaufbaues allerdings nicht im Header File 
aufscheinen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.