Forum: Mikrocontroller und Digitale Elektronik Hilfe bei ATmega32 Programmierung


von Sebastian K. (freshhermi)


Lesenswert?

Ich habe seit einiger Zeit nicht mehr in C programmiert, und brauche 
jetzt Hilfe beim Programmieren eines ATmega32. Ich programmiere ihn über 
ISP mit einem mySmartUSB light. Er steckt auf einem fertigen Board und 
auf dem Board sind zwei LEDs und drei Taster. Das ganze Zeug hängt am 
PORTD und alles was ich machen möchte ist, die LEDs beim Drücken des 
Tasters umzuschalten, und der Code dafür sollte doch vergleichsweise 
einfach sein, leider schaffe ich es nicht, dass es funktioniert.

Hier ist der "lächerlich einfache" Code:

#include <avr/io.h>
#include <inttypes.h>
#include <stdio.h>

int main(void)
{
  // Port D initialization
  // Function: Bit7=Out Bit6=Out Bit5=Out Bit4=In Bit3=In Bit2=In 
Bit1=Out Bit0=Out
  DDRD=(1<<DDD7) | (1<<DDD6) | (1<<DDD5) | (0<<DDD4) | (0<<DDD3) | 
(0<<DDD2) | (1<<DDD1) | (1<<DDD0);


  // State: Bit7=0 Bit6=0 Bit5=0 Bit4=P Bit3=P Bit2=P Bit1=0 Bit0=0
  PORTD=(0<<PD7) | (0<<PD6) | (0<<PD5) | (1<<PD4) | (1<<PD3) | (1<<PD2) 
| (0<<PD1) | (0<<PD0);

  while ((PIND && (1<<PD2)) | (PIND && (1<<PD3)) | (PIND && (1<<PD4)))
  {
    PORTD=(1<<PD6) | (0<<PD5);
  }
  PORTD=(0<<PD6) | (1<<PD5);
}

Danke im Voraus!

von Dennis S. (eltio)


Lesenswert?

Das Problem wird wohl die Abfrage in deiner While-Schleife sein. Diese 
sollte meines Wissens nach "nur" eine Endlosschleife sein:
1
while(1){}

Die Abfrage auf die Pins machst du dann darin separat.

Gruß Dennis

von Sebastian K. (freshhermi)


Lesenswert?

Danke, guter Tipp! Funktioniert aber leider auch nicht wenn ich ne 
Endlosschleife mach, und darin eine if-Abfrage...

von Dennis S. (eltio)


Lesenswert?

Früher oder später wirst du das hier eh zu hören bekommen: Zeig mal 
deinen Code... und bitte nutze die Formatierung.

Gruß Dennis

von Sebastian K. (freshhermi)


Lesenswert?

