Forum: Mikrocontroller und Digitale Elektronik ATmega 328PB Blinklicht


von Mans A. (mansmaak)


Lesenswert?

Hallo liebe Community,

ich möchte die LED3 und die LED4 im Wechsel blinken lassen. Ich habe 
folgendes
Programm geschrieben:
1
#define F_CPU 16000000UL
2
#include <avr/io.h>
3
#include <util/delay.h>
4
5
6
int main(void)
7
{
8
    
9
  DDRB=(1<<PB4);  //LED4 als Ausgang definiert
10
  DDRB=(1<<PB5); //LED3 als Ausgang definiert
11
  
12
  
13
    while (1) 
14
    {
15
    PORTB|=(1<<PB4);//LED4 an
16
    
17
    _delay_ms(250.0);
18
    
19
    PORTB &= ~(1<<PB4);//LED4 aus
20
    
21
    PORTB|=(1<<PB5);//LED3 an
22
    
23
    _delay_ms(250.0);
24
    
25
    PORTB &= ~(1<<PB5);//LED3 aus
26
    
27
    
28
    }
29
  return 0;
30
}

Es leuchtet jedoch nur die LED3! Weiß jemand wo mein Fehler ist.
Danke schon mal im Voraus!

von Helmut -. (dc3yc)


Lesenswert?

Schaue dir mal die Zuweisungen ans DDRB-Register an. Wird da nicht was 
überschrieben?

von Oliver S. (oliverso)


Lesenswert?

Led4 kaputt, falsch rum eingelötet, falsches Programm geflasht, was auch 
immer.

Oliver

: Bearbeitet durch User
von Mans A. (mansmaak)


Lesenswert?

Oliver S. schrieb:
> Led4 kaputt, falsch rum eingelötet, falsches Programm geflasht,
> was auch
> immer.
>
> Oliver

Nein. dass kann nicht sein. Ich benutze ein Simulationsprogramm!

von Georg M. (g_m)


Lesenswert?

DDRB = (1 << PB4) | (1 << PB5);

von au weia (Gast)


Lesenswert?

Mans A. schrieb:
> Nein. dass kann nicht sein.

Helmut hat es dir schon korrekt erklärt. Lies und verstehe.

von Matthias L. (Gast)


Lesenswert?

1
  DDRB=(1<<PB4);  //LED4 als Ausgang definiert
2
  DDRB=(1<<PB5); //LED3 als Ausgang definiert

Im Ergebnis ist nur PB5 auf Ausgang gesetzt. Und deshalb funktioniert 
nur die daran angeschlossene LED.

So ists korrekt:
1
  DDRB |= (1<<PB4);  //LED4 als Ausgang definiert
2
  DDRB |= (1<<PB5); //LED3 als Ausgang definiert

von Mans A. (mansmaak)


Lesenswert?

Matthias L. schrieb:
> DDRB=(1<<PB4);  //LED4 als Ausgang definiert
>   DDRB=(1<<PB5); //LED3 als Ausgang definiert
>
> Im Ergebnis ist nur PB5 auf Ausgang gesetzt. Und deshalb funktioniert
> nur die daran angeschlossene LED.
>
> So ists korrekt:  DDRB |= (1<<PB4);  //LED4 als Ausgang definiert
>   DDRB |= (1<<PB5); //LED3 als Ausgang definiert

Das ist auf jeden Fall schon mal ein Fehler! Danke!!
Leider leuchtet immer noch nur LED3! Ich kann es mir nicht erklären.
Auch wenn ich die delay- Zeit erhöhe, blinkt die LED3 unverändert 
weiter.
Habe ich im Programm sonst alles richtig?

von Matthias L. (Gast)


Lesenswert?

Mans A. schrieb:
> Habe ich im Programm sonst alles richtig?

Dann zeige das angepasste Programm doch nochmal

von Mans A. (mansmaak)


Lesenswert?

