www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik PIN bei Atmega128 abfragen


Autor: Roman (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich möchte bei einem Atmega128 den Zustand der PINS am PORTC anfragen. 
Ich setze diese als Eingang mit einem PULL UP und möchte einen von 
extern anliegenden LOW Pegel detektieren.

Habe also folgende Konfiguration:

 PORTC = 0xFF; //High setzen
 DDRC  = 0x00; //Eingang

Und eingentlich sollte es damit funktionieren:

(Für PIN 0 am PORT C)

if(PINC0 == 0)
{}

Leider funktioniert dies nicht.

Und dies hier auch nicht:

if((PINC &(1<<PINC0))== 1)


Wäre sehr dankbar, falls jemand einen Tip hat.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Roman wrote:

> Und eingentlich sollte es damit funktionieren:

nicht wirklich

> Und dies hier auch nicht:
>
> if((PINC &(1<<PINC0))== 1)

Das allerdings wäre richtig

> Wäre sehr dankbar, falls jemand einen Tip hat.

Poste doch mal dein komplettes Programm.

Autor: Roman (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

vielen Dank für eine schnelle Atnwort,

ich habe im Moment noch nicht viel Code, weil ich genau an der Stelle 
hänge.

void main(void)
{

   int n;
    CLI();  /*disable all interrupts*/
   init_devices();
   //SPI_MasterTransmit16Bit(0XAA, 0x00);
   //SPI_MasterTransmit16Bit(0XAE, 0x00);


   while(1)
   {


if((PINC &(1<<PINC0))== 1)
 {
test1 = 1;
}

 if((PINC &(1<<PINC1))== 1)
{
test2 = 1;
}

if((PINC &(1<<PINC2))== 1)
{
  test3 = 1;
}



}}

Autor: Daniel D. (bademeister)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mal ne evtl blöde Vermutung, aber lass doch mal den Vergleich weg. Evtl 
kommt bei dem UND was anderes als 1 raus..

Autor: Roman (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry,

der Vergleich sollte gar nicht rein. Ist wegen copy paste geblieben.

void main(void)
{

   int n;
    CLI();  /*disable all interrupts*/
   init_devices();
   //SPI_MasterTransmit16Bit(0XAA, 0x00);
   //SPI_MasterTransmit16Bit(0XAE, 0x00);


   while(1)
   {


if(PINC &(1<<PINC0))
 {
test1 = 1;
}

 if(PINC &(1<<PINC1))
{
test2 = 1;
}

if(PINC &(1<<PINC2))
{
  test3 = 1;
}



}

Autor: Roman (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und wieder ein copy fehler, ich möchte ja auf LOW Abfragen, also sollte 
es auch  if((PINC &(0<<PINC1))== 1) heißen.

Funktioniert leider nicht:


void main(void)
{

   int n;
    CLI();  /*disable all interrupts*/
   init_devices();
   //SPI_MasterTransmit16Bit(0XAA, 0x00);
   //SPI_MasterTransmit16Bit(0XAE, 0x00);


   while(1)
   {


if((PINC &(0<<PINC0))
 {
test1 = 1;
}

 if((PINC &(0<<PINC1))
{
test2 = 1;
}

if((PINC &(0<<PINC2))
{
  test3 = 1;
}



}

Autor: Daniel D. (bademeister)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mach aus dem (PINC & (1<<PINC0)) ein (!(PINC &(1<<PINC0)))
Das sollte klappen..

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

& macht eine Binärverknüpfung, das heißt Du bekommt 128, 64, 32, ... als 
Ergebnis, probiere doch mal:

(PINC & (1<<PINC0)) > 0

<< shiftet nach links, 0<<PINCx geht also nicht, da shiftest Du ja eine 
0, Du willst aber eine 1, also 1<<PINCx

Sebastian

Autor: Daniel D. (bademeister)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also das mit > 0 sollte das gleiche machen wie der Ausdruck, den ich 
oben gepostet habe. Denn ohne Vergleich wie z.B. == 1 wird die Klammer 
als Ergebnis eines Vergleiches angenommen. Sprich ist der Inhalt größer 
0 ist die Bedingung erfüllt und die Anweisungen ausgeführt.

Ist vom Sinn her das gleiche wie while(1) eine Endlosschleife ist.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sebastian wrote:
> & macht eine Binärverknüpfung, das heißt Du bekommt 128, 64, 32, ... als
> Ergebnis, probiere doch mal:
>
> (PINC & (1<<PINC0)) > 0


Mit dem > (größer) bin ich unglücklich.
Da lieferst du dich immer gewissen signed/unsigned Problemen aus. Wenn 
man das im Hinterkopf hat ist es an und für sich kein Problem, aber wenn 
es eine einfachere Lösung gibt ...

Alles was man wissen will ist doch:
Wenn ich nur dieses eine Bit vom Eingangs-Port übrig lasse, kommt dann 0 
raus (heist der Eingangs-Pin ist ebenfalls 0) oder nicht (dann bleibt 
als Zahlenwert, wie du richtig sagst 128, 64, 32, 16... raus, wobei der 
exakte Wert im Grunde nicht wirklich interessiert)
Die Frage, die sich stellt lautet also: Bleibt nach der Maskierung 0 
übrig oder nicht.
   if( ( PINC & ( 1 << PINC0 ) ) == 0 )
     // der Eingangspin war 0
bzw
   if( ( PINC & ( 1 << PINC0 ) ) != 0 )
     // der Eingangspin war 1, da er ja nicht 0 war
und da 0 signed und unsigned die gleiche Repräsentierung hat, ist man 
damit alle signed/unsigned Probleme los.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aber was anderes:
Bei Mega128 und Port C: gabs da nicht irgendein Problem mit den Fuse 
Bits, die man setzen musste um den Port als Eingang zu aktivieren

(Sorry: war ein halbes Jahr weg von AVR und mein Gedächtnic ist auch 
nicht mehr das was es mal war)

Autor: Roman (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, das mit

if( ( PINC & ( 1 << PINC0 ) ) == 0 )

funktioniert wunderbar. Vielen dank für die Tips und sehr schnelle 
Reaktion !!

PS. Tatsächlich funktioniert es beim PORTC mit PIN0 nicht, aber andere 
PINS des C Ports funktionieren.

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Bei Mega128 und Port C: gabs da nicht irgendein Problem mit den Fuse
>Bits, die man setzen musste um den Port als Eingang zu aktivieren

Mega103-Kompatibiltät lässt grüßen. Ich hätte eher an JTAG gedacht, aber 
laut Datenblatt ist der Betrieb des PortC nur als Ausgang möglich, wenn 
die Mega103-Compatible-Mode-Fuse gesetzt ist. Und die ist im 
Auslieferungszustand gesetzt.
JTAG hängt an PortF...(kann man auch ausschalten).

>if( ( PINC & ( 1 << PINC0 ) ) == 0 )

Kürzer:

If (!(PINC & (1<<PINC0)))

>if((PINC &(1<<PINC2))== 1)
Wenn PINC2 gesetzt ist, würde die Abfrage trotzdem nicht erfüllt werden, 
weil das Ergebnis von PINC & (1<<PINC2) nicht 1, sondern 4 wäre.
Sowas kann man gut dazu benutzen, wenn man nachgucken will, ob sich 
mehreren Port-Pins etwas getan hat:

if ((PINC & ((1<<PINC0) | (1<<PINC1) | (1<<PINC2)) == ((1<<PINC0) | 
(1<<PINC1) | (1<<PINC2))))
Dmit würde man feststellen, ob einer der Pins auf 0 gezogen wurde.

Autor: Roman (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tatsächlich, weil man eigentlich dann den falschen Bitwert abfragt.

Es funktioniert also nur zufälligerweise dann, wenn der abzufragender 
Bitwert Bit 0 ist.

Wie kann ich dann andere Bitstellen bzw. Port auf 0 Abfragen?

Wieso funktioniert eigentlich nicht folgende Abfrage:

if (PINC2 == 1)

oder

if (PINC2 == 0)

wäre doch ein logischer Zustand, der Abgefragt ist. Leider funktiniert 
es nicht im Contoller. Erkennt er die Zustände der einzelner Bits nicht?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Roman wrote:

> Wie kann ich dann andere Bitstellen bzw. Port auf 0 Abfragen?

mit 0 kannst du immer vergleichen.
Entweder das was nach der Maskierung übrig bleibt ist 0 oder es ist 
nicht 0. Welcher Wert dann genau übrig bleibt, hängt davon ab welches 
Bit du testest. Hab ich aber weiter oben schon ausgeführt

>
> Wieso funktioniert eigentlich nicht folgende Abfrage:
>
> if (PINC2 == 1)


Weil PINC2 ein Makro ist, welches schlicht und ergreifend zu 2 
expandiert.
Damit steht dann da

  if( 2 == 1 )

und das wird ja wohl nie wahr


Diese PINxx Makros sind einzig und alleine dazu gedacht Bit-Positionen 
an einem Port durchzuzählen und dafür einen schöneren Namen als einfach 
nur 2 zu geben. Mehr nicht. Insbesondere haben sie mit dem Port oder Pin 
Register nich das geringste zu tun. Es sind einfach nur symbolische 
Namen für konstante Zahlen.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.