Probleme beim Einlesen vom Dip-Schalter

Gast #2002432
Lesenswert?

Hallo zusammen, Ich möchte den Wert eines Dipschalters einlesen. Dieser 
hat 8 schalter und belegt so genau den Port B des Atmega8. im 
Mainprogramm, vor der Programmschleife initialisiere ich nun die Ports 
und lese den wert von Port B ein. Dieser wird in eine uint8_t variable 
geschrieben. Dann beginnt das eigentliche Programm in der while(1).
Jedoch wird der auf dem Dipschalter binär eingestellte wert nur manchmal 
nach dem reset des kontrollers übernommen, jedoch nicht bei jedem 
reset/startup. kann mir jemand sagen, warum?
1
#include <avr/io.h> 
2
             
3
uint8_t wert;
4

5
int main (void) 
6
{            
7
 
8
   DDRB  = 0x00;  //Data Direction Register Port B als input           
9
   PORTB = 0xff;  //Interne Pullup Widerstände für B aktivieren
10

11
   wert = (~PINB);  
12
   while(1)
13
   {
14
    //hier ist der Rest des programms
15
   }
16

17
return 0;  
18
}
Gast #2002500
Lesenswert?

danke schonmal für die hilfe.

Thomas Eckmann, Da ich pullup widerstände benutzte liegt an den ports 
bei schalterstellung "0" eine Logische "1". Daher dachte ich, der Port 
muss Bitweise Invertiert werden, damit die logische 0 am eingang auch 
der 0 im register entspricht. Diese Annahme ist doch richtg, oder? 
Verwunderlich finde ich ja, dass es machchmal nach dem startup/reset des 
controllers funktioniert und ein wert eingelesen wird und manchmal 
nicht.
Gast #2002513
Lesenswert?

>Verwunderlich finde ich ja, dass es machchmal nach dem startup/reset des
>controllers funktioniert und ein wert eingelesen wird und manchmal
>nicht.

Warte mal ein bisschen nach einschalten der Pullups.
Deine Schaltungskapazitäten wollen auch aufgeladen werden;)
Gast #2002575
Lesenswert?

so, ich habe das programm jetzt modifiziert:

1
#include <avr/io.h> 
2
#define F_CPU 1000000     /* Interner oszillator mit 1.0000 Mhz */         
3
#include <util/delay.h>  
4
           
5
uint8_t wert;
6

7
int main (void) 
8
{            
9
 
10
   DDRB  = 0x00;  //Data Direction Register Port B als input           
11
   PORTB = 0xff;  //Interne Pullup Widerstände für B aktivieren
12
   DDRC  = 0xff;  //Data Direction Register Port C als output 
13
   PORTC = 0x00;  //alle Portpins C auf NULL setzen
14

15
 
16
   _delay_ms(100);
17
   wert = (~PINB);  
18

19
   while(1)
20
   {
21
    if (wert==2)            //testprogramm
22
      {PORTC = 0xff}
23
   }
24

25
return 0;  
26
}


ich habe als Beispiel am dipschalter 00000010 eingestellt, also eine 2. 
wenn die 2 eingelesen wurde gehen leds an portC an. bevor der Wert 
eingelesen wird habe ich noch eine 100ms pause verbaut. Allerdings 
bleibt das problem dass in der hälfte der fälle kein Wert eingelesen 
wird.
#2002612
Lesenswert?

Marco schrieb:
> wo ist denn der syntaxfehler? ich sehe irgendwie keinen;)


Dein Compiler sagt ihn dir.

Im Ernst: Du musst auf solche Dinge achten. Ausnahmslos immer nach dem 
Build Vorgang dsas Ausgabefenster studieren, ob es irgendwo einen Fehler 
gab. Sonst brennst du ständig ein altes HEX_File in den µC und wunderst 
dich, warum deine Programmänderungen nichts bewirken.
#2002628
Lesenswert?

Marco schrieb:
> Diese Annahme ist doch richtg, oder?

Das ist richtig. Kann man natürlich so machen. Ich denke allerdings 
immer Low-Aktiv.
Ich hab das mal mit Tilde ausprobiert, hab' ich noch nie so gemacht. 
Funktioniert, auch ohne Delay. Mit oder ohne invertieren.
Da ist viellecht irgendwas anderes nicht in Ordnung.
Stützkondensator, Lötfehler etc. ?

Marco schrieb:
> Allerdings
>
> bleibt das problem dass in der hälfte der fälle kein Wert eingelesen
>
> wird.

Wird denn kein Wert, ich vermute mal du meinst damit 0, eingelesen oder 
wird irgendwas gelesen?


Ändere das mal:

Marco schrieb:
> if (wert==2)            //testprogramm
>
>       {PORTC = 0xff}

  PORTC = wert;

damit du siehst was da reinkommt.

mfg.
#2002633
Lesenswert?

Marco schrieb:
> achso, hab das ; vergessen. Ich habs gefunden, danke. Aber das ist nur
> im Forum falsch, nicht im Programm.

Du bist neu hier.
Drum sei dir gesagt, dass die Forenteilnehmer so etwas gar nicht gerne 
sehen, wenn du Code hier präsentierst, der so nie auf deiner Hardware 
gelaufen ist.
Denn dann suchen (und finden) wir Fehler, die im richtigen Code gar 
nicht existieren. Sprich: Wir machen uns Arbeit für nichts.

Wenn du deinen Code immer per Cut&Paste aus deinem Programmeditor 
übernimmst, dann kann das nicht passieren.

> Also ich fürchte, daran liegts auch
> nicht

Mach mal folgendes:
An Port B sind ja auch die Anschlüsse für eine externe Taktversorgung.

Ändere deine Abfrage mal so um, dass tatsächlich wirklich nur der eine 
DIP-Schalter abgefragt wird und der Rest des Port-Zustandes egal ist.
1
   while(1)
2
   {
3
     if (wert & 0x02)            //testprogramm
4
     {
5
       PORTC = 0xff;
6
     }
7
   }

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren