Dubbel UART - hur utforma program? (AVR)
Postat: 4 mars 2012, 02:14:56
Jag har hittills jobbat med enbart en UART-kanal med ATMega644.
Nu har jag ett nytt projekt med en ATMEGA644A som har två UART-kanaler (UART0 / UART1) och jag ska modifiera mina egna källfiler uart.c och uart.h för att kunna använda båda kanaler samtidigt. (I framtida projekt kanske jag vill använda tre eller fyra UART-kanaler).
Nu är frågan vad som är smartast/enklast/effektivast?
Göra dubbla uppsättningar funktioner av allting eller att försöka använda gemensamma funktioner men bara ändra en variabel 0 eller 1 beroende på vilken kanal jag vill använda?
Mina UART-rutiner bygger på interrupt och har buffert både för att ta emot och sända tecken. Jag har ett antal globala variabler som hör till:
(Dessa måste vara 'volatile' eftersom de används i interruptrutinerna).
I C++ hade det varit självklart att man bara hade skapar två objekt - en för varje kanal, så hade det varit klart. Men i C är det ju inte lika smidigt. Jag kan ju t.ex. göra en struct av alla variabler ovan och sedan göra en array med två likadana struct-element i. Då skulle det kanske kunna se ut så här?:
Så kan man sedan använda uart[0].uartSendBuffer[n] och uart[1].uartSendBuffer[n] men det känns intuitivt som om det kommer att öka på programomfånget rejält (hantera ytterligare ett index på alla variabler tar säkert många extra instruktioner för varje liten operation)...
Kanske man kunde göra någon egen variant av 'objektorientering' med hjälp av pekare... man sätter en 'startpekare' som pekar på vilken UART man vill arbeta med, sedan adderas bara konstanter till denna pekare för att hitta rätt variabler (eller blir det lika klumpigt som varianten med index?)
Utan någon form av 'indexering' av de två UART-kanalerna blir jag ju tvungen att göra dubbla funktioner för de två kanalerna , med exakt samma kod i, förutom att man skriver UART1 istället för UART0 etc. och att man döper dem till putChar0() respektive putChar1()...
Jag hoppas det går att förstå vad jag upplever är problemet här...
Hur skulle du ha gjort?
Nu har jag ett nytt projekt med en ATMEGA644A som har två UART-kanaler (UART0 / UART1) och jag ska modifiera mina egna källfiler uart.c och uart.h för att kunna använda båda kanaler samtidigt. (I framtida projekt kanske jag vill använda tre eller fyra UART-kanaler).
Nu är frågan vad som är smartast/enklast/effektivast?
Göra dubbla uppsättningar funktioner av allting eller att försöka använda gemensamma funktioner men bara ändra en variabel 0 eller 1 beroende på vilken kanal jag vill använda?
Mina UART-rutiner bygger på interrupt och har buffert både för att ta emot och sända tecken. Jag har ett antal globala variabler som hör till:
Kod: Markera allt
volatile int8_t uartInputBuffer[UART_INPUT_BUFFER_LEN];
volatile int8_t uartInbufpos; // läser in data hit
volatile int8_t uartInbufRead; // läser av data här/
volatile uint8_t uaflag; // flaggar olika tillstånd i inbuffer
volatile uint8_t uartLinesWaiting; // antal väntande rader som ska läsas in.
volatile uint8_t uartSendBuffer[UART_SEND_BUFFER_LEN];
volatile uint16_t uartSendbufWrite=0; // lägger in data här
volatile uint16_t uartSendbufRead=0; // skickar ut data här
volatile uint8_t ICR_flag_set = 0; // intern flagga
I C++ hade det varit självklart att man bara hade skapar två objekt - en för varje kanal, så hade det varit klart. Men i C är det ju inte lika smidigt. Jag kan ju t.ex. göra en struct av alla variabler ovan och sedan göra en array med två likadana struct-element i. Då skulle det kanske kunna se ut så här?:
Kod: Markera allt
struct uartstr {
uint8_t uartSendBuffer[UART_SEND_BUFFER_LEN];
uint16_t uartSendbufWrite=0; // lägger in data här
uint16_t uartSendbufRead=0; // skickar ut data här
uint8_t ICR_flag_set = 0; // intern flagga
}
struct uartstr uart[1]; // skapar en array med två poster [0] och [1]
Kanske man kunde göra någon egen variant av 'objektorientering' med hjälp av pekare... man sätter en 'startpekare' som pekar på vilken UART man vill arbeta med, sedan adderas bara konstanter till denna pekare för att hitta rätt variabler (eller blir det lika klumpigt som varianten med index?)
Utan någon form av 'indexering' av de två UART-kanalerna blir jag ju tvungen att göra dubbla funktioner för de två kanalerna , med exakt samma kod i, förutom att man skriver UART1 istället för UART0 etc. och att man döper dem till putChar0() respektive putChar1()...
Jag hoppas det går att förstå vad jag upplever är problemet här...

Hur skulle du ha gjort?