Hier:
1
#include <avr/io.h>
2
#include <inttypes.h>
3
#include <stdio.h>
4
5
int main(void)
6
{
7
  // Port D initialization
8
  // Function: Bit7=Out Bit6=Out Bit5=Out Bit4=In Bit3=In Bit2=In Bit1=Out Bit0=Out
9
  DDRD=(1<<DDD7) | (1<<DDD6) | (1<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (1<<DDD1) | (1<<DDD0);
10
  // State: Bit7=0 Bit6=0 Bit5=0 Bit4=P Bit3=P Bit2=P Bit1=0 Bit0=0
11
  PORTD=(0<<PD7) | (0<<PD6) | (0<<PD5) | (1<<PD4) | (1<<PD3) | (1<<PD2) | (0<<PD1) | (0<<PD0);
12
  while(1)
13
  {  
14
    if ((PIND && (1<<PD2)) || (PIND && (1<<PD3)) || (PIND && (1<<PD4)))
15
    {
16
      PORTD=(1<<PD6) | (0<<PD5);
17
    }
18
    else
19
    {
20
      PORTD=(0<<PD6) | (1<<PD5);
21
    }      
22
  }  
23
}

von Karl H. (kbuchegg)


Lesenswert?

Sebastian Kappel schrieb:
> Hier:

Deine Taster sind so verschaltet, dass sie eine 1 liefern, wenn sie 
nicht gedrückt sind?`


>     if ((PIND && (1<<PD2)) || (PIND && (1<<PD3)) || (PIND && (1<<PD4)))

Tja.
Dann wird das nicht funktionieren.
Denn irgendeiner der Taster ist dann immer 'nicht gedrückt', wenn du nur 
auf einen draufdrückst.
Und da hier steht:

   wenn irgendeiner der Taster nicht gedrückt ist, dann ...

>     {
>       PORTD=(1<<PD6) | (0<<PD5);

... landest du daher 'immer' in diesem Zweig.


Drück mal auf alle 3 Taster gleichzeitig drauf. Dann sollte umgeschaltet 
werden.

von Karl H. (kbuchegg)


Lesenswert?

Sebastian Kappel schrieb:


>       PORTD=(1<<PD6) | (0<<PD5);

gratuliere.
Du hast dir soeben die Pullup Widerstände an den auf Input geschalteten 
Portpins PD2, PD3, PD4 weggeschaltet.
Ohne die wird dann aber auch deine Tastenabfrage nicht mehr 
funktionieren.



-> Gewöhn dir diese 'An einen Port als ganzes' Zuweisungs-Rundumschläge 
ab.

Du willst einzelne Pins an diesem Port schalten? Dann tu das auch!

Pin auf 1 setzen   PORTx |= ( 1 << PinNummer );
Pin auf 0 setzen   PORTx &= ~( 1 << PinNummer );


Alles andere ist nur ein 'Ask for trouble', weil du das Chaos, welcher 
Pin wann welchen Zustand haben muss, nicht mehr beherrschen kannst.

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz Buchegger schrieb:

> Drück mal auf alle 3 Taster gleichzeitig drauf. Dann sollte umgeschaltet
> werden.

Das nehm ich zurück.
Solange du das Chaos mit den Pullup Widerständen nicht bereinigt hast, 
wird da gar nichts korrekt funktionieren.

von Sebastian K. (freshhermi)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Du hast dir soeben die Pullup Widerstände an den auf Input geschalteten
> Portpins PD2, PD3, PD4 weggeschaltet.

Tut mir leid wenn ich jetzt sehr dumm wirke, aber ich kenn mich wirklich 
nicht gut aus...
Wieso schalt ich mir die Pullup Wid. so weg?
Was ist der Unterschied zwischen

PORTx = (1<<PD1);
und
PORTx |= (1<<PD1);

von Dennis S. (eltio)


Lesenswert?

Sebastian Kappel schrieb:
1
PORTx |= (1<<PD1);

entspricht
1
PORTx = PORTx | (1<<PD1);

Das heißt du "überschreibst" deinen alten Wert nicht sondern änderst 
ihn. (Ja ich weiß... überschreiben ist auch ändern.)

Zum Thema interne Pullup-Widerstände:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Interne_Pull-Up_Widerst.C3.A4nde

Gruß
Dennis

von Sebastian K. (freshhermi)


Lesenswert?

Ahhh!
Schon klar! Vielen Dank dafür!
So funktionierts auch...

von Stefan W. (dl6dx)


Lesenswert?

Sebastian Kappel schrieb:
1
if ((PIND && (1<<PD2)) || (PIND && (1<<PD3)) || (PIND && (1<<PD4)))
Willst du hier die Bits PD2 bis PD4 von PINB abfragen?

Dann muss das so aussehen:
1
if ((PIND & (1<<PD2)) || (PIND & (1<<PD3)) || (PIND & (1<<PD4)))

Lies mal http://www.mikrocontroller.net/articles/Bitmanipulation

Ach ja: Alternativ ginge übrigens auch
1
if ((PIND & ((1<<PD2) | (1<<PD3)| (1<<PD4)))

Grüße

Stefan

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.