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


von Mario (Gast)


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.

von holger (Gast)


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);
      }

   }

von spess53 (Gast)


Lesenswert?

Hi

Bei 1 ms wirst du aber nicht viel Blinken sehen.

MfG Spess

von Niels H. (monarch35)


Lesenswert?

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

vorrausgesetzt XTAL im Makefile stimmt

von Mario (Gast)


Lesenswert?

was bringtt die "~"?

PORTA &= ~(1 << PA0);

von spess53 (Gast)


Lesenswert?

Hi

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

MfG Spess

von holger (Gast)


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); }

von M. V. (-_-)


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:
1
while(1) {
2
      PORTA = PINA ^ (1 << PA0);
3
4
      for(i=0;i<1000;i++) {
5
        _delay_ms(1);
6
      }
7
}

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

von Niels H. (monarch35)


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.

von holger (Gast)


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 ;)

von Niels H. (monarch35)


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.

von Niels H. (monarch35)


Lesenswert?

Nachtrag:

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

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

von ARM-Fan (Gast)


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.

von Mario (Gast)


Lesenswert?

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

von Thomas P. (Gast)


Lesenswert?

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

von spess53 (Gast)


Lesenswert?

Hi

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

MfG Spess

von Falk B. (falk)


Lesenswert?

Oder einfach das funktionierende Beispiel aus dem Tutorial nehmen.

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Warteschleifen_.28delay.h.29

MFG
Falk

von M. V. (-_-)


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.

von Niels H. (monarch35)


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

von Simon K. (simon) Benutzerseite


Lesenswert?

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

Edit: Doch Thomas P. ;)

von Niels H. (monarch35)


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.

von André K. (andre-)


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.

von holger (Gast)


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.

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.