AVR PORTE ansprechen wie genau?

Gast #4211376
Lesenswert?

Hi,

wenn ich bei einem ATMEGA162 PortE (Ausgang) beschreiben,in C, will geht 
es auf folgendes weise?

PORTE=0b001 BSP: Für PE0 =1 und alles andere = 0?

Oder muss ich schreiben 0b00000001 ?

Hintergrund ist folgender, ich habe eine Schaltung bei der ich den 
Fehler nicht finde. Und nun suche ich gerade ohne Zugriff auf die 
Schaltung selbst den Fehler zu finden. Und bei dem Punkt im Programm war 
ich mir unsicher.

Danke für eure Hilfe :-)
Gast #4211412
Lesenswert?

Johannes schrieb:
> Hi,
>
> wenn ich bei einem ATMEGA162 PortE (Ausgang) beschreiben,in C, will geht
> es auf folgendes weise?
>
> PORTE=0b001 BSP: Für PE0 =1 und alles andere = 0?
>
> Oder muss ich schreiben 0b00000001 ?

Auch zu beachten ist, dass nur der GCC diese Schreibweise versteht. 
Universeller ist es mit Hexnotation: PORTE = 0x01;
Am besten macht man es aber wie in dem von Falk verlinkten Artikel, dann 
werden auch nur die Bits manipuliert, welche im Code stehen und nicht 
alle auf ein mal...
#4211554
Lesenswert?

Ich schrieb:
> Auch zu beachten ist, dass nur der GCC diese Schreibweise versteht.
> Universeller ist es mit Hexnotation: PORTE = 0x01

Wahrscheinlicher ist es daß andere Compiler diese Notation irgendwann 
ebenfalls unterstützen werden als daß ein zukünftiger gcc das irgendwann 
aus heiterem Himmel plötzlich nicht mehr kann. Insofern also ist also 
das nun wirklich des OP's geringstes Problem.

Gegen die binären Zahlenliterale 0b.... ist also überhaupt nichts 
einzuwenden, sie machen manches deutlicher, bzw tragen zur 
Selbstdokumentation des Codes bei, machen die Bedeutung oder das 
Zustandekommen, bzw den angedachten Verwendungszweck einer solchen 
Konstante deutlicher.

Edit: Habe gerade gelesen daß die 0b Integer-Literale im nächsten 
offiziellen C++-Standard offiziell enthalten sein werden, also wird das 
wohl auch die C-Compiler-Hersteller und das C-Sprachkomitee stärker 
motivieren etwas praxisnäher zu denken.
Gast #4211586
Lesenswert?

Hallo Johannes,
Du weisst aber schon, dass vor der Bitausgabe der PortE bzw. die 
entsprechenden Bits des Ports erst über das DDRE auf Ausganggeschaltet 
werden müssen?!

#define MEINTESTBIT_E0 0

DDRE  |= (1<<MEINTESTBIT_E0);  // PortPin als Ausgang
PORTE |= (1<<MEINTESTBIT_E0); // Ausgang auf HIGH setzen
:
PORTE &= ~(1<<MEINTESTBIT_E0); // Ausgang auf LOW setzen
Gast #4211663
Lesenswert?

Hallo,

danke schonmal für eure Hilfe :-)

Ja die Ausgänge sind entsprechend gesetzt als Ausgang, habe allerdings 
dort DDRE=0xFF; geschrieben. Aber das sollte doch kein Problem sein 
oder?

Problem bei meinem vorhaben ist, dass ich eine bereits vorhandene 
Schaltung ansteuere, von der ich nur durch durchpiepsen herausgefunden 
habe wie sie funktioniert (Keine uC vorhanden). Nun bin ich mir halt 
nicht sicher wo wirklich der Fehler liegt.
Gast #4211681
Lesenswert?

Noch eine Frage:

Wenn ich mit "if(!(PINC & 0b10000000))" nach PINC7 abfrage, ist der 
Befehl so ok? Oder müssen dann alle anderen Eingänge zwingend=0 sein?

Der Grund warum ich nicht if ( !(PINC & (1<<PINC7)) schreibe ist 
folgender, ich frage zuerst PINC ab und speicher es in eine uint_8t 
Array Variable. Der eigentliche Befehl sieht dann so aus:

if(!(data[3] & 0b10000000))
Gast #4213080
Lesenswert?

Ich habe kurz nocheinmal eine Frage:

Wenn ich z.b. Schreibe:

uint_8t data;

data=PINC;

und dann abfragen will ob Bit PC7 zum Zeitpunkt beim kopieren in dummy 
gesetzt war, geht das dann folgendermaßen?

if(data & 0b10000000)

Oder habe ich da irgendwo den Denkfehler? Ich vermute an der Stelle 
meinen Fehler, da ich so an die ersten vier Bits rankomme, aber nicht an 
PC4...7

Würde mich über eine Antwort sehr freuen :-)
Gast #4213091
Lesenswert?

