Forum: Mikrocontroller und Digitale Elektronik Die ersten Versuche in C


von Florian K. (flo_ww)


Angehängte Dateien:

Lesenswert?

Guten Abend zusammen,

ich beschäftige mich nun seit ein paar Wochen mit der Programmierung in 
C. Einige Grundlagen habe ich bereits verstanden, vieles mit Sicherheit 
aber auch noch nicht. Nach einigen I/O Spielereien mit Copy&Paste auf 
dem Atmega8 habe ich nun erstmals ein kleines Programm komplett 
selbstständig erstellt.

Ich würde mich freuen wenn mal jemand darüber schauen könnte. Es geht 
mir in erster Linie um Lesbarkeit und Formatierung. Ich denke es ist 
einfacher Fehler am Anfang zu beheben als wenn man schlechte 
Angewohnheiten über längere Zeit praktiziert und sie dann ändern möchte.

Das Programm lässt sich Fehlerfrei im Atmel Studio compilieren und auch 
das Ergebnis auf dem Steckbrett ist genau das was ich mir Vorgestellt 
habe. Es werden zwei kleine Animationen auf vier 7-Segment LED Anzeigen 
ausgegeben. Als Ansteuerung dient mir ein Schieberegister und die 
Anzeigen sind 4:1 multiplex mit einer Refreshrate von 250Hz.

Für mich ist das eine erste kleine Übung auf dem Weg zum LED-Cube. Ich 
finde lieber selber den Weg dahin als eine fertige Schaltung inkl. Code 
aus dem Internet zu benutzen.

Beste Grüße

Flo

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Wenn du dir die ISR für den Timer nochmal genau anschaust, wird dir 
auffallen, das die Fallunterscheidung sich nur darin unterscheidet, das 
du in PORTC ein anderes Muster lädst:
1
TCNT0=128;          // Preload für Timer Interrupt 128 = 1ms
2
  
3
 switch(in)
4
  {
5
case0:  // Digit 0
6
    {
7
    PORTC  = LED_off;    // Alle LEDs aus
8
    SPDR  = liveout[0];  // Daten fŸr Ebene 0 auf SPI ausgeben
9
    while(!(SPSR & (1<<SPIF)));  // warten bis Ÿbertragung beendet
10
    PORTB  &=~  (1<<RCK);  // RCK Low
11
    PORTB  |=  (1<<RCK);  // RCK High - Daten werden in Register Ÿbernommen
12
    PORTC  =  ebene_0;  // LEDs fŸr ebene 0 an
13
    break;
14
    }
Du könntest also den Grossteil der Routinen gemeinsam machen und nur das 
Setzen des PORTC dann mit switch-case machen.
Ausserdem ist es normalerweise keine gute Strategie, in einer ISR zu 
warten, bis irgendeine Übertragung fertig ist, sinnvoll wäre es z.B., am 
Ende der ISR das SPI zu starten und beim nächsten Durchlauf dann die 
dazugehörigen Ports zu setzen.
> TCNT0=128;      // Preload für Timer
Schau dir dafür mal den CTC Modus des Timers an. Dann ist ein erneutes 
Laden des Timers unnötig und er wird ohne jeglichen Eingriff immer 
wieder nur bis zum gewünschten Wert zählen und dann den Interrupt 
auslösen.
>   PORTC  =  ebene_0;  // LEDs fŸr ebene 0 an

Für die Muster der Anzeige hast du schon ein Array gemacht, das kannst 
du ohne weiteres auch für die 'ebene' machen:
const uint8_t ebene[5] = {0b11111110,0b11111101,0b11111011.. usw.
In der ISR zählst du deine Variable 'in' hoch und greifst auf die ebene 
genauso zu, wie auf deine Muster,z.B. mit PORTC = ebene[in]. Dann kannst 
du dir das switch-case ganz sparen.

Noch ein Tipp. Konstante wie die ebene und das Muster sind normalerweise 
im Flash Speicher am besten aufgehoben, dann kosten sie keinen 
wertvollen RAM und müssen zur Laufzeit nicht noch initialisiert werden.
Dafür bietet avr-gcc das Attribut PROGMEM und die Funktionen 
pgm_read_byte(addr), pgm_read_word(addr) usw.
Das kann z.B. so aussehen (Beispiel aus dem ersten erreichbaren 
Programmstückchen hier):
1
const PROGMEM uint8_t expectedHallSequenceForward[8] =
2
{
3
  0xff,  5, 3, 1, 6, 4, 2, 5
4
};
5
// und dann später
6
 startupcount = 0; // kann eine Zahl zwischen 0 und 7 sein
7
 meinWert = pgm_read_byte(expectedHallSequenceForward+startupcount);
Ansonsten sieht das doch schon ganz gut aus. Ich hatte hier mit deinen 
vielen Tabs vor den Kommentaren ein paar Umformatierungsproblemchen, 
aber das ist oft so und eine der Optionen, mit denen sich Programmierer 
seit Jahrzehnten beschäftigen (ist ein Tab nun 4 Spaces lang oder 8 oder 
was?).

von Stefan F. (Gast)


Lesenswert?

> ist ein Tab nun 4 Spaces lang oder 8 oder was?

Deswegen benutze ich Tabs gar nicht mehr, sondern rücke mit Leerzeichen 
ein. Die meisten Editoren können das automatisch umsetzen.

von ich (Gast)


Lesenswert?

Hi,
Ich möchte NUR hinzufügen:
 Einige dich auf eine einrücktiefe, (die meisten Editoren die sich so 
nenen  dürfen können das in der Regel)
 Tutorials nie C&P machen (Außer du willst deine HW das erste mal 
testen, sollte man sowie so immer machen), beim Abtippen gleich SELBER 
gedanken machen was die Zeile bewirken soll. Dann ist das wie bei 
Radiowerbung, geht durch die Hand bleibt im Kopf. (Letzter Punkt ist 
Nicht expliziet für dich geschrieben sondern für andere Anfänger (wie 
mich, hab es früher auch so gemacht hat mir zwar schnelle erfolge 
gebraucht, aber habe auch viel zw. Zeitlich vergessen))
Sonst hatte ich keine Zeit genaueres zu lesen.
MfG
ich

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.