Forum: Mikrocontroller und Digitale Elektronik MSP430 Ports definieren


von Patti (Gast)


Lesenswert?

Hallo,
ich habe ein großes Problem beim MSP430 und dem GCC Compiler.
Ich möchte zB. einen Port auswählen und dem Werte zuweisen.
Wenn ich den Port wie folgt definiere:

#define DATA BIT7&P6IN  //Port 6.7 setzen

und später ihm einen Wert zuweise:

DATA=1;

bekomme ich immer diese Fehlermeldung: invalid lvalue in assignment

Hilfe... Wer kann mir da helfen?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Ersetze mal Dein "Macro" durch die Langform und Du wirst (hoffentlich) 
verstehen, warum das so nicht gehen kann:

  BIT7 & P6IN = 1;

Was Du machen willst, ist

  P6IN |= BIT7;   // setzen

bzw.

  P6IN &= ~BIT7;  // löschen

(angenommen, daß "BIT7" den Wert 0x80 enthält)

Die hier sehr beliebte Shiftoperatorschreibweise ließe das ganze so 
aussehen:

  P6IN |= (1 << 7);   // setzen

bzw.

  P6IN &= ~(1 << 7);  // löschen

von Joe (Gast)


Lesenswert?

#define mein_pin P1OUT_bit.P1OUT_7

so gehts beim IAR, dann funktioniert auch "mein_pin = 0" bzw. 
"mein_pin=1".

Ich kenne den GCC für MSP nicht aber ich denke es gibt ne ähnliche 
Lösung.

von Christian R. (supachris)


Lesenswert?

Schon mal versucht zu überlegen, wieso der Compiler sagt, dass er P6_IN_ 
nicht beschreiben kann? ;)







Auflösung:

Das Register is Read-Only, du musst P6OUT benutzen.

von Patti (Gast)


Lesenswert?

@Rufus
kannst du diese shift-Operatoren genauer erklären?

Nochmal zu meinem Problem:
Ich möchte einen PIN des MSP430 als Bidirektionalen Port nutzen, das 
heißt als EIN- und AUS-Gang.
Wie muss ich den deklarieren, dass ich Daten senden und auch einlesen 
kann?

Danke für eure schnellen Antworten :-)

von Jörg S. (Gast)


Lesenswert?

> Wie muss ich den deklarieren, dass ich Daten senden und auch einlesen
> kann?
Das PxDIR Register ständig zwischen Ein- und Ausgang umschalten.


Zu shift:
1 << 7 bedeutet den Wert 1 (00000001) um 7 Bit nach links verschieben. 
Also 10000000

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Du müsstest vor jedem Zugriff die Richtung umschalten.

Mit PxDIR legst Du fest, welche Bits des Ports Ein- und welche Ausgänge 
sind:


  P0DIR = 0xF0;

beispielsweise stellt P0.7 - P0.4 als Aus- und P0.3 bis P0.0 als Eingang 
ein.

Lesezugriffe erfolgen auf PxIN, Schreibzugriffe auf PxOUT.

Das mit den Shiftoperatoren ist nur eine Schreibweise, die manche für 
übersichtlicher halten.

  (1 << 7)

ist numerisch exakt dasselbe wie 0x80.
Die hier verwendete Schreibweise für Bits in einem Register ist die 
Angabe der Bitnummer.

In den Headerdateien, die sich an diese Konvention halten, stehen dann 
so Dinge wie

  #define PORTA_0 0
  #define PORTA_1 1
  #define PORTA_2 2
  #define PORTA_3 3

etc.

Der eigentliche Bitwert wird dann über den Shiftoperator erzeugt:

  PORTA = (1 << PORTA_3);


Achtung

Die in dem mit dem IAR-Compiler für MSP430 ausgelieferten Headerdateien 
verwendete Konvention sieht ANDERS aus, hier werden direkt die 
Bitwerte als Konstanten definiert:

  #define PORTA_0 1
  #define PORTA_1 2
  #define PORTA_2 4
  #define PORTA_3 8

etc.

Gebrauch dann ohne Shiftoperator:

  PORTA = PORTA_3;

von Patti (Gast)


Lesenswert?

Hat jemand von Euch schon Erfahrungen mit dem MSP430 und dem GCC 
Compiler? Irgendwie ist hier alles sehr gewöhnungsbedürftig.

Danke Euch :-)






von Christian R. (supachris)


Lesenswert?

Ich arbeite jeden Tag damit auf Arbeit. Hier gibts ne gute Anleitung:

http://www.mikrocontroller.net/Eclipse%20und%20MSPGCC/

Mit Eclipse geht das wirklich prima.

von Patti (Gast)


Lesenswert?

@superchris
Danke Dir.

Wie würdest du den so etwas umsetzen? Ich möchte einen Takt SCK 
rausschicken und habe eine Dateneleitung DATA. So wie es hier in dem 
Aussschnitt, ist es logisch nachvollziehbar, leider habe ich Probleme 
die Ports zu setzen bzw. den Wert zB. DATA=!ack zu realisieren.
Muss ich denn alles mit Schleifen umschreiben?
wie zB.
if (ack) DATA=1(bzw.Port als Ausgang und on);
else Data=0;

Sorry habe meine Unterlagen gerade nicht zur Hand ;-)


Beispiel:

{
unsigned char i,val=0;
DATA=1;                    //release DATA-line
for (i=0x80;i>0;i/=2)      //shift bit for masking
{ SCK=1;                   //clk for SENSI-BUS
if (DATA) val=(val | i);   //read bit
SCK=0;
}
DATA=!ack;                 //in case of "ack==1" pull down DATA-Line
SCK=1;                     //clk #9 for ack
nop();nop();nop();         //pulswith approx. 5 us
SCK=0;
DATA=1;                    //release DATA-line
return val;
}


von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Na, das könnte -ins Unreine geschrieben- so aussehen:


DATA ist Port1.3
SCK ist Port1.4
1
#define DATA (1 << 3)
2
#define SCK (1 << 4)
3
4
unsigned char meinkrempel(void)
5
{
6
  unsigned char i,val=0;
7
8
  P1OUT |= DATA;           //release DATA-line
9
10
  for (i=0x80;i>0;i/=2)    //shift bit for masking
11
  { 
12
    P1OUT |= SCK;          //clk for SENSI-BUS
13
    if (P1IN & DATA) 
14
      val |= i;            //read bit
15
    P1OUT &= ~SCK;
16
  }
17
  
18
  if (ack)
19
    P1OUT &= ~DATA;        //in case of "ack==1" pull down DATA-Line
20
  P1OUT |= SCK;            //clk #9 for ack
21
22
  nop();nop();nop();       //pulswith approx. 5 us
23
24
  P1OUT &= ~SCK;
25
  P1OUT |= DATA;           //release DATA-line
26
27
  return val;
28
}

Das wird so aber nicht funktionieren, da DATA bidirektional verwendet 
werden soll ... dazu musst Du auch noch die Portrichtung umschalten. Das 
erfolgt mit

  P1DIR |= DATA;  // Ausgang

  P1DIR &= ~DATA; // Eingang


Kann es sein, daß der Code von einem µC mit Open-Collector-Ausgängen 
stammt?

Was ist "ack"?

von Christian S. (aliendrummer)


Lesenswert?

ack = acknowledge  ?!?!

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.