hur organisera C-program?
Postat: 21 juli 2010, 15:31:35
jag håller på med några olika projekt med AVR som jag programmerar i C. Ett av dem är ganska omfattande, och det börjar bli lite rörigt, beroende på att jag inte har någon riktig "standard" på var jag ska lägga olika data och funktioner.
Nu ska jag inte gå in i detalj på röran i mitt projekt, utan efterlyser istället hur man allmänt bör lägga upp program som är lite större än "blinka lysdiod". Syftet är att jag ska kunna återanvända så mycket av koden som möjligt vid nya projekt, även om hårdvaran byts ut.
Vi tar ett exempel:
jag ska läsa in text från UART och/eller från annan enhet och skicka ut som text till en 128x64 grafisk LCD och/eller till en 4 x 20 raders textbaserad LCD. ena LCD:n har SPI-interface, den andra kopplas parallellt.
Jag vill då ha följande filer:
main.c - starta allt och hålla det rullande.
spi.c - grundläggande funktioner för SPI
graflcd.c - grundläggande kommandon för grafisk lcd.
txtlcd.c - fuktioner för textbaserad lcd.
uart.c - funktioner för UART
sen har varje fil en motsvarande headerfil (.h)
kanske jag även borde ha en egen c-fil (eller bara h-fil) med definitioner för just den hårdvara jag använder för tillfället. Så om jag ska skriva ett program för "kretskort x" så inkluderar jag bara "x.c" eller "x.h" så har jag det mesta konfigurerar för just den designen (ex.. LEDPORT = PORTB, RED_LED = PB4)
Tanken är väl att funktionerna i "graflcd" ska kunna användas oavsett *hur* jag sköter min SPI-kommunikation. Därför bör jag ha generella SPI-funktioner i separat fil. Och main.c i sin tur ska kunna anropa generella "skriva ut" rutiner utan att behöva veta *vilken* display (eller annan enhet) den skriver till.. t.ex. putChar('A'); eller print(string);
Frågan är hur jag lämpligast arrangerar möjligheten att byta enhet... just nu har jag en global variabel som heter put. och jag kan sätta den till olika värden: t.ex.
antag att uart.c (med tillhörande uart.h) ska vara en generell funktion för uart så ska man bland annat kunna ställa in vilken kanal man använder, baudrate osv... då ska man väl lämpligen ha UART_BAUDRATE och UART_KANAL definierade - bör då dessa definitioner alltid ligga i main.h eller var lägger jag dem? Och i så fall - då behöver jag väl alltid ha #include "main.h" i uart.h-filen, för annars hittar inte kompilatorn definitionerna? (jag vill hellre använda fasta definitioner på t.ex. BAUDRATE istället för funktioner, såvida det inte behöver ändras under programmets gång. Ett alternativ till funktioner är kanske att använda globala variabler, men det verkar som om det kan bli ganska rörigt.
Lite allmän "systemeringskunskap" för enklare processorsystem skulle vara intressant att få del av, gärna på svenska.
Nu ska jag inte gå in i detalj på röran i mitt projekt, utan efterlyser istället hur man allmänt bör lägga upp program som är lite större än "blinka lysdiod". Syftet är att jag ska kunna återanvända så mycket av koden som möjligt vid nya projekt, även om hårdvaran byts ut.
Vi tar ett exempel:
jag ska läsa in text från UART och/eller från annan enhet och skicka ut som text till en 128x64 grafisk LCD och/eller till en 4 x 20 raders textbaserad LCD. ena LCD:n har SPI-interface, den andra kopplas parallellt.
Jag vill då ha följande filer:
main.c - starta allt och hålla det rullande.
spi.c - grundläggande funktioner för SPI
graflcd.c - grundläggande kommandon för grafisk lcd.
txtlcd.c - fuktioner för textbaserad lcd.
uart.c - funktioner för UART
sen har varje fil en motsvarande headerfil (.h)
kanske jag även borde ha en egen c-fil (eller bara h-fil) med definitioner för just den hårdvara jag använder för tillfället. Så om jag ska skriva ett program för "kretskort x" så inkluderar jag bara "x.c" eller "x.h" så har jag det mesta konfigurerar för just den designen (ex.. LEDPORT = PORTB, RED_LED = PB4)
Tanken är väl att funktionerna i "graflcd" ska kunna användas oavsett *hur* jag sköter min SPI-kommunikation. Därför bör jag ha generella SPI-funktioner i separat fil. Och main.c i sin tur ska kunna anropa generella "skriva ut" rutiner utan att behöva veta *vilken* display (eller annan enhet) den skriver till.. t.ex. putChar('A'); eller print(string);
Frågan är hur jag lämpligast arrangerar möjligheten att byta enhet... just nu har jag en global variabel som heter put. och jag kan sätta den till olika värden: t.ex.
Kod: Markera allt
put = LCD;
print(helptext);
put = TFT2;
print(annan_text);
put = LCD|TFT2|UART;
print(skriver_ut_till_alla_enheter);
put = 0;
Lite allmän "systemeringskunskap" för enklare processorsystem skulle vara intressant att få del av, gärna på svenska.