Setup av µC, ett exempel

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
Icecap
Inlägg: 26648
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Setup av µC, ett exempel

Inlägg av Icecap »

Håller på att skriva startkoden till det nya styrkort som baseras på Renesas RX210.

Och jag har ofta irriterat mig på att jag ofta skriver en rutin som nollar alla portar och ställer dom till output - för att sedan initiera de olika enheter och då ställa portarna igen. Varför inte göra detta i ett svep?

Alltså tänkte jag till lite och skapade en hårdvarudefinitionsfil för projektet.

Kod: Markera allt

#define USED_AS_INPUT  0
#define USED_AS_OUTPUT 1

// Capture 0/In 0 on P25, MTIOC4C, input
#define In_0                PORT2.PIDR.BIT.B5 // Nu är PORT2.5 namngett till "In_0"
#define In_0_D              PORT2.PDR.BIT.B5 // Riktningsbitten är namngett
#define PORT25              USED_AS_INPUT // Jag ska använda den som ingång
#define PORT25_INIT         false // Den ska skicka ut en nolla - om den nu hade varit utgång

// Capture 1/In 1 on P24, MTIOC4A, input
#define In_1                PORT2.PIDR.BIT.B4
#define In_1_D              PORT2.PDR.BIT.B4
#define PORT24              USED_AS_INPUT
#define PORT24_INIT         false
...

// Out 0 on PB7, output
#define Out_0               PORTB.PODR.BIT.B7 // Namngivning för portpinnen
#define Out_0_D             PORTB.PDR.BIT.B7 // Namngivning för riktningsbit'en
#define PORTB7              USED_AS_OUTPUT // Denna ska vara output
#define PORTB7_INIT         false // Som initialt ska vara noll
// Out 1 on PB6, output
#define Out_1               PORTB.PODR.BIT.B6
#define Out_1_D             PORTB.PDR.BIT.B6
#define PORTB6              USED_AS_OUTPUT
#define PORTB6_INIT         false
...

// XPort  Tx   on PC7, SCI8, output
#define XPort_Tx            PORTC.PODR.BIT.B7
#define XPort_Tx_D          PORTC.PDR.BIT.B7
#define PORTC7              USED_AS_OUTPUT
#define PORTC7_INIT         true
#define XPort_Tx_F          PORTC.PMR.BIT.B7 // Denna bit växlar mellan "Normal portpinne"=0 eller "Perifer funktion"=1. Namngivit för att lättare förstå programmet sedan.
// XPort  Rx   on PC6, SCI8, input
#define XPort_Rx            PORTC.PIDR.BIT.B6
#define XPort_Rx_D          PORTC.PDR.BIT.B6
#define PORTC6              USED_AS_INPUT
#define PORTC6_INIT         false
#define XPort_Rx_F          PORTC.PMR.BIT.B6
// XPort #RTS  on P15, input
#define XPort_nRTS          PORT1.PIDR.BIT.B5
#define XPort_nRTS_D        PORT1.PDR.BIT.B5
#define PORT15              USED_AS_INPUT
#define PORT15_INIT         false
// XPort #CTS  on P16, output
#define XPort_nCTS          PORT1.PODR.BIT.B6
#define XPort_nCTS_D        PORT1.PDR.BIT.B6
#define PORT16              USED_AS_OUTPUT
#define PORT16_INIT         false
...

// 1-wire Tx on PA5, output
#define Tx_1Wire            PORTA.PODR.BIT.B5
#define Tx_1Wire_D          PORTA.PDR.BIT.B5
#define PORTA5              USED_AS_OUTPUT
#define PORTA5_INIT         false
// 1-wire Rx on PE5, input
#define Rx_1Wire            PORTE.PIDR.BIT.B5
#define Rx_Wire_D           PORTE.PDR.BIT.B5
#define PORTE5              USED_AS_INPUT
#define PORTE5_INIT         false
...

// Vsense          on P40, AN000, analog, input
#define Vsense_D            PORT4.PDR.BIT.B0
#define PORT40              USED_AS_INPUT
#define PORT40_INIT         false
// Display Current on P41, AN001, analog, input
#define Display_Current_D   PORT4.PDR.BIT.B1
#define PORT41              USED_AS_INPUT
#define PORT41_INIT         false
// Light sensor    on PE4, AN008, analog, input
#define Light_Sensor_D      PORTE.PDR.BIT.B4
#define PORTE4              USED_AS_INPUT
#define PORTE4_INIT         false

