Forum: Mikrocontroller und Digitale Elektronik Warum blinkt hier nix? (C-Code)


von Markus N. (roboscan)


Lesenswert?

Hi.
Ich habe heute meinen ersten test Chip bekommen.
Ich möchte gerne das die LEDs abwechselnd blinken aber warum tun sie
das nicht?
1
#include <avr/io.h>
2
3
#ifndef F_CPU
4
#define F_CPU 7372800UL
5
#endif
6
7
#include <avr/delay.h>
8
9
int main(void)
10
{
11
  
12
DDRA = 0x00; // Setzt alle Pins des Ports A auf Eingang
13
PORTA = 0xFF; //Pull-Up Wiederstände an
14
15
16
DDRB = 0xFF; // Setzt alle Pins des Ports B auf Ausgang;
17
PORTB = 0xFF; //PortB ausschalten
18
19
20
while (1 > 0)
21
{
22
  PORTB = 0x00; //PortB einschalten
23
  _delay_ms(200);
24
  
25
  PORTB = 0xFF; //PortB ausschalten
26
  _delay_ms(200);
27
28
}
29
30
}

Ich komme einfach nicht dahinter.

Gibt es ausserdem noch ne elegantere Version als meine While Schleife
zum Schluss damit sich alles immer wiederholt?

von Werner B. (Gast)


Lesenswert?

Zuerst das einfachere...

while(1)   oder    for(;;)

Jetzt das komplexere.

Sieh Dir doch mal die Kommentare im avr/delay.h zu _delay_ms() an  :)
(bzw. ab libc v1.0.4 in util/delay.h)

"The maximal possible delay is 262.14 ms / F_CPU in MHz."

Zudem sollen die ms als float Wert angegeben werden :)

von Michael Wilhelm (Gast)


Lesenswert?

zu Frage 2:
1.  while(1)
    {
      ...
    }

2.   for(;;)
     {
       ...
      }

zu Frage 1. LEDs falsch gepolt?? Mal mit einem Messeisen am Port
nachmessen, ob ein Spannungswechsel zu detektieren ist.

Wenn nicht, dann kommen Oszillator, Resetpin-Beschaltung,
Versorgungsspannung ... in Frage.

MW

von Markus N. (roboscan)


Lesenswert?

Ne die LEDs sind ja an... aber blinken tun sie eben nicht.

Hab das von dir Werner nicht ganz kappiert.
Also aus den Kommentaren werde ich nicht schlau, sorry bin noch totaler
Anfänger auf dem gebiet.
Und was is'n float Wert?

Wäre super wenn du mir den Code kurz so schreiben könntest damit es
auch läuft. Dann hätte ich jetzt ein Beispiel und dann kann ich darauf
aufbauen.

Danke für eure Antworten.

von Rahul (Gast)


Lesenswert?

1. wenn du while(1) schreibst, hast du eine Endlosschleife, was eine
kürzere Formulioerung als deine ist.

2. die grösste Zahl, die du bei _delayms einsetzen kannst, wird durch
262.14ms/ Fosc in MHz beschrieben.
Du hast 7,xx MHz, also kannst du keine 200ms verzögern.

Nimm sonst erst mal ein paar verschachtelte For-Schleifen (2 von 0-255
und eine bis 50). Dann hast du erst mal ein Blinken...

von Markus N. (roboscan)


Lesenswert?

Ah danke Raul probier ich sofor aus.

von Markus N. (roboscan)


Lesenswert?

Juhuuuuu es funktioniert

hab jetzt folgendes geschrieben
1
#include <avr/io.h>
2
#include <stdint.h>
3
4
uint8_t w1;
5
uint8_t w2;
6
uint8_t w3;
7
uint8_t w4;
8
9
10
int main(void)
11
{
12
  
13
DDRA = 0x00; // Setzt alle Pins des Ports A auf Eingang
14
PORTA = 0xFF; //Pull-Up Wiederstände an
15
16
17
DDRB = 0xFF; // Setzt alle Pins des Ports B auf Ausgang;
18
PORTB = 0xFF; //PortB ausschalten
19
20
21
while (1)
22
{
23
  for (w1=1; w1 <= 200; w1++)
24
  {
25
    for (w2=1; w2 <= 200; w2++)
26
    {  
27
    }
28
  }
29
30
  PORTB = 0x00; //PortB einschalten
31
  
32
  for (w1=1; w1 <= 50; w1++)
33
  {
34
    for (w2=1; w2 <= 200; w2++)
35
    {
36
    }
37
  }
38
  
39
  PORTB = 0xFF; //PortB ausschalten
40
41
}
42
43
}

Dank euch ;-)

von Johannes (Gast)


Angehängte Dateien:

Lesenswert?

Hi,

hier haste ne delay-funktion (Timer-Funktion), die in etwa
Millisekunden verzoegert.

Schreibst am anfang in dein Programm: "#include <delayms.c>"

und nachher kannste ueberall "delayms(200)" reinschreiben um zB
200Millisekunden abzuwarten. Geht auch mit 3000 fuer 3 Sekunden usw...

mg,
Johannes

von Markus N. (roboscan)


Lesenswert?

HI Johannes
Ich weiß leider noch nicht genau wo der Fehler in deinem Code liegt
aber es tut sich mit z.B. delayms(200) oder auch delayms(2) garnix.


Noch eine Theoretische frage.
Angenommen mein IC arbeitet mit einer Taktfrequenz von 4 MHz.
Dann müsste ich doch mit folgendem Code genau 1ms verzögern oder
nicht?

for (w1=1; w1 <= 4; w1++)
{
     for (w2=1; w2 <= 1000; w2++)
     {
     }
}

von Rahul (Gast)


Lesenswert?

nein.weil da noch etwas "Overhead" durch die Schleifen ansich entsteht
(Initialisierung, Überprüfen der Abbruchbedingung etc).
Ausserdem wird es kaum gehen mit einem uint8 bis 1000 zu zählen...

Besorg dir am besten ein vernünftiges C-Buch z.B. K&R "Programmieren
in C".

von Markus N. (roboscan)


Lesenswert?

is ja auch unit16 aber danke ich werd mir auch morgen ein Buch für C
holen ;-)
somit werd ich deinen Buch Tip anschauen.

von Lumpi (Gast)


Lesenswert?

Delays sind die schlechteste Lösung. Damit blockiert man den Controller
. Besser ist es, in einem Timer-Interrupt Variablen
auf/abzählen zu lassen. Diese Variable kann man auf zB. 0 testen
und dann eine Aktion auslösen.

SG Lumpi

von Lumpi (Gast)


Lesenswert?

Timerinterrupt zB alle 1ms:

if (Timer_ms > 0) Timer_ms--;


Main:

if (Timer_ms == 0) {PORTA = !PORTA ; Soft_Timer = 300;}



SG Lumpi

von Markus N. (roboscan)


Lesenswert?

Das mit den Timern werde ich angreifen wenn ich erst ma den Grundaufbau
von den AVRs kappiert hab.
Im Moment kämpfe ich noch mit den Eingängen.
Aber danke.

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.