Forum: Mikrocontroller und Digitale Elektronik Verwaltung von Pins und Peripherie global oder lokal


von Karl (Gast)


Lesenswert?

Hallo Zusammen,

seit einigen Tage treibt mich die Frage um, wie man die Pinzuweisungen 
(und Peripheriebelegung) am besten handhabt. Für mich gibt es 2 
offensichtliche Möglichkeiten:

- "global": Es gibt genau eine Stelle im Projekt, in der alle 
Pinzuweisungen und Peripherieinitialisierungen vorgenommen werden. 
Vorteil: Es ist alles an einem Fleck und man erspart sich evtl. das 
Pflegen einer separaten Liste (z.B. in Excel). Nachteil: Wenn eine Modul 
von einem Projekt in ein anderes übernommen wird, muss man das recht 
manuell nachziehen,

- "lokal": Jedes Modul kümmert sich selbst um die Initialisierung. 
Vorteil: Die Übernahme eines Moduls in ein anderes Projekt ist mit 
weniger Schreibarbeit verbunden, die Kapselung besser. Nachteil: Man 
muss fast eine externe Liste über die Verwendung pflegen (was früher 
oder später schief gehen wird).


Wie handhabt Ihr das?

VG
Karl

von Walter T. (nicolas)


Lesenswert?

Ich habe von der lokalen Variante auf die globale gewechselt; sprich, in 
jedem Projekt gibt es eine "ioconfig.h". So lassen sich die 
Pinbelegungen beim Routen direkt anpassen (und es ist sofort 
ersichtlich, bei welchen Pinbelegungen das überhaupt geht). Und hat den 
Nachteil daß ich bei der Nutzung von Fremdquelltext diesen erst einmal 
anpassen muß.

Aber das ist wie eine Frage, an welcher Seite man das Ei am besten 
aufschlägt (big endian oder little endian). Die Musterantwort kennt 
vermutlich niemand.

Viele Grüße
Nicolas

von Stefan (Gast)


Lesenswert?

Ich mache das global.

von Cyblord -. (cyblord)


Lesenswert?

Deine beiden Möglichkeiten sind schon falsch und bringen einiges 
durcheinander.

1.
Portzuweisungen und Zuweisung von anderen Ressourcen sollten natürlich 
global sein, sonst hat man redundanten Code und muss für eine 
Portänderung an zig Stellen was ändern.

2.
Initalisierung von Peripherie sollte schon das Modul machen, welches 
über die Peripherie abstrahiert. Davon sollte es nur eines geben und 
somit gibt es nur eine Initalisierung obowohl diese lokal ist. Trotzdem 
entsteht kein redundanter Code.

Portierung macht hier keine Probleme, denn das Peripherie-Modul bekommt 
weiterhin von der globalen Quelle seine Infos, also z.B. Portzuweisungen 
oder die Nummer des UART welches es darstellt usw.

Bei OO würde das z.B. so aussehen:

UART pcConnection = new UART(USART0);

Hier hat man die Zuweisung der Hardware (USART0) global am 
Programmstart, die Implementierung aber nur im Modul. Das Modul bleibt 
Portabel und eine Änderung der HW, also z.B. jetzt soll USART1 verwendet 
werden, braucht nur eine Änderung und keine externen Listen (brrr das 
ist sowieso so eine Idee aus der Hölle).

Das geht auch, wenn ein Modul die Zuweisungen nur über #defines bekommt.



gruß cyblord

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Ich mach das immer global, hier mal ein Ausschnitt:
1
#ifndef _hardware_h_
2
#define _hardware_h_
3
4
#include "sbit.h"
5
6
/********************************************** Fuse settings ***********************************/
7
/************************************************************************************************/
8
9
#define FUSE_EXT        0xFD                    // fuse o.k.
10
#define FUSE_HIGH       0xD0
11
#define FUSE_LOW        0xFF
12
13
/********************************************** Digital IO **************************************/
14
/************************************************************************************************/
15
16
/*** Outputs ***/
17
#define LED_RD          PORT_A5
18
#define LED_RD_oe        DDR_A5
19
#define xDAC8532        PORT_E6
20
#define xDAC8532_oe      DDR_E6
21
#define xADS8345        PORT_B0
22
#define xADS8345_oe      DDR_B0
23
#define SCK             PORT_B1
24
#define SCK_oe           DDR_B1
25
#define MOSI            PORT_B2
26
#define MOSI_oe          DDR_B2
27
#define FAN             PORT_B5
28
#define FAN_oe           DDR_B5
29
30
/*** Inputs ***/
31
#define xENABLE_in       PIN_E7    // general Enable o.k.
32
33
/*** Bidirectional ***/
34
#define W1              PORT_E3
35
#define W1_oe            DDR_E3
36
#define W1_in            PIN_E3
37
38
/********************************************** Analog inputs internal ADC **********************/
39
/************************************************************************************************/
40
41
#define ADC_RES         1024.0                                  // resolution
42
#define UREF            5.0                                     // 5.0V (VCC)
43
44
#define U24V            24.0                                    // 24.0V
45
#define DIV24V          ((51.0 + 10.0) / 10.0)                  // 51k, 10k
46
#define U24V_ADC        (U24V / DIV24V / UREF * ADC_RES)
47
48
#define MEAS_24V        0                                       // ADC input channels
49
#define MEAS_CABLE      2

