Forum: Mikrocontroller und Digitale Elektronik Kleines Testprogramm tut nicht was es soll (C)


von Fritz B. (kleinfritzchen)


Lesenswert?

Ich hab ein kleines Programm geschrieben was eigenzlich auf einen 
Tstendruck einen Zähler hochzählen soll und das Ergebnis auf 4 
Leuchtdioden ausgeben soll.
Irgendwie hab ich das Gefühl das das Programm nur ein mal durchlaufen 
wird.
Ich hab zum lernen ein AVR-C Tutorial von 2007. Ich hoffe das passt noch 
halbwegs da ich Anfänger bin und noch nicht die Ahnung hab.
Hier mal das Programm:
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#define F_CPU 1000000UL
4
5
int main (void) {
6
  DDRD= 0x0f; //Port D die unteren 4 Bit als Ausgang
7
  DDRB= 0b00000000;
8
  PORTB = 0x02;// pull Up Wiederstand für ALLE PinS  aktiviert
9
  
10
  
11
  
12
    uint8_t tg=0;
13
    uint8_t taste=0;
14
    uint8_t dioden = 0;
15
  PORTD=0x0f;
16
  _delay_ms(500);
17
  PORTD=0x00;
18
  _delay_ms(100);
19
    
20
  while(1){
21
    
22
    if (!(PINB & (1<<PB1))){
23
      dioden++;
24
      PORTD=dioden;
25
      _delay_ms(100);
26
      loop_until_bit_is_set(PINC,PC3);
27
    }
28
    PORTD ^= (1<<PD3);
29
    _delay_ms(200);
30
    PORTD ^= (1<<PD3);
31
    
32
    //dioden &= 0x0f;
33
    //PORTD = ++dioden;
34
    //PORTD = taste;
35
    return 0;
36
  }
37
    
38
}
Ich hoffe  es kann mir mal einer erklähren warum die Diode an PD3 nicht 
laufend blinkt.

MfG Fritz

von Captain Obvious (Gast)


Lesenswert?

return 0 steht in der schleife

von Christian Karle (Gast)


Lesenswert?

Um die LED anzuschalten musst Du schreiben:

PORTD|= (1<<PD3);

Und um sie auszuschalten:

PORTD&= ~(1<<PD3);

Deine Befehle Löschen weder ein Bit, noch setzten Sie eines.

von Captain Obvious (Gast)


Lesenswert?

^= ist ein XOR, d.h. toggeln (ist schon alles wies sein soll)
Nach dem zweiten ^= solltes man ein delay einfügen, weil du sonst das 
Blinken nicht siehst, weil es zu schnell ist.

von Christian Karle (Gast)


Lesenswert?

Die Delays vor der While-Schleife sind unnötig. Um ein Blinken 
wahrnehmen zu können fehlt ein Delay nach

PORTD &= ~(1<<PD3);

_delay_ms(200);

von Christian (Gast)


Lesenswert?

Was tut denn diese ominöse Funktion?
loop_until_bit_is_set()
Hängt er da vielleicht in dem loop?
Ansonsten halte ich es ebenfalls für Unsinn, ein Return 0 in die 
While(1)-Schleife einzubauen ;-)

von Rolf M. (rmagnus)


Lesenswert?

Christian schrieb:
> Was tut denn diese ominöse Funktion?
> loop_until_bit_is_set()

Der Name könnte doch eindeutiger nicht sein. Ist aber ein Makro:
http://www.atmel.com/webdoc/AVRLibcReferenceManual/group__avr__sfr_1gaaf6857fa882da35f8685e2001e5c3bbe.html

> Ansonsten halte ich es ebenfalls für Unsinn, ein Return 0 in die
> While(1)-Schleife einzubauen ;-)

Was auch relativ gut dieses Problem erklärt:

Fritz Bie schrieb:
> Irgendwie hab ich das Gefühl das das Programm nur ein mal durchlaufen
> wird.

von Fritz B. (kleinfritzchen)


Lesenswert?

Danke das war auch der Fehler mit dem Return in der Schleife!
Die Funktion loop_until_bit_is_set() dient hier eigentlich nur um ein 
sehr einfaches entprellen zu ermöglichen. Ist zwar unschön aber tuts für 
den Anfang.
Das Blinken vor der While Schleife dient nur dazu die Kontakte auf dem 
Steckbrett zu überprüfen. Und die Zeitschleifen in der While Schleife 
sind auch nur zum verlangsamen da.
Ich hab schon mal einen Einführungskurs in Assembler auf der 
Folkshochschule gemacht von da her kenn ich wenigstens ein bischen aus.
Danke für die schnelle Hilfe!!!


Mfg Fritz

von Christian (Gast)


Lesenswert?

Rolf Magnus schrieb:
> Christian schrieb:
>> Was tut denn diese ominöse Funktion?
>> loop_until_bit_is_set()
>
> Der Name könnte doch eindeutiger nicht sein. Ist aber ein Makro:
> 
http://www.atmel.com/webdoc/AVRLibcReferenceManual/group__avr__sfr_1gaaf6857fa882da35f8685e2001e5c3bbe.html

Und ich dachte es wäre eine selbst-gefrickelte Funktion, die uns 
vorenthalten wird ;-)

von NSA (Gast)


Lesenswert?

F_CPU im makefile definieren (oder wenigstens vorm einbinden der 
delay.h). Sollte eigentlich ne Warnung verursachen.

Ist aber wahrscheinlich nicht Ursache des Problems.

von Karl H. (kbuchegg)


Lesenswert?

weiters
1
    if (!(PINB & (1<<PB1))){      <-------------- PIN B
2
      dioden++;
3
      PORTD=dioden;
4
      _delay_ms(100);
5
      loop_until_bit_is_set(PINC,PC3); <--------- PIN C
6
    }

du solltest dich schon mit dir selbst darüber einig sein, an welchem Pin 
nun der Taster hängt

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.