mikrocontroller.net

Forum: Compiler & IDEs [AVR] Pins über Array ansteuern


Autor: Christian Illy (alloc)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

wir haben zur Zeit das Problem, dass wir in unserem Code dynamisch auf 
Pins zugreifen können müssen.
So wie es jetzt ist überprüfen wir mit nem relativ großen switch-case 
den anzusteuernden Index und greifen dann von Hand auf Port* und DDR* zu 
was den Code unnötig aufbläht.
Um das zu optimieren bräuchten wir ein Array in dem die IO-Adressen der 
Ports stehen, so dass man über einen Index die Adresse auslesen kann und 
dann auf der Adresse die Daten ausgeben kann.
Die Port*-Defines bekommen wir irgendwie nicht so in einem Array 
gespeichert, dass wir danach auf die Ports zugreifen können. Gibt es da 
irgendwelche Tricks über Pointer/Dereferenzierung oder müssen wir die 
kompletten Adressen für alle Controller von Hand in eine Liste 
eintragen?

Grüße,
Chris

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da die gängige Methode mit gcc einen Port in eine Funktion
hinein zu übergeben darin besteht, einen Pointer an die
Funktion zu übergeben
  void foo( uint8_t* Port )
  {
    *Port = ( 1 << 5 );    // setze Bit 5 an welchem Port auch immer
  }

  int main()
  {
    foo( &PORTB );
  }

müsste das eigentlich auch mit einem Array aus Pointern klappen.
Ich kanns hier nicht ausprobieren, aber irgendwas in der Art:
  int main()
  {
    uint8_t* Ddrs[]  = { &DDRB,  &DDRC,  &DDRD };
    uint8_t* Ports[] = { &PORTB, &PORTC, &PORTD };

    Ddrs[1] = 0xFF;    // DDRC auf Output schalten
    Ports[1] = 0xFF;   // PORTC komplett auf 1
  }

Wie gesagt: Ich kanns hier nicht testen.
Was habt ihr denn so ausprobiert?

Autor: Werner B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist fast so etwas...

http://www.circuitcellar.com/avr2006/winners/AT3296.htm

Gruß
Werner

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Karl heinz: Da fehlt noch das bei I/O-Ports obligatorische volatile.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rolf Magnus wrote:
> @Karl heinz: Da fehlt noch das bei I/O-Ports obligatorische volatile.

Ja richtig.
Hab ich im Eifer des Gefechts übersehen.
Vielen Dank.

Autor: Christian Illy (alloc)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke euch, das sieht echt gut aus (konnte es noch nicht probieren bis 
jetzt ;) ).
Eine Frage noch: In dem Code auf den Werner gelinkt hat wird die 
DDR*-Adresse berechnet indem 1 von der Port*-Adresse abgezogen wird ... 
gilt das für alle ATmegas?

Grüße,
Chris

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Darauf würde ich mich lieber nicht verlassen. Wenn du für einen 
bestimmten AVR programmierst, kannst du ja im Datenblatt nachschauen.

Autor: Christian Illy (alloc)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger wrote:
>
>   int main()
>   {
>     uint8_t* Ddrs[]  = { &DDRB,  &DDRC,  &DDRD };
>     uint8_t* Ports[] = { &PORTB, &PORTC, &PORTD };
> 
>     Ddrs[1] = 0xFF;    // DDRC auf Output schalten
>     Ports[1] = 0xFF;   // PORTC komplett auf 1
>   }
> 

//EDIT:
Ignoriert das hier, volatile vergessen ;)

OLD
Haben das jetzt mal so probiert (nur die Arrays global statt lokal) und 
da gibt der Compiler folgenden Fehler zurück:
"../main.c:9: warning: initialization discards qualifiers from pointer 
target type"

Hat da jemand eine Idee?

Ansonsten müsste beim Zugriff doch noch ein * vor das Ddrs[1] / 
Ports[1]?

Gruß,
Chris

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian Illy wrote:
> Karl heinz Buchegger wrote:
>>
>>   int main()
>>   {
>>     uint8_t* Ddrs[]  = { &DDRB,  &DDRC,  &DDRD };
>>     uint8_t* Ports[] = { &PORTB, &PORTC, &PORTD };
>> 
>>     Ddrs[1] = 0xFF;    // DDRC auf Output schalten
>>     Ports[1] = 0xFF;   // PORTC komplett auf 1
>>   }
>> 
>
> Haben das jetzt mal so probiert (nur die Arrays global statt lokal) und
> da gibt der Compiler folgenden Fehler zurück:
> "../main.c:9: warning: initialization discards qualifiers from pointer
> target type"
>
> Hat da jemand eine Idee?

Das ist das volatile das ich vergessen habe:

  volatile uint8_t* Ddrs[] = { &DDRB, &DDRC, &DDRD };

Ditto für das andere Array

> Ansonsten müsste beim Zugriff doch noch ein * vor das Ddrs[1] /
> Ports[1]?
Ja, klar. Ist im Eifer des Gefechts passiert.
Sorry

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.