Gerald M. schrieb:
> denn PinC7 ist nichts anderes "0b1000000"
Und (1 << PinC7) damit gleich
1
0b10000000000000000000000000000000000000000000000000000000000000000
?
Überleg dir das noch mal...


Johannes schrieb:
> Ich habe kurz nocheinmal eine Frage:
> Wenn ich z.b. Schreibe:
>
> uint_8t data;
> data=PINC;
>
> und dann abfragen will ob Bit PC7 zum Zeitpunkt beim kopieren in dummy
> gesetzt war, geht das dann folgendermaßen?
>
> if(data & 0b10000000)
Ja, ich würde aber die (1 << PINC7) Notation verwenden, da man damit auf 
dem ersten Blick sihet um welches bit es geht und Fehler durch eine 
vergessene 0 vermeidet.
#4213094
Lesenswert?

@Johannes (Gast)

>und dann abfragen will ob Bit PC7 zum Zeitpunkt beim kopieren in dummy
>gesetzt war, geht das dann folgendermaßen?

>if(data & 0b10000000)

Ja.

>Oder habe ich da irgendwo den Denkfehler?

Nein.

>Ich vermute an der Stelle
>meinen Fehler, da ich so an die ersten vier Bits rankomme, aber nicht an
>PC4...7

??
Gast #4213100
Lesenswert?

Ich habe folgenden ISR:
1
ISR (TIMER0_COMP_vect){
2
  
3
  
4
  inv++;
5
  
6
  if (inv==0xFF){PORTB ^= (1<<PB4);} //LED Blinken lassen
7
  
8
  switch (adress)
9
    {
10
      case 0:
11
      data[3]=PINC;
12
      PORTE=0x00;
13
          
14
      break;
15
        
16
      case 1:
17
      data[0]=PINC;
18
      PORTE=0b01;
19
      
20
      break;
21
        
22
      case 2:
23
      data[1]=PINC;
24
      PORTE=0b10;
25
      
26
      break;
27
        
28
      case 3:
29
      data[2]=PINC;
30
      PORTE=0b11;
31
      break;
32
      }
33
  
34
  adress++;
35
  if (adress==4){adress=0;}
36
  
37
    
38
}
Damit will ich in abhängigkeit von PORTE das was an PINC anliegt 
abspeichern.

Später will ich dann auf das Array data darauf mit o.g. Befehl prüfen 
welche Bits gesetzt sind.

Und das funktioniert nur für die Bits 0..3 für 4..7 geht es nicht?

Die Lösung mit dem ISR habe ich gewählt, weil der Zustand von PORTE alle 
x ms geändert werden muss, sonst schaltet ein Watchdog die andere 
angeschlossene Schaltung ab.

data ist global als volatile uint_8t definiert.
Gast #4213148
Lesenswert?

Bernd K. schrieb:

> Edit: Habe gerade gelesen daß die 0b Integer-Literale im nächsten
> offiziellen C++-Standard offiziell enthalten sein werden, also wird das
> wohl auch die C-Compiler-Hersteller und das C-Sprachkomitee stärker
> motivieren etwas praxisnäher zu denken.

Ja, und in villeicht 200 Jahren oder so denken dann vielleicht sogar die 
C-Sprachgewaltigen darüber nach, ob es vielleicht sinnvoll wäre, diesen 
seit mindestens 30 Jahren schon vollkommen nutzlosen Oktalkram 
rückstandsfrei zu entsorgen.

DAS würde nämlich die Kompatibilität zu praktisch ALLEN anderen 
heute relevanten Programmiersprachen massiv erhöhen. Und wer weiß, wie 
die Lage erst in 200 Jahren ist wäre...
Gast #4213230
Lesenswert?

Bernd K. schrieb:
> Ich schrieb:
>> Auch zu beachten ist, dass nur der GCC diese Schreibweise versteht.
>> Universeller ist es mit Hexnotation: PORTE = 0x01
>
> Wahrscheinlicher ist es daß andere Compiler diese Notation irgendwann
> ebenfalls unterstützen werden als daß ein zukünftiger gcc das irgendwann
> aus heiterem Himmel plötzlich nicht mehr kann. Insofern also ist also
> das nun wirklich des OP's geringstes Problem.

Es ist kein Problem solange der GCC benutzt wird (was spätestens wenn 
man sich mal mit ARM beschäftigt hat durchaus nicht immer der Fall sein 
muss), ist nur als Hinweis gedacht.

> Gegen die binären Zahlenliterale 0b.... ist also überhaupt nichts
> einzuwenden, sie machen manches deutlicher, bzw tragen zur
> Selbstdokumentation des Codes bei, machen die Bedeutung oder das
> Zustandekommen, bzw den angedachten Verwendungszweck einer solchen
> Konstante deutlicher.

Doch, Portierbarkeit.

> Edit: Habe gerade gelesen daß die 0b Integer-Literale im nächsten
> offiziellen C++-Standard offiziell enthalten sein werden, also wird das
> wohl auch die C-Compiler-Hersteller und das C-Sprachkomitee stärker
> motivieren etwas praxisnäher zu denken.