Matthias L. schrieb:
> Mans A. schrieb:
>> Habe ich im Programm sonst alles richtig?
>
> Dann zeige das angepasste Programm doch nochmal
1
#define F_CPU 16000000UL
2
#include <avr/io.h>
3
#include <util/delay.h>
4
5
6
int main(void)
7
{
8
    
9
  DDRB|=(1<<PB4);  //LED4 als Ausgang definiert
10
  DDRB|=(1<<PB5); //LED3 als Ausgang definiert
11
  
12
  
13
    while (1) 
14
    {
15
    PORTB|=(1<<PB4);//LED4 an
16
    
17
    _delay_ms(250.0);
18
    
19
    PORTB &= ~(1<<PB4);//LED4 aus
20
    
21
    PORTB|=(1<<PB5);//LED3 an
22
    
23
    _delay_ms(250.0);
24
    
25
    PORTB &= ~(1<<PB5);//LED3 aus
26
    
27
    
28
    }
29
  return 0;
30
}

von Hugo H. (hugo_hu)


Lesenswert?

Mans A. schrieb:
> Habe ich im Programm sonst alles richtig?

LED "verpolt" ?

von au weia (Gast)


Lesenswert?

Hugo H. schrieb:
> LED "verpolt" ?

Mans A. schrieb:
> Nein. dass kann nicht sein. Ich benutze ein Simulationsprogramm!

von Jens N. (midibrain)


Lesenswert?

Warum schreibst Du "_delay_ms(250.0);" und nicht einfach 
"_delay_ms(250);" ?

von Matthias L. (Gast)


Lesenswert?

Mans A. schrieb:
> Ich benutze ein Simulationsprogramm!

Dann steppe doch mal durch und sie Dir an, was die PORTB Zuweisungen 
erzeugen.

von Wolfgang (Gast)


Lesenswert?

Mans A. schrieb:
> Ich benutze ein Simulationsprogramm!

Mans A. schrieb:
> Leider leuchtet immer noch nur LED3! Ich kann es mir nicht erklären.

Dann stelle fest, in welcher Zeile sich das Programm nicht so verhält, 
wie du es erwartest, prüfe den Zustand der beteiligten Register und 
zeige es hier.

von Hugo H. (hugo_hu)


Lesenswert?

Mans A. schrieb:
> Nein. dass kann nicht sein. Ich benutze ein Simulationsprogramm!

Zu spät gesehen - da kannst Du lange warten, bis die delays abgearbeitet 
worden sind. Stelle (für die Simulation) mal 1 ms ein und freue Dich, 
was passiert :-)

von Wolfgang (Gast)


Lesenswert?

Mans A. schrieb:
> Es leuchtet jedoch nur die LED3!

Geht sie auch wieder aus?

von Hugo H. (hugo_hu)


Lesenswert?

Wolfgang schrieb:
> Geht sie auch wieder aus?

Ja.

von Hugo H. (hugo_hu)


Lesenswert?

Mans A. schrieb:
> Auch wenn ich die delay- Zeit erhöhe, blinkt die LED3 unverändert
> weiter.

Damit hast Du hier vermutlich nicht nur mich in die Irre geführt. LED3 
"blinkt" nicht - sie ist (längere Zeit - im Simulator) unverändert "an".

Für den Simulator setze ich delays - wenn ich sie denn verwende - immer 
auf ein Minimum. Du kannst die angegebene Wartezeit für den Simulator 
locker * 1000 nehmen ... (bei mir zumindest), da es einiges an Code "zu 
simulieren" gilt.

von HildeK (Gast)


Lesenswert?

Mans A. schrieb:
> Habe ich im Programm sonst alles richtig?

Ja, das angepasste Programm ist jetzt richtig. Ich habe es in einen 
Tiny26 geladen (mit F_CPU angepasst) und es wechselblinkt schön 😀.
Nicht notwendig ist das 'return 0' am Ende, es gibt nicht, wo ein Wert 
zurückgegeben werden könnte und zudem wird die Zeile nicht erreicht. 
Schadet aber auch nicht.

Wenn es in deinem Simulator nicht so funktioniert, dann machst du bei 
dessen Bedienung etwas falsch.

von Hugo H. (hugo_hu)


Lesenswert?

HildeK schrieb:
> Wenn es in deinem Simulator nicht so funktioniert, dann machst du bei
> dessen Bedienung etwas falsch.

Nein - nicht bei der Bedienung (es sei Denn, Du meinst dass "nicht ca. 5 
Minuten auf ein _delay_ms(250) warten zu wollen/können" falsche 
Bedienung ist :-) )

von HildeK (Gast)


Lesenswert?

