Hallo, ich arbeite mit dem Launchpad 430G2 unter CCS 6.2 und suche eine Dokumentation über den zur Verfügung stehenden C - Sprachumfang. Es ist ja eigentlich ein Witz. Ich arbeite schon seit über 10 Jahren mit dieser Umgebung, habe viel Wissen aus dem TI-Beispielcode oder anderen Code entnehmen können. Das reicht ja auch in der Regel. Jetzt bin ich mit einem neuen Projekt zu gange und möchte es doch etwas eleganter Programmieren und es genauer Wissen. MSP430 Optimizing C/C++ Compiler (SLAU132L) sagt eigentlich wenig über die Sprachimplementation, bzw., aus meiner Sicht fehlt dort der Unterbau. Z.B. Kapitel 5.6 Data Types. short, signed short 16 bits unsigned short 16 bits int, signed int 16 bits Dann finde ich in einem Source "uint16_t". Jetzt geht das Rätselraten los. Es handelt sich bestimmt um "unsigned short 16 bits". Aber was bedeutet "_t"? Oh, "uint16_t" kennt der Compiler nicht, aber dafür "unsigned short". Das war nur ein kleines Beispiel. Eine ebenso einfache Frage wäre, wird ein "elseif" oder "else if" unterstützt? Das habe ich noch nicht herausbekommen. Vielleicht habe ich ja irgendeine Doku übersehen. mfg klaus
:
Bearbeitet durch User
Der C-Sprachumfang ist eigentlich relativ konstant, Abweichungen sollten auf ein paar Seiten zusammengefasst sein. else if ist C #elseif auch elseif nicht und ob uint16_t als typedef oder #define, als short oder int ausgeführt ist, wird in einer Header-Datei stehen. Einfach mit der IDE danach suchen. Wenn es nicht vorhanden ist, einfach als z.B. typedef unsigned int uint16_t; anlegen, natürlich in einer Plattform-Header, mit "wenn für diesen Prozessor".
Achim S. schrieb: > Wenn es nicht vorhanden ist, einfach als z.B. typedef unsigned int > uint16_t; anlegen, natürlich in einer Plattform-Header, mit "wenn für > diesen Prozessor". uint16_t sollte auch C sein; aus <stdint.h>
Vielen Dank Achim. Ich möchte noch ein Beispiel anführen, von dem in nicht weiss ob das so üblich ist. Der Konstrukt tut zumindest was er soll.
1 | void WDT_Start(int dauer); |
2 | |
3 | WDT_Start(WDT_MDLY_32); |
4 | WDT_Start(WDT_MDLY_8); |
5 | WDT_Start(WDT_MDLY_0_5); |
6 | WDT_Start(WDT_MDLY_0_064); |
7 | |
8 | void WDT_Start(int dauer) |
9 | {
|
10 | // Bei 1MHz DCO-Clock
|
11 | |
12 | if (dauer == WDT_MDLY_32) |
13 | WDTCTL = WDT_MDLY_32; // WatchDog-Timer 32ms starten (default) |
14 | |
15 | if (dauer == WDT_MDLY_8) |
16 | WDTCTL = WDT_MDLY_8; // " 8ms |
17 | |
18 | if (dauer == WDT_MDLY_0_5) |
19 | WDTCTL = WDT_MDLY_0_5; // " 500µs |
20 | |
21 | if (dauer == WDT_MDLY_0_064) |
22 | WDTCTL = WDT_MDLY_0_064; // " 64µs |
23 | |
24 | IFG1 &= ~WDTIFG; // Interrupt-Flag fuer WatchDog loeschen |
25 | IE1 |= WDTIE; // WatchDog-Interrupt einschalten |
26 | }
|
WDTCTL ist ein 16-Bit Register. Der Funktion WDT_Start übergebe ich ein Typ int, das nach SLAU123L ein signed int wäre. Da man meist nicht die Übersicht hat ob es da zu einem Überlauf kommen könnte, sollte man hier besser mit unsigned int arbeiten. Das "else if" möchte ich dann in der Funktion einsetzen. Es sollen aber nur die vorgegebenen Werte ausgeführt werden. Nimmt man hier eine IF ... ELSE IF ... Kette oder ein IF zu Überprüfung der Gültigkeit und danach eine direkte Zuweisung "WDTCTL = dauer;"? mfg klaus
Torsten R. schrieb: > uint16_t sollte auch C sein; aus <stdint.h> In der Tat. Ich vermute mal das die Verwendung mir selber nicht viel bringt, ausser der kürzeren Schreibweise. mfg klaus
Klaus R. schrieb: > In der Tat. Ich vermute mal das die Verwendung mir selber nicht viel > bringt, ausser der kürzeren Schreibweise. Wenn ein uint16_t auf Deiner Zielplattform definiert ist, dann ist er auch garantiert 16 bit groß. Ein unsigned short kann auf bestimmten Plattformen auch größer sein. Also verwendet man üblicherweise uint16_t, wenn man einen 16 bit großen Typen meint.
Hallo Torsten, ich verstehe. In diesem Fall ist SLAU132L ziemlich konkret. Es werden hier MSP430 C/C++ Data Types beschrieben. Aber wenn ich es mir so recht überlege wäre genau für den Fall das Registerwerte behandelt werden sollen ein uint8_t oder uint16_t konkreter. So berücksichtigt man die verschiedenen Registerlängen besser. Vielen Dank. Klaus
Achim S. schrieb: > else if ist C > #elseif auch > elseif nicht Ja, ja, die Else kann einem schon zu schaffen machen. SCNR
Klaus R. schrieb: > Vielleicht habe ich ja irgendeine Doku übersehen. 5.6 Data Types; Seite 89 http://www.ti.com/lit/ug/slau132m/slau132m.pdf
Der TI-Compiler (oder gcc) hält sich an die entsprechenden C- und C++-Standards. Du kannst die also jede beliebigen Dokumentationen und Tutorials über Standard-C/C++ anschauen. Die TI-Dokumentation beschreibt größtenteils nur die Sachen, die jeder Compiler anders implementieren kann.
Ja genau auf diese Stelle hatte ich mich bezogen. SLAU132M ist etwas aktueller als mein SLAU132L. Für ein Vollprofi der täglich µC programmiert ist diese Art der Doku OK. Aber es nervt schon wenn man erst durch das Syntax-Highlighting erfährt, dass etwas geht oder nicht. Die Hilfe schweigt. mfg klaus
Clemens L. schrieb: > Der TI-Compiler (oder gcc) hält sich an die entsprechenden C- und > C++-Standards. Ich werde mich fügen.
Du arbeitest seit 10 Jahren (!) mit einem Mikrocontroller und hast die Grundlagen der Programmiersprache C noch nicht erlernt? Du bist aber nicht von berufswegen ein Entwickler oder? Hab ich da was falsch verstanden? Gruß Dennis
Klaus R. schrieb: > Nimmt man hier eine IF ... ELSE IF ... Kette oder ein IF zu > Überprüfung der Gültigkeit und danach eine direkte Zuweisung "WDTCTL = > dauer;"? Weder noch. Hier nimmt man switch/case. Gerne in Kurzschreibweise:
1 | void WDT_Start(int dauer) |
2 | {
|
3 | switch(dauer) |
4 | {
|
5 | case WDT_MDLY_32: |
6 | case WDT_MDLY_8: |
7 | case WDT_MDLY_0_5: |
8 | case WDT_MDLY_0_064: WDTCTL = dauer; |
9 | break; |
10 | default: .... ja wass denn? |
11 | break; |
12 | }
|
13 | ...
|
14 | }
|
Man will das hier aber garnicht. WDT_Start ist zu "fragil". Der Code bei default offenbart es. Hier nimmt man:
1 | void WDT_Start(int dauer) |
2 | {
|
3 | if (dauer > WDT_MDLY_8) {WDTCTL = WDT_MDLY_32;} |
4 | else if (dauer > WDT_MDLY_0_5) {WDTCTL = WDT_MDLY_8;} |
5 | else if (dauer > WDT_MDLY_0_064) {WDTCTL = WDT_MDLY_0_5;} |
6 | else {WDTCTL = WDT_MDLY_0_064;} |
7 | ...
|
8 | }
|
Dennis S. schrieb: > Du arbeitest seit 10 Jahren (!) mit einem Mikrocontroller und hast > die Grundlagen der Programmiersprache C noch nicht erlernt? Von beruflich war ich auch schon einmal Programmierer. C spielte damals aber keine grosse Rolle. Ich denke schon das eine C Anwendungsprogrammierung sich von einer C µC Programmierung etwas unterscheidet. Wie gesagt, die Samples von TI sind oft trivial. Aber vielfach genügt das ja auch. Mit den Grundlagen der Programmiersprache C nach K&R komme ich schon zurecht. Das µC Umfeld unter rudimentärem C mit seinen nicht typisierten Werten ist schon ein Stolperstein. Unter Visual Studio mit C# fühl ich mich da wohler. Aber was soll es, da muss man durch. mfg klaus
Achim S. schrieb: > Man will das hier aber garnicht. WDT_Start ist zu "fragil". Das switch in der Tat übersichtlicher als eine If ... Else If Kette. Achim S. schrieb: > WDT_Start ist zu "fragil". Eigentlich haben die Defines ja einen festen Wert. Der Programmierer sollte da schon wissen welche Dauer er auswählt. In der Anwendungsprogrammierung programmiere ich gerne so strikt, werfe dann aber im Fehlerfall auch eine Meldung heraus. Beim µC ist man da etwas beengt. Achim S. schrieb: > Der Code bei default offenbart es. Da kann man ja wieder den Defaultwert nehmen. Vielen Dank für Deine Unterstützung. mfg klaus
Zu dem MSP430 kann ich dir das buch von Josh Davies empfehlen: MSP430 Microcontroller Basics Ich habe sowohl mit MSP's als auch mit STM32 gearbeitet, meiner Meinung nach, gibt es keine Gründe einen MSP dem STM32 vorzuziehen :)
Klaus R. schrieb: > Mit den Grundlagen der Programmiersprache C nach K&R komme ich schon > zurecht. Das µC Umfeld unter rudimentärem C mit seinen nicht typisierten > Werten ist schon ein Stolperstein. Also wenn ich mit die Beschreibung zu dem Compiler so anschaue steht da: MSP430 Optimizing C/C++ Compiler v15.9.0.STS User's Guide ... The compiler accepts C and C++ code conforming to the International Organization for Standardization (ISO) standards for these languages. The compiler supports both the 1989 and 1999 versions of the C language and the 2003 version of the C++ language. Somit ist das ein ganz normaler Normgerechter C99 Compiler und nichts rudimentäres. https://de.wikipedia.org/wiki/Varianten_der_Programmiersprache_C#C99 http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf
♪Geist schrieb: > Zu dem MSP430 kann ich dir das buch von Josh Davies empfehlen: MSP430 > Microcontroller Basics Danke, nicht schlecht! Eine schöne Zusammenfassung des Stoffs. mfg klaus
Irgendwer schrieb: > http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf Nach so etwas hatte ich auch gesucht. Prima, Klaus.
Irgendwer schrieb: > Somit ist das ein ganz normaler Normgerechter C99 Compiler und nichts > rudimentäres. Na ja, vielleicht liegt es ja nicht direkt am Compiler. Ich wollte im Debugmode Consolausgaben mit printf() machen können. Unter dem IAR wird dies vom IAR mit unterstützt. Hier unter CCS gibt es nur Fehlermeldungen, obwohl ich die Konfiguration entsprechend angepasst habe. Beim MSP430G2553 habe ich zwar 16KB Flash, die unter CCS auch zur Verfügung stehen, aber nur 512 Byte RAM. Und printf() braucht wohl mehr RAM. Ich weiss zwar, man kann sich da etwas selber basteln, aber zur Zeit ist der Leidensdruck noch nicht so hoch und schaue ggf. in die Register. mfg klaus
Klaus R. schrieb: > Hier unter CCS gibt es nur Fehlermeldungen ... welche denn? > nur 512 Byte RAM. Und printf() braucht wohl mehr RAM. ganz sicher nicht. Zumal es für ganz kleine Plattformen z.B. versionen ohne Float gibt. Das Problem ist eher: Wohin soll printf schreiben? Auf den Bildschirm? Selbst wenn Du einen hast, weiss der Compiler nicht, welchen. Auf die serielle Schnittstelle? Mit welcher Baudrate? Wenn printf unter IAR "einfach so" funktioniert, ist das für den Einstieg vielleicht ganz schön, aber irgendwann fliegt Dir dieses "einfach so" um die Ohren. printf rotzt einfach jedes Zeichen mit putchar(int c) raus. Damit Dein Problem "nur" noch, ein Zeichen rauszusenden. Setze einen Uart auf, schreibe in putchar das niederwertige Byte in den Uart-Transmit und warte bis das Zeichen versendet ist.
Achim S. schrieb: > > printf rotzt einfach jedes Zeichen mit putchar(int c) raus. Damit Dein > Problem "nur" noch, ein Zeichen rauszusenden. Setze einen Uart auf, > schreibe in putchar das niederwertige Byte in den Uart-Transmit und > warte bis das Zeichen versendet ist. So weit komme ich gar nicht. Beim Build gibt es folgende Fehlermeldung. "./lnk.cmd", line 48: error #10099-D: program will not fit into available memory. placement with alignment fails for section ".text" size 0x2b12 . Available memory ranges: FLASH size: 0x1000 unused: 0xe56 max hole: 0xe56 mfg klaus
Du hast den Optimizer aber schon eingeschaltet, oder? Woher kommt deine printf-Implementierung, also was ist das für eine C-Bibliothek, die du da hast?
Hallo, ich arbeite mit CCS6.2. Die Funktion printf() ist dort unter STDIO.H v15.12.3 defaultmässig eingebunden. Die MSP430 Compiler Optimization habe ich nicht verändert und steht wohl per default auf Optimization level "0 - Register Optimization". Das hier etwas zu ändern wäre habe ich gelesen, meine ich. Kennst Du den CCS? mfg klaus
Klaus R. schrieb: > Die Funktion printf() ist dort unter STDIO.H v15.12.3 defaultmässig > eingebunden. Das ist aber nicht alles. Entscheidend ist, welche Variante von printf() verwendet wird. Und das entscheidet nicht die verwendete Headerdatei (die enthält nur den Prototypen), sondern die verwendete Library. Üblich ist, daß es unterschiedlich umfangreiche printf-Varianten gibt; wird auf float-Unterstützung verzichtet, wird das schon deutlich weniger umfangreich. Sieh mal hier: http://processors.wiki.ti.com/index.php/Printf_support_in_compiler Da wird die Kommandozeilenoption --printf_support beschrieben, die just das macht.
Ich habe mit MSP430 noch nie zu tun gehabt, daher kann ich dir nur empfehlen, die Optimierung einzuschalten oder im Zweifelsfall eine eigene printf-Implementation zu benutzen.
Rufus Τ. F. schrieb: > Üblich ist, daß es unterschiedlich umfangreiche printf-Varianten gibt; > wird auf float-Unterstützung verzichtet, wird das schon deutlich weniger > umfangreich. Der Knackpunkt ist wohl die Grösse des RAMs mit 512 Byte. Unter CCS stehen ja immerhin 16K Flash zur Verfügung. ....I'm haven't used an MSP430 device yet, but according to the specs for the Launch Pad MSP430G2 the largest processor that comes with it only has 16KB Flash and 512 bytes of RAM. This is pretty small (especially RAM) for a full implementation of printf. For "Hello, world", all you need to do is configure the UART and copy characters to it one by one, so you don't need the many number formatting options provided by printf.... OK. Ich muss mal grundsätzlich Fragen. Im Prinzip geht es um das Debuggen. Es würde so etwas wie ein debug.print genügen. Also einfach eine Ausgabe in das Debug-Consolenfenster. Gibt es etwas anderes als printf()? mfg klaus
Schau dir erstmal an, was das minimale printf vom CCS anbietet (das kann nur char, int und string und sollte hinreichend klein sein). Ansonsten musst du dich einfach mal mit der C Standardlibrary befassen (z.B. puts) oder deine Ausgabe selbst bauen.
Klaus R. schrieb: > Der Knackpunkt ist wohl die Grösse des RAMs mit 512 Byte. Unter CCS > stehen ja immerhin 16K Flash zur Verfügung. Klaus R. schrieb: > So weit komme ich gar nicht. Beim Build gibt es folgende Fehlermeldung. > > "./lnk.cmd", line 48: error #10099-D: program will not fit into > available memory. placement with alignment fails for section ".text" > size 0x2b12 . > Available memory ranges: > FLASH size: 0x1000 unused: 0xe56 max hole: 0xe56 .text gehört ins Flash, nicht ins RAM. Dein Programm ist 11026 Byte (0x2b12) groß, aber für den Compiler/Linker sind nur 4K (0x1000) Bytes vorhanden.
Hallo, printf mit dem MSP2553 im CCS geht definitiv nicht, selbst in der kleinsten Ausführung und ohne float. Wenn man mal in die Header files vom Compiler schaut wird dort eine BUFFSIZE von 256 Bytes definiert, das braucht der 2x nämlich für Input und Output, damit wäre der gesamte RAM belegt... Es gibt da durchaus selbstgestrickte Lösungen, wie man eine Debugausgage im Konsolenfenster machen kann, braucht man aber in der Regel nicht, da es sich ja hier um einen echten Debugger handelt, warum soll man also ein printf ins Programm nur für's debuggen reinschreiben, wenn man stattdessen einfach nur einen Breakpoint setzen kann und sich dann in aller Ruhe sämtliche Variablenwerte und Registerwerte im Debugger anschauen kann. Gruß wv
wv schrieb: > warum soll man also > ein printf ins Programm nur für's debuggen reinschreiben, ... und wenn man was in der Art will, dann kann man ein "blink, blink", mit einer Led einbauen.
genau schrieb: >> Man will das hier aber garnicht. > > warum nicht? Weil Code (trotz assert) immer funktionieren soll (und Compile-Zeit-Assert ist in dieser Funktion nicht möglich). Es gibt für Makros wie WDT_MDLY_32 ... WDT_MDLY_0_064 3 mögliche Implementierungen: a) fortlaufende enums von z.B. [4,5,6,7]. In dem Fall reicht eine Bereichsprüfung b) willkürlich verteilte special values, z.b. [17,11,39,117]. In dem Fall brauche ich den Vollvergleich (mit switch/case). c) "passende" Teiler, z.B. [2,4,8,16]. Der Watchdog solte aber auch mit falschem Wert sinnvoll gesetzt werden (+assert). Für die 3 Beispiele oben: a) 4 wenn <4, 7 wenn >7 b) längste WDT-Zeit c) der nächst-längere Wert bzw. der längste. Notfalls mit Compiletime-Asserts die Annahmen über die Makros sicherstellen. asserts sind nicht zuverlässig, weil nicht immer debuggt wird. Compiletime-Asserts dageben sind (auch in C) sicher.
Leo C. schrieb: > Klaus R. schrieb: >> Der Knackpunkt ist wohl die Grösse des RAMs mit 512 Byte. Unter CCS >> stehen ja immerhin 16K Flash zur Verfügung. > > Klaus R. schrieb: >> So weit komme ich gar nicht. Beim Build gibt es folgende Fehlermeldung. >> >> "./lnk.cmd", line 48: error #10099-D: program will not fit into >> available memory. placement with alignment fails for section ".text" >> size 0x2b12 . >> Available memory ranges: >> FLASH size: 0x1000 unused: 0xe56 max hole: 0xe56 > > .text gehört ins Flash, nicht ins RAM. > Dein Programm ist 11026 Byte (0x2b12) groß, aber für den Compiler/Linker > sind nur 4K (0x1000) Bytes vorhanden. Das verstehe ich nicht. Es handelt sich um ein MSP430G2553. Der hat 16K Flash und 512 Byte RAM. Unter CCS werden auch alle 16K Flash zur Verfügung gestellt. Der IAR würde Flash auf 8K begrenzen. Das Programm ohne printf() hat folgende Memory Allocation: PERIPHERALS_8BIT 240 PERIPHERALS_16BIT 256 RAM 82 (16%) 512 FLASH 732 ( 4%) 16.350 mfg klaus
Klaus R. schrieb: > Das verstehe ich nicht. Es handelt sich um ein MSP430G2553. Weiß das auch der Compiler? Irgendwo in den Projekteinstellungen wirst Du festlegen müssen, welchen Controller Du verwendest - das hast Du getan?
Ich verwende vorzugsweise sprintf(). Dann kann man die Puffergröße bequem selber festlegen. Und auch, wohin dieser Puffer ausgegeben werden soll.
wv schrieb: > Hallo, > > printf mit dem MSP2553 im CCS geht definitiv nicht, selbst in der > kleinsten Ausführung und ohne float. Wenn man mal in die Header files > vom Compiler schaut wird dort eine BUFFSIZE von 256 Bytes definiert, das > braucht der 2x nämlich für Input und Output, damit wäre der gesamte RAM > belegt... > Das glaube ich inzwischen auch. Die Hello-printf, die man so findet, waren in einem Fall definitiv unter dem IAR gelaufen. Ich habe da zwar gute eine Lösung mittels UART gefunden, die schreibt aber nicht ins Debugfenster. http://www.bralug.de/wiki/Tux_trifft_MSP430-Launchpad#Serielle_Schnittstelle_.28Uart.29 Es spricht noch etwas gegen die UART-Lösung. Das Lauchpad nutze ich nur zum Test gewisser Funktionen. Die eigentliche Entwicklung läuft auf einer anderen Platine die für Steuerungszwecke dient. Das eZ430 Debugging Interface habe ich vierpolig ausgeführt, P1.1 und P1.2 nicht angeschlossen. > Es gibt da durchaus selbstgestrickte Lösungen, wie man eine Debugausgage > im Konsolenfenster machen kann, braucht man aber in der Regel nicht, da > es sich ja hier um einen echten Debugger handelt, warum soll man also > ein printf ins Programm nur für's debuggen reinschreiben, wenn man > stattdessen einfach nur einen Breakpoint setzen kann und sich dann in > aller Ruhe sämtliche Variablenwerte und Registerwerte im Debugger > anschauen kann. Ich denke auch das ich auf die Debugausgabe im Konsolenfenster verzichten kann und mir die Register anschaue, wie bisher. klaus
:
Bearbeitet durch User
Peter D. schrieb: > sprintf() Also sprintf() kann ich zumindest so "nackt" einbinden. Es wird ohne Fehler compiliert und gelinkt. Memory Allocation: PERIPHERALS_8BIT 240 PERIPHERALS_16BIT 256 RAM 82 (16%) 512 FLASH 1.722 (10%) 16.350 Peter D. schrieb: > Dann kann man die Puffergröße > bequem selber festlegen. Und auch, wohin dieser Puffer ausgegeben werden > soll. Kannst Du mir ein Beispiel geben? mfg klaus
Achim S. schrieb: > Es gibt für Makros wie WDT_MDLY_32 ... WDT_MDLY_0_064 3 mögliche > Implementierungen: > > a) fortlaufende enums von z.B. [4,5,6,7]. In dem Fall reicht eine > Bereichsprüfung > b) willkürlich verteilte special values, z.b. [17,11,39,117]. In dem > Fall brauche ich den Vollvergleich (mit switch/case). > c) "passende" Teiler, z.B. [2,4,8,16]. > > Der Watchdog solte aber auch mit falschem Wert sinnvoll gesetzt werden > (+assert). Für die 3 Beispiele oben: > a) 4 wenn <4, 7 wenn >7 > b) längste WDT-Zeit > c) der nächst-längere Wert bzw. der längste. Ich stimme Dir da zu und bin in diesem Fall beim Vollvergleich geblieben. Die Laufzeit wird letztlich dadurch nur unwesentlich verändert. In einem anderen Fall mag eine andere Variante angebrachter sein. mfg klaus
F. F. schrieb: > wv schrieb: >> warum soll man also >> ein printf ins Programm nur für's debuggen reinschreiben, > > ... und wenn man was in der Art will, dann kann man ein "blink, blink", > mit einer Led einbauen. Ja, das ist nicht lächerlich. Ich musste gestern feststellen, dass ich durch das Ausschalten eines Netzteils den Debugger ins Nirwana schicke. Das trat anfangs nicht auf. Deswegen muss ich die Schaltung mal ohne SBW laufen lassen und brauche eine blinkende LED an einem Signalausgang. mfg klaus
Achim S. schrieb: > Der Watchdog solte aber auch mit falschem Wert sinnvoll gesetzt werden Blödsinn, wenn an der Stelle schon ein falscher Wert steht, was für'n Schrott ist dann der Rest? Einzig sinnvoll ist der genaue Vergleich (z. B. switch case) und einer Fehlerbehandlung bei default. Denn du weißt nicht, ob der Parameter erst zur Laufzeit gebildet wird. Die Funktion bleibt so universell.
Hallo, ich habe noch eine spezielle Frage zu Timer. Auf Seite 21 geht es um "32 bit counter extension". http://www.ece.utep.edu/courses/web3376/Notes_files/ee3376-timer.ppt.pdf Beim MSP430G2552 haben wir einen 16-Bit Counter. In der verlinkten Doku wird der Counter auf 32-Bit erweitert. Geht das mit allen MSP430? Und, wie macht man das? Trotz intensiver Suche konnte ich nichts finden. mfg Klaus
Klaus R. schrieb: > Trotz intensiver Suche konnte ich nichts finden. So, wie auf Seite 21 Deines Dokuments beschrieben. Du musst im Timeroverflowinterrupt Dich selbst um die oberen 16 Bit kümmern:
1 | Set overflow interrupt service routine to increment |
2 | a global variable - 16 bit TAR_extended - which |
3 | represents the upper 16 bits of a 32 bit word. |
Das Konzept ist mit jedem µC umsetzbar, der einen Timeroverflowinterrupt kennt.
Hallo Rufus, vielen Dank für den Hinweis. Jetzt habe ich reichlich Quellen gefunden. Timermodi, anschaulich dargestellt. http://www.crash-bang.com/getting-started-msp430-timers-2/ Timeroverflowinterrupt, übersichtlicher Source https://gist.github.com/wmercer/4745806 mfg klaus
Na ja, da finde ich die Ausführungen im Family User Guide besser. Hast du daüberhaupt schon einmal rein geguckt?
genau schrieb: > Na ja, da finde ich die Ausführungen im Family User Guide besser. > Hast du daüberhaupt schon einmal rein geguckt? Ja sicher. Aber es sind oftmals eben Kleinigkeiten die den Sachverhalt transparenter machen. Timermodi, anschaulich dargestellt. http://www.crash-bang.com/getting-started-msp430-timers-2/ Im Family-Guide wird der Up/Down Mode unter 12.2.3.5 vorgestellt. Grafik 12-7 gibt den Funktionsablauf wieder. Alles korrekt. Im Link haben wir diesen Verlauf zum Ende der Seite. Eigentlich wird das selbe dargestellt, nur etwas farbig. Aber CCR0 wird bei TI knapp unterhalb von 0FFFFh platziert, im farbigen Beispiel etwas über dem ersten Drittel, also deutlich abgesetzt. Zudem wird blass der Verlauf des Continuous Mode zum Vergleich angedeutet. Die Stellen für Interrupt Flags werden übersichtlich einmal aufgezeigt. Ich finde dies didaktisch gut aufbereitet. mfg klaus
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.