// I2C uses P12 (SCL) & P13 (SDA)
#define IIC_SCL             PORT1.PODR.BIT.B2
#define IIC_SCL_D           PORT1.PDR.BIT.B2 // Select direction of pin
#define IIC_SCL_F           PORT1.PMR.BIT.B2 // Select between normal or alternative use of pin
#define PORT12              USED_AS_INPUT
#define PORT12_INIT         false
#define IIC_SDA             PORT1.PODR.BIT.B3
#define IIC_SDA_D           PORT1.PDR.BIT.B3 // Select direction of pin
#define IIC_SDA_F           PORT1.PMR.BIT.B3 // Select between normal or alternative use of pin
#define PORT13              USED_AS_INPUT
#define PORT13_INIT         false

// DS3232 SQW uses P34, IRQ4
#define RTC_SQW_D           PORT3.PDR.BIT.B4
#define RTC_SQW_F           PORT3.PMR.BIT.B4
#define PORT34              USED_AS_INPUT
#define PORT34_INIT         false

// Unused port pins
#define PORT03              USED_AS_OUTPUT
#define PORT03_INIT         false
...

// Summing up
#define PORT0_PDR  (                                         (PORT03 << 3) |                 (PORT05 << 5) |                 (PORT07 << 7))
#define PORT1_PDR  (                         (PORT12 << 2) | (PORT13 << 3) | (PORT14 << 4) | (PORT15 << 5) | (PORT16 << 6) | (PORT17 << 7))
#define PORT2_PDR  (PORT20 | (PORT21 << 1) | (PORT22 << 2) | (PORT23 << 3) | (PORT24 << 4) | (PORT25 << 5) | (PORT26 << 6) | (PORT27 << 7))
#define PORT3_PDR  (PORT30 | (PORT31 << 1) | (PORT32 << 2) | (PORT33 << 3) | (PORT34 << 4) | (PORT35 << 5) | (PORT36 << 6) | (PORT37 << 7))
#define PORT4_PDR  (PORT40 | (PORT41 << 1) | (PORT42 << 2) | (PORT43 << 3) | (PORT44 << 4) | (PORT45 << 5) | (PORT46 << 6) | (PORT47 << 7))
#define PORT5_PDR  (PORT50 | (PORT51 << 1) | (PORT52 << 2) | (PORT53 << 3) | (PORT54 << 4) | (PORT55 << 5)                                )
#define PORTA_PDR  (PORTA0 | (PORTA1 << 1) | (PORTA2 << 2) | (PORTA3 << 3) | (PORTA4 << 4) | (PORTA5 << 5) | (PORTA6 << 6) | (PORTA7 << 7))
#define PORTB_PDR  (PORTB0 | (PORTB1 << 1) | (PORTB2 << 2) | (PORTB3 << 3) | (PORTB4 << 4) | (PORTB5 << 5) | (PORTB6 << 6) | (PORTB7 << 7))
#define PORTC_PDR  (PORTC0 | (PORTC1 << 1) | (PORTC2 << 2) | (PORTC3 << 3) | (PORTC4 << 4) | (PORTC5 << 5) | (PORTC6 << 6) | (PORTC7 << 7))
#define PORTD_PDR  (PORTD0 | (PORTD1 << 1) | (PORTD2 << 2) | (PORTD3 << 3) | (PORTD4 << 4) | (PORTD5 << 5) | (PORTD6 << 6) | (PORTD7 << 7))
#define PORTE_PDR  (PORTE0 | (PORTE1 << 1) | (PORTE2 << 2) | (PORTE3 << 3) | (PORTE4 << 4) | (PORTE5 << 5) | (PORTE6 << 6) | (PORTE7 << 7))
#define PORTH_PDR  (PORTH0 | (PORTH1 << 1) | (PORTH2 << 2) | (PORTH3 << 3)                                                                )
#define PORTJ_PDR  (         (PORTJ1 << 1)                 | (PORTJ3 << 3)                                                                )