Hugo H. schrieb:
> Nein - nicht bei der Bedienung (es sei Denn, Du meinst dass "nicht ca. 5
> Minuten auf ein _delay_ms(250) warten zu wollen/können" falsche
> Bedienung ist :-) )

Bei mir funktioniert auch das Durchsteppen im Simulator problemlos. Da 
muss man keine 5 Minuten warten ...

von Hugo H. (hugo_hu)


Lesenswert?

HildeK schrieb:
> Bei mir funktioniert auch das Durchsteppen im Simulator problemlos. Da
> muss man keine 5 Minuten warten ...

Ja.

Da habe ich zu hoch geschätzt (aus der kurzen Durchlaufzeit mit 
delay_ms(1)).

Im Microchip-Studio (WIN 10) sind es 1 Minute 42 Sekunden, im 
AtmelStudio 6.2 (XP) in einer virtuellen Maschine sind es knapp 54 
Sekunden (jeweils mit dem "originalen" _delay_ms(250.0); ).

Welchen Simulator (in welcher IDE) nutzt Du?

: Bearbeitet durch User
von HildeK (Gast)


Angehängte Dateien:

Lesenswert?

Hugo H. schrieb:
> Welchen Simulator (in welcher IDE) nutzt Du?

Mein altes Atmel Studio 4.18SP2 unter WIN7. Da steppe ich von Hand (F11)
oder mit Autostep; geht genau so.

Bei solchen Sachen (Delay, Timer, Watchdog) ist es meist problematisch 
mit dem Simulieren, da gebe ich dir recht.
Offenbar arbeitet der (mein) Simulator virtuell mit 4 MHz. Wenn ich den 
Code mit F_CPU = 16MHz übersetze, ja, dann dauert es natürlich länger. 
Ich hatte ihn mit 1MHz übersetzt (und auf den Tiny26 gebrannt), damit 
wird es etwas schneller als in Echtzeit bei Autostep.

Siehe Anhang

von Hugo H. (hugo_hu)


Lesenswert?

HildeK schrieb:
> Ich hatte ihn mit 1MHz übersetzt (und auf den Tiny26 gebrannt), damit
> wird es etwas schneller als in Echtzeit bei Autostep.

Klar - je nachdem, wie Du übersetzt (F_CPU bestimmt die delay-Cycles) 
geht es auch schneller. Aber so schnell wie in Deinem Video? Den Test 
(eine WIN 7 VM habe ich auch noch) mache (mit AS 4.18) ich noch (heute 
oder morgen) - ich melde mich ...

: Bearbeitet durch User
von HildeK (Gast)


Lesenswert?

Hugo H. schrieb:
> Aber so schnell wie in Deinem Video?

Ich habe jedenfalls nichts getrickst bei dem Video. Es entspricht dem, 
was ich auf dem Schirm sehe. War übersetzt mit '-Os'; geht ja bei Delays 
nicht mit '-O0'. Als Simulator habe ich den AVR Simulator genommen.
Da oben mal die Realzahl beim _delay_ms-Argument angemerkt wurde, habe 
ich beide Varianten drin.
Und meine Quadcore CPU hat auch schon einige Jahre auf dem Buckel: 
i7-4770 ...

von Hugo H. (hugo_hu)


Lesenswert?

HildeK schrieb:
> Und meine Quadcore CPU hat auch schon einige Jahre auf dem Buckel:
> i7-4770 ...

Prozessor  Intel(R) Core(TM) i7 CPU         920  @ 2.67GHz, 2668 MHz, 4 
Kern(e), 8 logische(r) Prozessor(en)

Ich bin gespannt auf 4.18 :-)

Kannst Du bitte Dein Projekt hier einhängen?

: Bearbeitet durch User
von HildeK (Gast)


Lesenswert?

Hugo H. schrieb:
> Kannst Du bitte Dein Projekt hier einhängen?

Das Projekt nützt dir leider nichts: es hat absolute Pfade drin.
Hier steht der Code:
Mans A. schrieb:
> ...
Mach ein neues auf, wähle den Tiny26 oder 261 und nimm den AVR 
Simulator. Kopiere den Code rein, ändere F_CPU auf 1MHz compiliere mit 
-Os und simuliere ...
Mehr habe ich auch nicht gemacht.

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.