Forum: Mikrocontroller und Digitale Elektronik Anfängerfrage: API für Eingänge/Ausgänge und co ?


von Daniel D. (misterschpock)


Lesenswert?

Hallo Forum,

ich hab einen MSP430G2553 bereits erfolgreich programmiert und kann 
bereits einige LED blinken lassen, wie ich will.
Als nächstes möchte ich ein Eingangssignal einbringen, eine FFT 
implementieren und eventuell über eine PWM die LED von einem Musiksignal 
abhängig leuchten lassen.

Die bisherige Ansteuerung der led hab ich mir aus dem Beispielcode 
geklaut.
Ich kann programmieren (c++ und java) und dank meines Phsyikstudiums 
kann ich auch alle anderen Sachen ganz gut - aber was ich überhaupt 
nicht geregelt kriege, ist die Ansteuerung der Funktionen des µc...

Es muss doch sowas geben wie eine API, die die Infos enthält wie:

"BEFEHL[argument(typ)] Setzt die Spannung von Pin x auf den Wert des 
Arguments"

Also meine Frage ist pinzipiell: Wie kriege ich allgemein Zugriff auf 
die verschiedenen Pins des µc, wie kann ich dort Spannungen einlesen und 
ausgeben? Ich hab da einfach keine richtige Anleitung bisher zu 
gefunden.

Ich hoffe ihr könnt mir helfen :-)


Viele Grüße,
MisterSchpock

: Verschoben durch Admin
von codehamster (Gast)


Lesenswert?

Beim MSP430 nennt sich das gesuchte Dokument User’s Guide

von codehamster (Gast)


Lesenswert?


von Daniel D. (misterschpock)


Lesenswert?

merkwürdig, dass ich über die TI seite noch nicht auf das Dokument 
gestoßen bin! Vielen Dank!!
Gaaanz schön umfangreich.
Ok, ich hätte noch eine Frage: Und zwar mache ich das warten bisher noch 
mit einer leeren Schleife, die ich runterlaufen lasse.
Ich hab so ein 32KHz Quarz als Zähler - den kann ich doch sicher 
irgendwie benutzen, um diese Softwarelösung zu umgehen, oder? Also meine 
Frage ist: Klärt sich das auch in diesem Dokument oder muss ich da noch 
woanders suchen.

von codehamster (Gast)


Lesenswert?

da müsstest du noch etwas forschen.
Es gibt Timers die du für eine Zeitbasis verwenden kannst.

Aber das Thema "Warten" ist in diesem Forum schon diverse male erläutert 
worden, solltest also mit der Suchfunkton auf einen Treffer stossen =)

von Daniel D. (misterschpock)


Lesenswert?

codehamster schrieb:
> da müsstest du noch etwas forschen.
> Es gibt Timers die du für eine Zeitbasis verwenden kannst.
>
> Aber das Thema "Warten" ist in diesem Forum schon diverse male erläutert
> worden, solltest also mit der Suchfunkton auf einen Treffer stossen =)

Also ich habe da jetzt mal alles durchforstet.
Die ersten Lösungen waren genau wie im Beispielcode eine For-Schleife, 
die einfach den Controller eine gewisse Zeit "beschäftigen" soll... Das 
finde ich ist eine grauenhafte Lösung, also habe ich weiter gesucht.
Die zweite Lösung scheint zu sein, den Watchdog-Timer zu missbrauchen - 
fraglich, ob das immer gut ist.

Die für mich beste Lösung ist wohl die eines externen oszillators.
Ich hab jetzt einen 32Khz Oszillator an Xin und Xout gelötet und will 
dadurch die Zeit geben lassen.
Ich stelle mir vor, dass ich dem Controller sagen kann "mach mal Pause" 
und dann ein Signal vom Oszillator kommt, wenn zb eine Sekunde vorbei 
ist ... Nur wer zählt da die Takte mit ist die Frage ...

Bin ich da auf dem richtigen Weg ?

von codehamster (Gast)


Lesenswert?

Wenn du nur warten willst und nix nebenbei gemacht werden soll.
Dann ist das der richtige Weg.

Konfiguriere deinen Timer und nimm deinen Quarz als Source.

danach kannst du in deinem Programm den Timer mit einem Wert befüllen.
Als nächstes warten bis das Timerflag gesetzt wird --> Timer abgelaufen.

von codehamster (Gast)


Lesenswert?

Die Code examples zu deinem Prozessor hast du gesehen?

http://www.ti.com/litv/zip/slac485a

von Daniel D. (misterschpock)


Lesenswert?

codehamster schrieb:
> Die Code examples zu deinem Prozessor hast du gesehen?
>
> http://www.ti.com/litv/zip/slac485a

ich hab mir schon tausend codebeispiele angesehen, aber diese sind für 
mich nicht ausreichend dokumentiert.

 WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  P1DIR |= 0x0C;                            // P1.2 and P1.3 output
  P1SEL |= 0x0C;                            // P1.2 and P1.3 TA1/2 
options
  CCR0 = 512-1;                             // PWM Period
  CCTL1 = OUTMOD_7;                         // CCR1 reset/set
  CCR1 = 384;                               // CCR1 PWM duty cycle
  TACTL = TASSEL_1 + MC_1;                  // ACLK, up mode

  _BIS_SR(LPM3_bits);                       // Enter LPM3

hier zum beispiel ...
Was ist CCR0, was ist CCTL1, was ist CCR1, TACTL und was passiert da ?


ich würd gern n beispielcode fürs einfache warten haben, es soll nichts 
auf irgendwelche pins ausgegeben werden :((

von codehamster (Gast)


Lesenswert?

Das steht im User's Guide

Lies dir mal das ganze Kapitel Timer A durch.

von codehamster (Gast)


Lesenswert?


von Daniel D. (misterschpock)


Lesenswert?

codehamster schrieb:
> http://www.mikrocontroller.net/articles/MSP430_Codebeispiele


void init_TimerA(unsigned int cycles )
{
  TACTL = TASSEL1 + TACLR;              // SMCLK, clear TAR
  CCTL0 = CCIE;                         // CCR0 interrupt enabled
  CCR0 = cycles;
  TACTL |= MC_2;                         // Start Timer_A in continuous 
mode
  _EINT();                              // interrupt enable
}

// Timer A0 interrupt service routine
interrupt (TIMERA0_VECTOR) Timer_A(void)
{
  P1OUT ^= 0x01;                        // Toggle P1.0
  CCR0 += 50000;                        // Add Offset to CCR0
}


das?
Ja, hab ich.
Was genau passiert da?
Also wo fließt die Taktrate des Timers ein, wo wird der timer 
aufgerufen, wo wird ein interrupt geworfen ?

Und gibt es irgendwo auf diesem Planeten eine Übersetzung, was die 
ganzen CCTL, CCR, TACTL etc ausgeschrieben heißen sollen ???

von abc (Gast)


Lesenswert?

Timer zählt 50000 schritte.

danach wird die ISR angesprungen und wieder 50000 schritte werden 
gesetzt.

und das ganze endlos....

von abc (Gast)


Lesenswert?

Stefan Datenschutz schrieb:
> Also wo fließt die Taktrate des Timers ein, wo wird der timer
> aufgerufen, wo wird ein interrupt geworfen ?

SMCLK = Auswahl der Taktquelle
Weitere Infos dazu im Kapitel 5 Basic Clock Module

Der Timer wird nicht aufgerufen. Der wird konfiguriert und dann läuft 
der.
Mit der Funktion void init_TimerA(unsigned int cycles )
wird der Timer aufgestzt.
Wenn die cycles abgelaufen sind wird die HW ein Interrupt setzen.
Daher wird dann automatisch die ISR --> interrupt (TIMERA0_VECTOR) 
Timer_A(void) aufgerufen.
Dort wird nix anderes gemacht als den Timer wieder gestartet.

von Daniel D. (misterschpock)


Lesenswert?

abc schrieb:
> Stefan Datenschutz schrieb:
>> Also wo fließt die Taktrate des Timers ein, wo wird der timer
>> aufgerufen, wo wird ein interrupt geworfen ?
>
> SMCLK = Auswahl der Taktquelle
> Weitere Infos dazu im Kapitel 5 Basic Clock Module
>
> Der Timer wird nicht aufgerufen. Der wird konfiguriert und dann läuft
> der.
> Mit der Funktion void init_TimerA(unsigned int cycles )
> wird der Timer aufgestzt.
> Wenn die cycles abgelaufen sind wird die HW ein Interrupt setzen.
> Daher wird dann automatisch die ISR --> interrupt (TIMERA0_VECTOR)
> Timer_A(void) aufgerufen.
> Dort wird nix anderes gemacht als den Timer wieder gestartet.

Okay, die 50000 schritte wären bei 32768 hz also ca 1,5 sekunden?
Was ist das für eine initialisierung "cycles" ?
Das ist ja auch CCR0 (was auch immer das heißen mag)
Es wird erst ein Wert für CCR0 gesetzt und dann immer 50000 addiert.
Was bedeutet das CCR0=cycles ?

ich hab jetzt folgenden code


int main(void) {
  WDTCTL = WDTPW | WDTHOLD;    // Stop watchdog timer


  TACTL = TASSEL1 + TACLR;              // SMCLK, clear TAR
    CCTL0 = CCIE;                         // CCR0 interrupt enabled
    CCR0 = 32768; // ??????
    TACTL |= MC_2;                         // Start Timer_A in cont.
    _EINT();                              //

  while(1){
  P1DIR = 0x01;   // macht die LED an
    CCR0 += 32768;   // sollte eine Sekunde warten
    P1DIR = 0x00; // macht die LED aus
    CCR0+=32768;  // sollte eine Sekunde warten
  }

  return 0;
}


das macht so aber überhaupt noch keinen sinn und funktioniert 
entsprechend auch nicht.
Die void-methode bringt übrigens immer einen syntax error, daher hab ich 
die mit in die main gepackt.

von Helfer (Gast)


Lesenswert?

Stefan Datenschutz schrieb:
> das macht so aber überhaupt noch keinen sinn und funktioniert
> entsprechend auch nicht

Nicht böse gemeint: Weisst du was ein µC ist und wie er grundlegend 
funkioniert?

von Fabio S. (codehamster)


Lesenswert?

Was du suchst ist hier beschrieben...

http://odolshinu.wordpress.com/2010/11/06/understanding-msp430-timer_a/

trotzdem wirst du mich mit dem User Guide auseinander setzen.
Und nachschlagen müssen was welches Register bedeutet.

Ansonsten wirst du das nie verstehen.

von Daniel D. (misterschpock)


Lesenswert?

Das sieht gut aus.

leider schaff ich es erst jetzt,m weiterzumachen.
Hm ich finds trotzdem schade, dass hier alle Leute nur auf Links 
verweisen.

Kommt mir sehr bekannt aus meinem Studium vor.

Wie auch immer, ich versuche es dann mal weiter.
Mir ist halt nicht klar, welches Register wie für was zuständig ist und 
mit welchem Akronym/Abkürzung/Befehl es programmierbar ist.

von codehamster (Gast)


Lesenswert?

Das ging hier allen so.
Der Einstieg in die Mikrocontroller-Welt besteht meist aus Datenblatt 
bzw. UserGuide zu wälzen.

Ich hoffe du nimmst es mir nicht übel. Aber die UserGuides von TI finde 
ich eigentlich ganz gut. Und wenn du da die wesentlichen Kapitel 
durchgelesen hast weisst du auch welche Register du nutzen musst und was 
sie bedeuten.
Ist alles in den oben erwähnten Kapiteln beschrieben.

von Daniel D. (misterschpock)


Lesenswert?

codehamster schrieb:
> Das ging hier allen so.
> Der Einstieg in die Mikrocontroller-Welt besteht meist aus Datenblatt
> bzw. UserGuide zu wälzen.
>
> Ich hoffe du nimmst es mir nicht übel. Aber die UserGuides von TI finde
> ich eigentlich ganz gut. Und wenn du da die wesentlichen Kapitel
> durchgelesen hast weisst du auch welche Register du nutzen musst und was
> sie bedeuten.
> Ist alles in den oben erwähnten Kapiteln beschrieben.

Ach quatsch übel nehme ich niemandem was, bin ja um jede Hilfe dankbar, 
insbesondere deinen Namen hab ich jetzt schon oft gelesen :-)

Muss mich auch korrigieren, waren auch einige gute direkte Hinweise 
drin. Ich sitze jetzt am Codeschreiben und wusel mich weiter vor, 
mindestens mit 30% trial and error ... aber bis ich meine erste 
Schachengine oder meinen ersten Raytracer geschrieben hatte, verging 
auch eine Weile !!

von Daniel D. (misterschpock)


Lesenswert?

codehamster schrieb:
> Das ging hier allen so.
> Der Einstieg in die Mikrocontroller-Welt besteht meist aus Datenblatt
> bzw. UserGuide zu wälzen.
>
> Ich hoffe du nimmst es mir nicht übel. Aber die UserGuides von TI finde
> ich eigentlich ganz gut. Und wenn du da die wesentlichen Kapitel
> durchgelesen hast weisst du auch welche Register du nutzen musst und was
> sie bedeuten.
> Ist alles in den oben erwähnten Kapiteln beschrieben.

aaaaaaahhhh, jetzt hab ich das verstanden mit den Registern.
Komplett bin ich durch die Syntax zwar noch nicht durchgestiegen (wann 
man | schreibt und wann man eine Zahl zuweißt und warum man zB ID_3 
schreiben muss statt ID=11 oder ID_11 aber mit etwas ausprobieren habe 
ich es geschafft und alles einigermaßen funkionstüchtig hinbekommen.
TACCR0 kann ich jetzt auch prima schreiben und so meinen Puls 
modulieren, hab eine wunderbar gedimmte LED bekommen.

Jetzt hab ich noch die Taylorapproximation vom Sinus implementiert und 
kriege tolle langsam pulsierende Lichter :)

Frag mich aber, ob ich jetzt jede mathematische Funktion erst noch 
implementieren muss oder ob ich einfach sowas wie math.h importieren 
kann ....
eeehm ja, das sollte ich einfach mal ausprobieren haha :-D

von Peter II (Gast)


Lesenswert?

Stefan Datenschutz schrieb:
> wann
> man | schreibt und wann man eine Zahl zuweißt

das hat nicht mit den Register zu tun sondern mit C und dort mit 
Bitmanipulation.

von Daniel D. (misterschpock)


Lesenswert?

okay also das verstehe ich, wenn ich C besser verstehe? Dachte es ist 
µC-Controller-spezifisch, weil ich das so noch nicht gesehen habe :)
Danke für den Hinweis

