AVR will Pin nicht einlesen

Der chaotische Hauptfaden

Moderatoren: Heaterman, Finger, Sven, TDI, Marsupilami72, duese

Antworten
Benutzeravatar
Nicki
Beiträge: 3128
Registriert: So 11. Aug 2013, 20:16
Wohnort: wo Mosel und Rhein sich treffen

AVR will Pin nicht einlesen

Beitrag von Nicki »

Moin,
ich habe hier einen Atmega88, der PC2 mit nem internen Pullup auf 3,3V zieht und sich mittels Taster auf GND ziehen lässt (tut soweit, etwa 80µA bei Kurzschluss).
Jetzt soll er gucken, was sich an dem Pin tut.
Ist nicht so zeitkritisch, daher müsste ich auch ohne Interrupt auskommen.
Nur: weder

Code: Alles auswählen

if(PINC2==0)
{
}
noch

Code: Alles auswählen

a=PINC2;
if(a==0)
{
}
werden aufgerufen, wenn ich den Taster drücke.
Die Anweisung da drin knipst ne LED an (aber vorerst mal nicht aus).
Bei der tut sich nix, also schaut er wohl nie dort vorbei.
Warum zum Geier?
Muss ich wirklich den ganzen Port auslesen und das einzelne Bit da rausfummeln?
bastelheini
Beiträge: 1663
Registriert: So 11. Aug 2013, 13:55

Re: AVR will Pin nicht einlesen

Beitrag von bastelheini »

JTAG ausschalten?
Benutzeravatar
Nicki
Beiträge: 3128
Registriert: So 11. Aug 2013, 20:16
Wohnort: wo Mosel und Rhein sich treffen

Re: AVR will Pin nicht einlesen

Beitrag von Nicki »

Hat der anscheinend gar nicht.
In den Fuses ist nur SPI aktiviert (was er ja iirc auch für ISP braucht).
enebk
Beiträge: 619
Registriert: Mi 14. Aug 2013, 18:51
Wohnort: Dorsten

Re: AVR will Pin nicht einlesen

Beitrag von enebk »

Ist das überhaupt die richtige Abfrage?

Ich benutze immer so etwas:

Code: Alles auswählen

if (! (PINC & (1<<PC2))) //Mach etwas wenn PinC2 low ist
{
}
bastelheini
Beiträge: 1663
Registriert: So 11. Aug 2013, 13:55

Re: AVR will Pin nicht einlesen

Beitrag von bastelheini »

sicher das PINC2 geht?
Normalerweise gibt es doch nur PINC als 8 bit Wert, wo man sich das entsprechende Bit rausselektieren muss?
Benutzeravatar
Kaputnik
Beiträge: 157
Registriert: Sa 15. Feb 2014, 06:54
Wohnort: Bayern

Re: AVR will Pin nicht einlesen

Beitrag von Kaputnik »

Das ist folgendermaßen definiert:

Code: Alles auswählen

#define PINC2   2
Kann also in der Form nicht gehen. :P
Benutzeravatar
ferdimh
Beiträge: 9430
Registriert: Fr 16. Aug 2013, 15:19

Re: AVR will Pin nicht einlesen

Beitrag von ferdimh »

Enebeks Lösung ist die richtige.
Die PINXy, PORTXy und DDRXy #defines sind nur dazu da, den Code "lesbarer" zu machen. Sie werden alle mit "y" ersetzt.
Die Ports sind immer 8 bit breit und werden auch so ein- und ausgelesen. Makros für einzelbits könnte man sich bauen, sinnvolle Benennungen sind durch die bereits vorhandenen PINXy #defines aber verbaut.
Benutzeravatar
Fritzler
Beiträge: 12604
Registriert: So 11. Aug 2013, 19:42
Wohnort: D:/Berlin/Adlershof/Technologiepark
Kontaktdaten:

Re: AVR will Pin nicht einlesen

Beitrag von Fritzler »

Wenn man von der Arduinowelt auf ordentliches C umsattelt, dann das hier durchlesen:
http://www.mikrocontroller.net/articles/Bitmanipulation
Benutzeravatar
Nicki
Beiträge: 3128
Registriert: So 11. Aug 2013, 20:16
Wohnort: wo Mosel und Rhein sich treffen

Re: AVR will Pin nicht einlesen

Beitrag von Nicki »

Und ich schlafe in der Dusche, denn die Dusche ist normal...
Danke, jetzt läufts ;)
Benutzeravatar
eJunkie
Beiträge: 756
Registriert: Mi 14. Aug 2013, 20:05

Re: AVR will Pin nicht einlesen

Beitrag von eJunkie »

Ob PINxn leserlicher ist... Ich habe das NIE verstanden was die AVR Leute da geritten hat. Wenn man (aus welchen Gründen auch immer) den Code von PORTA nach PORTB umschreiben muss, dann muss man alle Konstanten ersetzen. Ne, halt... muss man ja gar nicht weil Bit n ist ja immer noch Bit n. Oder besser doch, damit es leserlich bleibt. Renudante Informationen sind nie gut, der Port geht ja idR. direkt aus dem Kontext hervor. Ich persönlich schreibe da wirklich lieber direkt 1 << 2. Das kann man auch in Macros verwenden wo die konkrete Nennung eines Ports auch arg komisch kommt. Die 1 << n Notation hat auch schon so einige Leute genarrt die es gewohnt sind das die Konstanten Bitmasken statt Bitnummern sind. Am liebsten wären mir Konstanten wie PORT_BIT2 = 0x100b
Benutzeravatar
Bauteiltöter
Beiträge: 254
Registriert: So 11. Aug 2013, 17:37

Re: AVR will Pin nicht einlesen

