Forum: Compiler & IDEs Problem mit Eingangspinabfrage


von dgraebn (Gast)


Lesenswert?

Hallo!
Ich bin noch relativ neu in der Welt der Mikrocontroller und habe schon 
ein wundersames Problem, welches ich nicht verstehe.
Im folgenden Quelltext sollen die Ausgänge PB0 und PB3 auf High gesetzt 
werden, sobald am Pin PB2 ein Signal kommt und danach für 10 Sekunden in 
diesem Zustand bleiben. Dabei wird am Ausgang PB3 immer wieder zwischen 
Low und High gewechselt, um ein blinken an den angeschlossenen LEDs zu 
erzeugen.
Das ganze ist auf einen ATtiny13A-SSH programmiert. PB2 ist gegen VCC 
geschaltet und dazwischen ist ein Schalter.

Jetzt zum Problem:
Sobald man das Netzteil einsteckt, werden PB0 und PB3 auf High gesetzt. 
Da diese über Widerstand und LEDs gegen GND geschaltet sind, fangen die 
LEDs an zu leuchten bzw. zu blinken. Dies geschieht jedoch ohne dass der 
Schalter zwischen VCC und PB2 geschlossen wurde. Folglich erhält der 
Eingang kein Signal. Warum wird dann in den if-Teil gesprungen und PB0 
und PB3 auf High gesetzt?

Liebe Grüße!

1
#include <avr/io.h>
2
#include <util/delay.h>
3
4
int main(void)
5
{
6
  DDRB |= (1<<PB3)|(1<<PB0); //PB0, PB3 auf Ausgang
7
  DDRB &=~ (1<<PB2); //PB2 auf Eingang
8
  PORTB &=~ ((1<<PB3)|(1<<PB0)); //PB0, PB3 auf Low
9
    while(1)
10
    {
11
    if(PINB&(1<<PB2))
12
    {
13
      for(uint8_t i=0; i< 10; i++) // 10 mal = 10 sec
14
      {
15
        PORTB |= (1<<PB3)|(1<<PB0); //PB0, PB3 auf High --> LEDs leuchten
16
        _delay_ms(500);
17
        PORTB &=~ (1<<PB3); //PB3 auf Low für Blinken
18
        _delay_ms(500);
19
      }
20
      
21
    }
22
    else
23
    {
24
      PORTB &=~ (1<<PB0);
25
    }
26
    
27
        //TODO:: Please write your application code 
28
    }
29
}

von Karl H. (kbuchegg)


Lesenswert?

Schalter oder Taster lässt man nicht nach Vcc schalten, sondern nach 
GND.
Denn dann kann man den internen Pullup-Widerstand zuschalten.

Will man unbedingt nach Vcc schalten, dann muss an den Eingangspin ein 
externer Pulldown-Widerstand. So ungefähr 10k vom Pin direkt nach GND.


Denn: es ist ein Trugschluss, dass man an einem offfenen Eingangspin 
eine 0 misst. Der Pin wirkt wie eine Antenne und fängt sich jedes 
elektromagnetische Feld aus der näheren Umgebung ein. Und davon gibt es 
viele: Radio, Fensehen, die 230V Leitung in der Wand, du selber, ...

von Andreas B. (bitverdreher)


Lesenswert?

Hallo,
sollten PB0 und PB3 offen sein, so sind die Eingänge 1.
Du mußt die Eingänge mit einem Widerstand gegen GND schalten.
Besser: Eingänge mit Schalter gegen GND schalten, nicht gegen Vcc.

Gruß
Andreas

Edit: zu spät..

von dgraebn (Gast)


Lesenswert?

Danke für den Hinweis. Schalte ich dann einfach gegen GND und frage ab, 
ob der PB2 im Register PINB eine 0 hat?

Also im Prinzip:
1
if(~(PINB&(1<<PB2)))

Oder wie ist da die Syntax?

von Lötlackl *. (pappnase) Benutzerseite


Lesenswert?

dgraebn schrieb:
> Also im Prinzip:
> if(~(PINB&(1<<PB2)))
> Oder wie ist da die Syntax?

Besser ist
1
if(!(PINB&(1<<PB2)))

von Karl H. (kbuchegg)


Lesenswert?

** Lötlackl schrieb:
> dgraebn schrieb:
>> Also im Prinzip:
>> if(~(PINB&(1<<PB2)))
>> Oder wie ist da die Syntax?
>
> Besser ist
>
1
if(!(PINB&(1<<PB2)))

nicht nur "besser".

~ wäre falsch, weil das Ergebnis immer TRUE lauten würde, egal ob der 
Pin 0 oder 1 liefert.

Pin auf 0:  ~ 00000000 -> 11111111 -> ungleich 0 -> TRUE
Pin auf 1:  ~ 00000100 -> 11111011 -> ungleich 0 -> TRUE

Ansonsten
AVR-GCC-Tutorial

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.