#define PORT0_PODR (                                                        (PORT03_INIT << 3) |                      (PORT05_INIT << 5) |                      (PORT07_INIT << 7))
#define PORT1_PODR (                                   (PORT12_INIT << 2) | (PORT13_INIT << 3) | (PORT14_INIT << 4) | (PORT15_INIT << 5) | (PORT16_INIT << 6) | (PORT17_INIT << 7))
#define PORT2_PODR (PORT20_INIT | (PORT21_INIT << 1) | (PORT22_INIT << 2) | (PORT23_INIT << 3) | (PORT24_INIT << 4) | (PORT25_INIT << 5) | (PORT26_INIT << 6) | (PORT27_INIT << 7))
#define PORT3_PODR (PORT30_INIT | (PORT31_INIT << 1) | (PORT32_INIT << 2) | (PORT33_INIT << 3) | (PORT34_INIT << 4) | (PORT35_INIT << 5) | (PORT36_INIT << 6) | (PORT37_INIT << 7))
#define PORT4_PODR (PORT40_INIT | (PORT41_INIT << 1) | (PORT42_INIT << 2) | (PORT43_INIT << 3) | (PORT44_INIT << 4) | (PORT45_INIT << 5) | (PORT46_INIT << 6) | (PORT47_INIT << 7))
#define PORT5_PODR (PORT50_INIT | (PORT51_INIT << 1) | (PORT52_INIT << 2) | (PORT53_INIT << 3) | (PORT54_INIT << 4) | (PORT55_INIT << 5)                                          )
#define PORTA_PODR (PORTA0_INIT | (PORTA1_INIT << 1) | (PORTA2_INIT << 2) | (PORTA3_INIT << 3) | (PORTA4_INIT << 4) | (PORTA5_INIT << 5) | (PORTA6_INIT << 6) | (PORTA7_INIT << 7))
#define PORTB_PODR (PORTB0_INIT | (PORTB1_INIT << 1) | (PORTB2_INIT << 2) | (PORTB3_INIT << 3) | (PORTB4_INIT << 4) | (PORTB5_INIT << 5) | (PORTB6_INIT << 6) | (PORTB7_INIT << 7))
#define PORTC_PODR (PORTC0_INIT | (PORTC1_INIT << 1) | (PORTC2_INIT << 2) | (PORTC3_INIT << 3) | (PORTC4_INIT << 4) | (PORTC5_INIT << 5) | (PORTC6_INIT << 6) | (PORTC7_INIT << 7))
#define PORTD_PODR (PORTD0_INIT | (PORTD1_INIT << 1) | (PORTD2_INIT << 2) | (PORTD3_INIT << 3) | (PORTD4_INIT << 4) | (PORTD5_INIT << 5) | (PORTD6_INIT << 6) | (PORTD7_INIT << 7))
#define PORTE_PODR (PORTE0_INIT | (PORTE1_INIT << 1) | (PORTE2_INIT << 2) | (PORTE3_INIT << 3) | (PORTE4_INIT << 4) | (PORTE5_INIT << 5) | (PORTE6_INIT << 6) | (PORTE7_INIT << 7))
#define PORTH_PODR (PORTH0_INIT | (PORTH1_INIT << 1) | (PORTH2_INIT << 2) | (PORTH3_INIT << 3)                                                                                    )
#define PORTJ_PODR (              (PORTJ1_INIT << 1)                      | (PORTJ3_INIT << 3)                                                                                    )
Sedan kan jag initiera allt på detta vis:

Kod: Markera allt

void Initiate_Ports(void)
  {
  // Standard setup of all ports
  PORT0.PODR.BYTE         = PORT0_PODR;
  PORT0.PDR.BYTE          = PORT0_PDR;
  PORT0.PCR.BYTE          = 0x00;
  PORT1.PODR.BYTE         = PORT1_PODR; 
  PORT1.PDR.BYTE          = PORT1_PDR;
  PORT1.PCR.BYTE          = 0x00;
  PORT1.ODR0.BYTE         = 0x00;
  PORT1.ODR1.BYTE         = 0x00;
  PORT1.DSCR.BYTE         = 0x00;
  PORT2.PODR.BYTE         = PORT2_PODR;
  PORT2.PDR.BYTE          = PORT2_PDR;
  PORT2.PCR.BYTE          = 0x00;
  PORT2.ODR0.BYTE         = 0x00;
  PORT2.ODR1.BYTE         = 0x00;
  PORT2.DSCR.BYTE         = 0x00;
  PORT3.PODR.BYTE         = PORT3_PODR;
  PORT3.PDR.BYTE          = PORT3_PDR;
  PORT3.PCR.BYTE          = 0x00;
  PORT3.ODR0.BYTE         = 0x00;
  PORT3.ODR1.BYTE         = 0x00;
  PORT3.DSCR.BYTE         = 0x00;
  PORT4.PODR.BYTE         = PORT4_PODR;
  PORT4.PDR.BYTE          = PORT4_PDR;
  PORT4.PCR.BYTE          = 0x00;
  PORT5.PODR.BYTE         = PORT5_PODR;
  PORT5.PDR.BYTE          = PORT5_PDR;
  PORT5.PCR.BYTE          = 0x00;
  PORT5.DSCR.BYTE         = 0x00;
  PORTA.PODR.BYTE         = PORTA_PODR;
  PORTA.PDR.BYTE          = PORTA_PDR;
  PORTA.PCR.BYTE          = 0x00;
  PORTA.ODR0.BYTE         = 0x00;
  PORTA.ODR1.BYTE         = 0x00;
  PORTA.DSCR.BYTE         = 0x00;
  PORTB.PODR.BYTE         = PORTB_PODR;
  PORTB.PDR.BYTE          = PORTB_PDR;
  PORTB.PCR.BYTE          = 0x00;
  PORTB.ODR0.BYTE         = 0x00;
  PORTB.ODR1.BYTE         = 0x00;
  PORTB.DSCR.BYTE         = 0x00;
  PORTC.PODR.BYTE         = PORTC_PODR;
  PORTC.PDR.BYTE          = PORTC_PDR;
  PORTC.PCR.BYTE          = 0x00;
  PORTC.ODR0.BYTE         = 0x00;
  PORTC.ODR1.BYTE         = 0x00;
  PORTC.DSCR.BYTE         = 0x00;
  PORTD.PODR.BYTE         = PORTD_PODR;
  PORTD.PDR.BYTE          = PORTD_PDR;
  PORTD.PCR.BYTE          = 0x00;
  PORTD.DSCR.BYTE         = 0x00;
  PORTE.PODR.BYTE         = PORTE_PODR;
  PORTE.PDR.BYTE          = PORTE_PDR;
  PORTE.PCR.BYTE          = 0x00;
  PORTE.ODR0.BYTE         = 0x00;
  PORTE.ODR1.BYTE         = 0x00;
  PORTE.DSCR.BYTE         = 0x00;
  PORTH.PODR.BYTE         = PORTH_PODR;
  PORTH.PDR.BYTE          = PORTH_PDR;
  PORTH.PCR.BYTE          = 0x00;
  PORTH.DSCR.BYTE         = 0x00;
  PORTJ.PODR.BYTE         = PORTJ_PODR;
  PORTJ.PDR.BYTE          = PORTJ_PDR;
  PORTJ.PCR.BYTE          = 0x00;
  PORTJ.DSCR.BYTE         = 0x00;
  }
På detta sätt kan jag enkelt dels skapa en standard "initiera alla portar" för den µC, dels kan jag få felmeddelanden om någon pinne inte är definierat eller dubbelt definierat. Samtidig ger jag alla pinnar arbetsnamn som är tydliga att förstå.

Jag påstår inte att detta sätt är världsbäst - men jag är ganska nöjd med det för stunden.

Till detta kommer såklart initieringen av de olika funktioner men som första uppstartsinställning gör det livet enklare för att undvika ryck här o där.

Just RX-serien har en sjujäkla massa register som styr vad portpinnar används för så initieringen ser stor ut men så är det bara.

När jag har kört denna rutin är jag säker på att hårdvaran inte står o bränner av energi vid att en utgång driver mot en annan utgång. Ingen ingång lämnas flytande heller.
Användarvisningsbild
psynoise
EF Sponsor
Inlägg: 7226
Blev medlem: 26 juni 2003, 19:23:36
Ort: Landvetter

Re: Setup av µC, ett exempel

Inlägg av psynoise »

Hur förhåller du dig till att använda makron för alla vänsterskift och ellerfunktioner för att göra koden något enklare?
Användarvisningsbild
Icecap
Inlägg: 26648
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Setup av µC, ett exempel

Inlägg av Icecap »

Frågan är väl: behövs det?

Och hur kunde du tänka dig göra det så att den blir mer översiktligt/tydlig?
Skriv svar