von Walter T. (nicolas)


Lesenswert?

cyblord ---- schrieb:
> Initalisierung von Peripherie sollte schon das Modul machen, welches
> über die Peripherie abstrahiert.

Hat cyblord natürlich Recht. Die Pin-Initialisierung ist nicht mehr in 
der "iomapping.h", sondern in dem Modul, das die IOs nutzt.

Bei mir sehen die io-mappings ähnlich aus:
1
/* Grafik-LCD Steuer-Port: */
2
#define GLCD_CTRL_PORT PORTD
3
#define GLCD_CTRL_PIN  PIND
4
#define GLCD_CTRL_DDR  DDRD
5
#define GLCD_RS   PD0  // Data/Instr (D=1/I=0)
6
#define GLCD_RW   PD1  // Read/Write (R=1/W=0)
7
#define GLCD_ECLK PD2  // Enable (E)
8
#define GLCD_CS1  PD3  // CS/1
9
#define GLCD_CS2  PD4  // CS/2
10
#define GLCD_RESET PD6 // Reset-Pin (RESET = 0)
11
12
/* Grafik-LCD Daten-Port   */
13
/* Px7: -> DB7 (MSB) + Busy-Flag)
14
 * Px6: -> DB6
15
 * Px5: -> DB5
16
 * Px4: -> DB4
17
 * Px3: -> DB3
18
 * Px2: -> DB2
19
 * Px1: -> DB1
20
 * Px0: -> DB0 (LSB)   */
21
#define GLCD_DATA_PORT PORTB
22
#define GLCD_DATA_PIN  PINB
23
#define GLCD_DATA_DDR  DDRB
24
25
26
// Eingaenge fuer Potis und Bedienelemente
27
#define POTI_I_SOLL PA6 // Bedienpoti I_SOLL
28
#define POTI_T_ON   PA4 // Bedienpoti T_ON
29
#define POTI_T_OFF  PA5 // Bedienpoti T_OFF
30
#define POTI_UPDWN  PA7 // Bedientpoti Schrittmotor Auf/Ab
31
32
#define ADC_SENSE   PA0 // Eingang Stromsensor
33
34
35
// Drehgeber und Taster
36
#define ENC_A_PORT PORTA
37
#define ENC_A_PIN  PINA
38
#define ENC_A_DDR  DDRA
39
#define ENC_A_P PA2
40
41
#define ENC_B_PORT PORTA
42
#define ENC_B_PIN  PINA
43
#define ENC_B_DDR  DDRA
44
#define ENC_B_P PA1
45
46
#define TAST_PORT PORTA
47
#define TAST_PIN PINA
48
#define TAST_DDR DDRA
49
#define TAST_P PA3
50
51
/* I2C-Pins */
52
#define I2C_PORT PORTC
53
#define I2C_DDR  DDRC
54
#define I2C_PIN  PINC
55
#define I2C_SCL PC0
56
#define I2C_SDA PC1
57
58
59
// Freie Pins
60
61
#define SPARE0      PC3
62
#define SPARE0_PIN  PINC
63
#define SPARE0_DDR  DDRC
64
#define SPARE0_PORT PORTC
65
66
#define SPARE1 PC2
67
#define SPARE1_PIN  PINC
68
#define SPARE1_DDR  DDRC
69
#define SPARE1_PORT PORTC
70
71
#define SPARE2 PD7
72
#define SPARE2_PIN  PIND
73
#define SPARE2_DDR  DDRD
74
#define SPARE2_PORT PORTD

: Bearbeitet durch User
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.