von Karl H. (kbuchegg)


Lesenswert?

Stefan Datenschutz schrieb:
> okay also das verstehe ich, wenn ich C besser verstehe? Dachte es ist
> µC-Controller-spezifisch, weil ich das so noch nicht gesehen habe :)


Nö. Das ist ganz normales C. Sind ja alles C Standard-Operationen

  |    bitweises OR
  &    bitwiese AND
  ~    bitweise Invertierung


Aber zugegebenermassen sind diese Operatoren ausserhalb der µC Szene 
nicht sehr gebräuchllich. Treiber-Programmierer brauchen sowas noch des 
öfteren, wenn sie Bytes sparen wollen.


Der Link scheint verloren gegangen zu sein. Daher nochmal
Bitmanipulation

von Daniel D. (misterschpock)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Stefan Datenschutz schrieb:
>> okay also das verstehe ich, wenn ich C besser verstehe? Dachte es ist
>> µC-Controller-spezifisch, weil ich das so noch nicht gesehen habe :)
>
>
> Nö. Das ist ganz normales C. Sind ja alles C Standard-Operationen
>
>   |    bitweises OR
>   &    bitwiese AND
>   ~    bitweise Invertierung
>
>
> Aber zugegebenermassen sind diese Operatoren ausserhalb der µC Szene
> nicht sehr gebräuchllich. Treiber-Programmierer brauchen sowas noch des
> öfteren, wenn sie Bytes sparen wollen.
>
>
> Der Link scheint verloren gegangen zu sein. Daher nochmal
> Bitmanipulation
Gut dann weiß ich Bescheid und bin beruhigt, dass es nicht ganz so 
schlimm ist, dass ich das noch nie benutzt habe.
Trotzdem danke!
Ja, der Link ist in der Tat untergegangen, bin aber schon über google 
drauf gestoßen, als ich eben nach Bitmanipulation gesucht habe.
Wenn das Eis erstmal gebrochen ist, macht es tierisch Spaß. Und im 
Nachhinein machen auch die meisten Kommentare hier Sinn ;-)

von codehamster (Gast)


Lesenswert?

schön zu hören!

in die uC Welt einzusteigen ist manchmal etwas schwierig, aber wie du ja 
selbst festgestellt hast, wenns man mal was begriffen hat machts 
plötlich Spass.

ev. suchst du dir mal noch die MSP430G2553.h ,MSP430G25xx.h oder so 
ähnlich auf deinem Rechner und öffnest diese mal.

Da stehn die ganzen Register und anderes drin.
Z.b.
/************************************************************
* STANDARD BITS
************************************************************/

#define BIT0                (0x0001)
#define BIT1                (0x0002)
#define BIT2                (0x0004)
#define BIT3                (0x0008)
#define BIT4                (0x0010)
#define BIT5                (0x0020)
#define BIT6                (0x0040)
#define BIT7                (0x0080)
#define BIT8                (0x0100)
#define BIT9                (0x0200)
#define BITA                (0x0400)
#define BITB                (0x0800)
#define BITC                (0x1000)
#define BITD                (0x2000)
#define BITE                (0x4000)
#define BITF                (0x8000)

Somit wird dann:

REGISTER = BIT0 | BIT7
REGISTER = b00000001 | b10000000
zu
REGISTER = b10000001
und das ist dann das gleiche wie
REGISTER = 0x81

und das ganze in dez

REGISTER = 129

viel Erfolg wünsch ich

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.