mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Blinken (Wieso geht der Code nicht?)


Autor: Mario (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#include <avr/io.h>
//#include <avr/interrupt.h>
//#include <avr/pgmspace.h>
//#include <avr/sleep.h>
//#include <inttypes.h>
#include <util/delay.h>


int main (void) {

  DDRA=0xff;
  uint8_t i;

    while(1) {

      PORTA |= (1 << PA0);


      for(i=0;i<1000;i++){

        _delay_ms(1);
      }



      PORTA &= (1 << PA0);


    }


}



die led bleibt leider immer aus! Einzeln an und aus schalten klappt.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
while(1) {

      PORTA |= (1 << PA0);


      for(i=0;i<1000;i++){

        _delay_ms(1);
      }



      PORTA &= ~(1 << PA0);

      for(i=0;i<1000;i++){

        _delay_ms(1);
      }

   }

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Bei 1 ms wirst du aber nicht viel Blinken sehen.

MfG Spess

Autor: Niels Hüsken (monarch35)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@spess:
du hast die for()-Schleife übersehen. 1000*1ms= 1sek

vorrausgesetzt XTAL im Makefile stimmt

Autor: Mario (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
was bringtt die "~"?

PORTA &= ~(1 << PA0);

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Na ja. Warum einfach, wenns umständlich geht.

MfG Spess

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Spess

>Bei 1 ms wirst du aber nicht viel Blinken sehen.

Die Klammern bei seinen for() Schleifen sind scheisse gesetzt.
Da sieht man es halt nicht so schnell ;)

Ich persönlich bevorzuge dieses

      for(i=0;i<1000;i++)
       {
        _delay_ms(1);
       }

oder

      for(i=0;i<1000;i++) { _delay_ms(1); }

Autor: M. V. (-_-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Um die eigentliche Frage zu beantworten: Der Code funktioniert nicht, 
weil du  nur anschaltest, dann eine Verzögerung hast, ausschaltest, und 
dann sofort wieder die Mainloop begonnen wird, dh. eingeschaltet wird. 
Folglich ist nur extrem kurz aus.

@holger: kürzer geht's noch:
while(1) {
      PORTA = PINA ^ (1 << PA0);

      for(i=0;i<1000;i++) {
        _delay_ms(1);
      }
}

Und was heisst da, 'scheisse gesetzt'? Das ist vollkommen 
standardkonform.

Autor: Niels Hüsken (monarch35)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
holger wrote:

>       for(i=0;i<1000;i++) { _delay_ms(1); }

Bei nur einem Befehl können die Brackets auch weggelassen werden.

for (i=0;i<1000;i++) _delay_ms (1);


dem OP bleibt zu raten, sich mal die wikiseite über bitmanipulation sich 
mal zu gemüte zu führen.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Jemand

Deine Lösung ist natürlich eleganter !

>Und was heisst da, 'scheisse gesetzt'? Das ist vollkommen
>standardkonform.

Ja, mag sein. Aber UNÜBERSICHTLICH. Spess hats doch gerade vorgemacht ;)

Autor: Niels Hüsken (monarch35)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jemand -_- wrote:

> Und was heisst da, 'scheisse gesetzt'? Das ist vollkommen
> standardkonform.

Ist reine Gewöhnungssache. Ich bin es ebenfalls gewohnt, das Brackets in 
einzelenen Zeilen stehen.

Autor: Niels Hüsken (monarch35)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nachtrag:

Jemand -_- wrote:
>
> while(1) {
>       PORTA = PINA ^ (1 << PA0);
[...]
> }
> 

PINx ist nur für Eingänge gedacht. Du meinst sicherlich
  PORTA = PORTA ^ (1<<PA0);

Autor: ARM-Fan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Mario: Ist dir denn jetzt klar geworden, wo deine Fehler sind?

Holger hat zwar schon alles gleich richtig geschrieben,
aber hier trotzdem nochmal:

      PORTA &= (1 << PA0);

ändert rein gar nichts am Zustand deiner LED.
Du verundest das Bit mit 1.

Du willst es ja löschen. Deswegen also die Tilde ~
Damit verundest du mit dem bitweise invertierten Wert.

Zweitens: Du mußt natülich auch nach dem zweiten Statement
eine Pause machen.

Autor: Mario (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
es liegt an der "~"!!!!! Ich hatte es erst ohne das ging nix mit geht!

Autor: Thomas P. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
uint8_t ? und dann bis 1000 in der for-Schleife? Dafür würde ich 
persönlich einen uint16_t nutzen :-)

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Als Assemblerprogrammierer wurde ich einfach eine XOR-Verknüpfung mit 1 
machen. Dann wird das Bit jedesmal invertiert.

MfG Spess

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oder einfach das funktionierende Beispiel aus dem Tutorial nehmen.

http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

MFG
Falk

Autor: M. V. (-_-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>PINx ist nur für Eingänge gedacht. Du meinst sicherlich
>  PORTA = PORTA ^ (1<<PA0);

Nein, denn dann hätte ich PORTA ^= (1<<PA0); geschrieben.

Siehe auch Datenblatt:
"Independent of the setting of Data Direction bit DDxn, the port pin can 
be read through the PINxn Register Bit."

Was natürlich nicht unbedingt heissen muss, dass deine Lösung nicht 
funktioniert, wobei ich mich aber zu erinnern meine, dass das mit dem 
PORTx auslesen, nicht zum gewünschten Ergebnis führt.

Autor: Niels Hüsken (monarch35)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
spess53 wrote:

> Als Assemblerprogrammierer wurde ich einfach eine XOR-Verknüpfung mit 1
> machen. Dann wird das Bit jedesmal invertiert.

Richtig. Die Lösung hatte "jemand" schon geschrieben.

 PORTA^=1;

^=XOR und ~=Complement

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hat eigentlich noch niemand gemerkt, dass 1000 nicht in einen uint8_t 
passen?

Edit: Doch Thomas P. ;)

Autor: Niels Hüsken (monarch35)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jemand -_- wrote:

> Was natürlich nicht unbedingt heissen muss, dass deine Lösung nicht
> funktioniert, wobei ich mich aber zu erinnern meine, dass das mit dem
> PORTx auslesen, nicht zum gewünschten Ergebnis führt.


Ich glaube du verstehst da etwas miss.
Wenn du PINx liest, erhälst du die Zustände der Portpins, die auf 
Eingang konfiguriert sind. Aus PORTx liesst du die Zustände der 
Portpins, die auf Ausgang geschaltet sind.

PORTx = PORTx ^ 1

ist in diesem Fall richtig.

Autor: André K. (andre-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Nein, denn dann hätte ich PORTA ^= (1<<PA0); geschrieben."

Welch selbiges du auch haettest tun sollen. Mit Pinx wird das nix (das 
KANN funktionieren), denn du moechtest auf den derzeitigen Zustand der 
Ausgangsstufe zugreifen.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ich glaube du verstehst da etwas miss.
>Wenn du PINx liest, erhälst du die Zustände der Portpins, die auf
>Eingang konfiguriert sind. Aus PORTx liesst du die Zustände der
>Portpins, die auf Ausgang geschaltet sind.

Mit PINx liest man den Zustand der Portpins
der gerade dort anliegt. Dabei ist es EGAL ob Eingang oder Ausgang.

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.