Forum: Mikrocontroller und Digitale Elektronik AVR PORTE ansprechen wie genau?


von Johannes (Gast)


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 :-)

von Falk B. (falk)


Lesenswert?

@Johannes (Gast)

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

Ja.

>Oder muss ich schreiben 0b00000001 ?

Nein. Führende Nullen kann man weglassen.

Besser ist es jedoch, sinnvolle Namen für die Bits zu nutzen, das macht 
die Sache deutlich besser lesbar, siehe Bitmanipulation.

von Ich (Gast)


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...

von Bernd K. (prof7bit)


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.

: Bearbeitet durch User
von BirgerT (Gast)


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

von Johannes (Gast)


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.

von Johannes (Gast)


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))

von Gerald M. (gerald_m17)


Lesenswert?

Du solltest dir mal klar machen was das "&" bedeutet und was "PinC7".
Damit verundest du das Byte vor dem "&" und danach.
Ob du jetzt "& 0b10000000" oder "& (1<< PinC7)" schreibst ist egal, denn 
PinC7 ist nichts anderes "0b1000000"
Steht so in den #defines

von Johannes (Gast)


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 :-)

von -C- (Gast)


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.

von Falk B. (falk)


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

??

von S. Landolt (Gast)


Lesenswert?

> aber nicht an PC4...7
JTAG abgeschaltet?

von Johannes (Gast)


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.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Johannes schrieb:

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

Und nochmal die Frage.

Hast du das JTAG Interface per Fuse abgeschaltet?

Per Default ist es nämlich eingeschaltet. Und es arbeitet auf den Pins 
.... tadaaaaa .... PC4 bis PC7. Was soviel bedeutet wie: du kannst dann 
die Pins nicht selbst benutzen.

: Bearbeitet durch User
von Johannes (Gast)


Lesenswert?

S. Landolt schrieb:
>> aber nicht an PC4...7
> JTAG abgeschaltet?

DANKE!   Das wars :-)

von c-hater (Gast)


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...

von Ich (Gast)


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.

von Bastler (Gast)


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 ;-)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.

: Bearbeitet durch Moderator
von BirgerT (Gast)


Lesenswert?

Bastler schrieb:
> 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 ;-)

Beitrag "Re: Witz der Woche"

von Bernd K. (prof7bit)


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?

von Bastler (Gast)


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 ;-)

von BirgerT (Gast)


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.

von Bastler (Gast)


Lesenswert?

_BV(n) ist das Macro, das (1<<(n)) produziert, d.h. es ist das Gleiche.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.

von Tom (Gast)


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.

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.