Ja, aber das ist aktuell noch Zukunftsmusik.
Gast #4213274
Lesenswert?

Johannes scheint kein Profi zu sein und wer heute mit dem GCC bastelt, 
der braucht sich keine Sorgen zu machen morgen auf einen anderen 
inkompatiblen "Profi"-Compiler wechseln zu müssen.
Und wer keine Binärzahlen versteht, der kommt natürlich auch nicht mit 
Oktalzahlen zurecht. Abschaffen muß man sie deshalb nicht, denn es gibt 
immer noch die Anderen ;-)
Moderator Persönliche Seite #4213294
Lesenswert?

Bernd K. schrieb:
> Edit: Habe gerade gelesen daß die 0b Integer-Literale im nächsten
> offiziellen C++-Standard offiziell enthalten sein werden

Curious: wo hast du das gelesen?

Hintergrund: ich hatte die derzeitige GCC-Implementierung dafür damals
auch und vor allem deshalb durch die Instanzen gedrückt, weil mich der
lapidare Satz im C99-Rationale “A proposal to add binary constants was
rejected due to lack of precedent and insufficient utility.” angepiept
hat und ich wenigstens wollte, dass sie beim nächsten Mal nicht mehr
einen “lack of precedent” konstatieren können … insofern ist es nett,
wenn jetzt zumindest C++ das mal aufgegriffen haben sollte.  Natürlich
war GCC keineswegs der erste Compiler, der das konnte.
#4214361
Lesenswert?

Bastler schrieb:

> wer heute mit dem GCC bastelt,
> der braucht sich keine Sorgen zu machen morgen auf einen anderen
> inkompatiblen "Profi"-Compiler wechseln zu müssen.

Ich schätze mal wenn man alle Maschinenbefehle die in allen Prozessoren 
der ganzen Welt zusammengenommen heute morgen zwischen 00:00:00 und 
00:00:01 UTC irgendwo auf der Welt ausgeführt wurden, wenn man von jedem 
einzelnen aufschreiben würde aus welchem Compiler er irgendwann mal 
rausgefallen ist dann würde man wahrscheinlich feststellen das der 
"Bastelcompiler" doch ganz schön beliebt zu sein scheint. Wer traut sich 
ne Schätzung zu?
Gast #4214568
Lesenswert?

Ok, ich geb's zu, die Ironie hab ich zu gut versteckt.

Es war eigentlich die Antwort auf die Frage, ob man sich auf die GCC 
Erweiterung "Dualzahlkonstante" einlassen kann. Man kann, denn einem 
Hobbyist wird so schnell nichts besseres unterkommen. Nur 
Assemblerhelden sind (vermeintlich) besser.
Ich hab vor 26 Jahren in einer 32-Bit DOS Umgebung zum ersten mal diesen 
Compiler benutzt, hab ihn nicht sofort geliebt, baue ihn aber inzwischen 
für den AVR selbst an und bin begeistert, was man für den Preis bekommt.
Wir stehen also auf der selben Seite ;-)
Gast #4214634
Lesenswert?

Was ist eigentlich der Unterschied zwischen
flag = (1<<BIT7);
und
flag = _BV(BIT7);
bzw. was ist wann richtig eingesetzt?

Weil, zum einen steht im Buch "Mikrocomputertechnik mit Controllern der 
Atmel AVR-RISC-Familie" geschrieben, das die GNU Makros BV, _BV veraltet 
seien, und man lieber die form (1<<XX) verwenden solle, zum anderen ein 
netter Hinweis, aus Kompatbilitätsgründen sollte ich lieber die BV 
Makros benutzen.
Moderator Persönliche Seite #4214651
Lesenswert?

BirgerT schrieb:
> das die GNU Makros BV, _BV veraltet seien

BV gab's wirklich mal, wurde aber vor mehr als 10 Jahren aus dem
Verkehr gezogen, weil er doch recht intrusiv in den application
namespace eingreift.  Als Ersatz wurde dann _BV ins Leben gerufen,
aber ich wüsste nicht, wer ihn warum als „veraltet“ deklariert
hätte. ;-)

Der einzige Grund für die Existenz dieses Makros ist, dass sich
1
REGX = _BV(BITA) | _BV(BITB) | _BV(BITC);

geringfügig besser liest als
1
REGX = (1 << BITA) | (1 << BITB) | (1 << BITC);

Ansonsten ist seine Verwendung Geschmackssache.
Gast #4214669
Lesenswert?

Ich schrieb:
> Doch, Portierbarkeit.

Die Bit-Konstanten hat man, wenn man irgendwann einen kommerziellen 
Proficompiler benutzen muss, in ein paar Minuten mit einer Scriptsprache 
der eigenen Wahl automatisch ersetzt.

Und Code, in dem solches Bitgefrickel oberhalb der untersten 
HW-Abstraktionsschicht, die beim Portieren komplett ausgetauscht wird, 
betrieben wird, ist sowieso nicht ohne größeren Aufwand portierbar.

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