Beitrag von Bauteiltöter »

Ich finde das prinzip eigentlich ganz praktisch, mit ein paar einfachen Makros bleibt es auch sehr gut auf andere Hardware portierbar.

Code: Alles auswählen

#define LED_DDR DDRA
#define LED_PORT PORTA
#define LED 5

...

LED_DDR |= (1<<<LED);
LED_PORT |= (1<<LED);
bzw für eingänge:

Code: Alles auswählen

#define BUTTON_DDR DDRB
#define BUTTON_PIN PINB
#define BUTTON 3

...

BUTTON_DDR &= ~(1<<BUTTON);
if(BUTTON_PIN & (1<<BUTTON))
{
...
}
Wenn sich dann die Hardware ändert, muss man nur die Makros ändern, die bei größeren Projekten noch in einer anderen Header-Datei liegen als das normale Programm. ist vielleicht am Anfang etwas gewöhnungbedürftig, funktioniert aber sehr gut.
Benutzeravatar
Fritzler
Beiträge: 12604
Registriert: So 11. Aug 2013, 19:42
Wohnort: D:/Berlin/Adlershof/Technologiepark
Kontaktdaten:

Re: AVR will Pin nicht einlesen

Beitrag von Fritzler »

Und damit man nicht zwischen PIN/PORT/DDR unterscheiden muss:

Code: Alles auswählen

#define DDR(x) (*(&x - 1))
#define PIN(x) (*(&x - 2))
Frisst den PORT define und wandelt das um.

Code: Alles auswählen

DDR(PORTA) = (1 << PA0);
Benutzeravatar
eJunkie
Beiträge: 756
Registriert: Mi 14. Aug 2013, 20:05

Re: AVR will Pin nicht einlesen

Beitrag von eJunkie »

Huch ???

Das funtzt auf allen AVRs? Ich meine ja nur wg. Speicherlayout und so...

Edit sagt noch: Mit der direkten Bitnummer schreiben meine ich natürlich nicht im Code, sondern in den defines. Das Beispiel "#define LED 5" ist also genau so wie ich es machen würde, außer das ich direkt #define LED (1 << 5) schreiben würde. Dann kann man sich das spätere geshifte auch sparen.
Benutzeravatar
Fritzler
Beiträge: 12604
Registriert: So 11. Aug 2013, 19:42
Wohnort: D:/Berlin/Adlershof/Technologiepark
Kontaktdaten:

Re: AVR will Pin nicht einlesen

Beitrag von Fritzler »

Das funzt bei allen bis auf nen paar Ausnahmen, glaube Mega103 und noch einer.
Ansonsten liegen die 3 Register immer schön in dieser Reihenfolge hintereinander.
Benutzeravatar
eJunkie
Beiträge: 756
Registriert: Mi 14. Aug 2013, 20:05

Re: AVR will Pin nicht einlesen

Beitrag von eJunkie »

Der Trick ist gleich mal abgeheftet, gefällt mir :D
Benutzeravatar
Zabex
Beiträge: 633
Registriert: Di 2. Jul 2013, 08:45
Wohnort: Aldenhoven
Kontaktdaten:

Re: AVR will Pin nicht einlesen

Beitrag von Zabex »

Inzwischen habe ich mir angewöhnt, im Programmkopf 8 Bits zu definieren:

Code: Alles auswählen

#define BIT0 1
#define BIT1 2
#define BIT2 4
#define BIT3 8
#define BIT4 16
#define BIT5 32
#define BIT6 64
#define BIT7 128
Initialisierungscode sieht dann z.B. bei meiner RGB-LED-Steuerung so aus (ich find's gut lesbar):

Code: Alles auswählen

  DDRB = BIT0 | BIT1 | BIT2; //RGB-Leds
  DDRC = 0;
  DDRD = BIT0 | BIT1 | BIT2 | BIT3 | BIT4; //Tasten-LEDs

  PORTB=0;
  PORTC=BIT3 | BIT4 | BIT5; //Pull-Ups für Tasten
Zugriffe auf Ports werden dann noch benannt:

Code: Alles auswählen

#define BLAU_EIN {PORTB|=BIT0;}
#define BLAU_AUS {PORTB&=~BIT0;}
Und schon ist der Code lesbar und wartbar.
Benutzeravatar
Torpert
Beiträge: 1436
Registriert: Mo 12. Aug 2013, 22:40
Wohnort: Saarland
Kontaktdaten:

Re: AVR will Pin nicht einlesen

Beitrag von Torpert »

Zabex hat geschrieben:Inzwischen habe ich mir angewöhnt, im Programmkopf 8 Bits zu definieren:

Code: Alles auswählen

#define BIT0 1
#define BIT1 2
#define BIT2 4
#define BIT3 8
#define BIT4 16
#define BIT5 32
#define BIT6 64
#define BIT7 128
Initialisierungscode sieht dann z.B. bei meiner RGB-LED-Steuerung so aus (ich find's gut lesbar):

Code: Alles auswählen

  DDRB = BIT0 | BIT1 | BIT2; //RGB-Leds
  DDRC = 0;
  DDRD = BIT0 | BIT1 | BIT2 | BIT3 | BIT4; //Tasten-LEDs

  PORTB=0;
  PORTC=BIT3 | BIT4 | BIT5; //Pull-Ups für Tasten
Zugriffe auf Ports werden dann noch benannt:

Code: Alles auswählen

#define BLAU_EIN {PORTB|=BIT0;}
#define BLAU_AUS {PORTB&=~BIT0;}
Und schon ist der Code lesbar und wartbar.
Schöne Lösung, die sollte für die Nachwelt erhalten bleiben. Am besten im Wiki, oder?
Antworten