Moin, ich bin Schüler und arbeite momentan im Rahmen des Informatik-Unterrichtes mit dem MSP430 F5529. Mit anderen Worten: ich bin blutiger Anfänger, also bitte Geduld aufbringen! Folgende Problemstellung: Erstellen eines Wobbelgenerators mit variabler Frequenz sowie variabler Pulsbreite (beides in Grenzen) Also zwei unterschiedliche Betriebsarten in C programmieren. Frequenz-Wobbel (100Hz …. 2kHz) und dann Pulsbreite-Wobble bei einer festen Frequenz. mit einer Pulsbreite von ca. 2% …. Ca. 98% (in etwa). Als kleine optionale Erweiterung: die oben genannten Funtionen mit einem Poti realisieren (was könnte in diesem Zusammenhang der Begriff ADC bedeuten? AD-Wandler? was hat das jz mit dem Poti und dem Programmieren zu tun?) Was mir bekannt ist: Funktionsweise des Timers im Up-Mode, weitere Funktionen des MSP kann ich mir anlesen. Grundsetzlich kann ich alles wissen, was im UserGuide von dem Gerät steht respektive könnt ihr bei euren Ausführungen voraussetzen. Woran es mangelt: Habe so ziemlich null Erfahrung mit programmieren, C soll ja nicht unbedingt einfach sein. (Aber bitte jetzt nicht stumpf Link zum nächstbesten Tutorial schicken) Mir wäre mit Beispielprogrammen, die ein sehr ähnliches Thema behandeln, am meisten geholfen. (Oder gibt es schon Programme in C für einen Wobbel-generator ?) Meine ersten Schritte wären: -Mit der Funktionsweise eines Wobbelgenerators vertraut machzen (überhaupt notwenig??? Wenn ja, was muss man zum Programmieren wissen?) -PAP erstellen für beide Varianten (Wie würdet ihr das angehen?) -Programm erstellen -später dann: Messungen mit dem Oszi durchführen -Anregungen von euch, was man noch so anstellen kann? Hat vielleicht sogar jmd Zeit, mein Projekt langfristig zu begleiten (mit hilfreichen Tipps und Tricks). Sollte ich mal millionen verdienen, würde ich mich entsprechend kenntlich zeigen =) Freue mich über jede noch so kleine Antwort. Schoneinmal vielen Dank dafür. Grüße Antonow
Oha, ein F5529 ist ein nicht ganz so häufig vorkommendes Exemplar eines MSP430 und dir wurde ein Launchpad zur Lösung deiner Aufgabe zur Verfügung gestellt. Leider habe ich einen so großen MSP nicht, aber ich kann dir ein paar kleine Antworten geben: Antonowan225 schrieb: > (was könnte in diesem Zusammenhang der Begriff ADC > bedeuten? AD-Wandler? ADC steht für: Analog-Digital-Converter und ist tatsächlich der Wanalog-Digital-Wandler. Antonowan225 schrieb: > was hat das jz mit dem Poti und dem Programmieren > zu tun?) Mit dem Poti soll wohl ein Spannungteiler aufgebaut werden und somit wird eine Spannung verfügbar, die eben der Einstellung des Potenziometers entspricht. Mittels des ADC kannst du diese Spannung einlesen und hast somit eine Abfrage, wie der Poti "eingestellt ist". Mittels dieses eingelesenen Wertes kannst du die PWM-Register (Pulsweitermodulation) des Controllers beschreibe der seinerseits eben wieder den Tastgrad (Pulszeit zu Gesamtzeit) einstellt... oder du beschreibst damit ein Timerregister und stellst damit die Frequenz bspw. ebenfalls über PWM bei 50% Tastgrad ein. Prinzipiell sollte das relativ einfach gehen, aber in Ermangelung eines solchigen Chips kann ich dir kein Programmbeispiel geben. Welche Toolchain (Grundsätzliche Software bestehend aus Compiler, Linker und Uploadsoftware) steht dir hierfür zur Verfügung?
Ralph S. schrieb: > elche Toolchain (Grundsätzliche Software bestehend aus Compiler, Linker > und Uploadsoftware) steht dir hierfür zur Verfügung? Hey Ralph, ich bin mir nicht ganz sicher, was du damit meinst. Ich arbeite mit IAR Embedded Workbench. LG
Antonowan225 schrieb: > Erstellen eines Wobbelgenerators mit variabler Frequenz sowie variabler > Pulsbreite (beides in Grenzen) Bei "Wobbel" denke ich an Sinus-Schwingungen, aber ich vermute mal, du sollst ein Digitalsignal ausgeben? > Grundsetzlich kann ich alles wissen, was im UserGuide > von dem Gerät steht Für PWM-Signale siehe Abschnitt 17.2.5.1.1. > Also zwei unterschiedliche Betriebsarten in C programmieren. > Frequenz-Wobbel (100Hz …. 2kHz) und dann Pulsbreite-Wobble bei einer > festen Frequenz. mit einer Pulsbreite von ca. 2% …. Ca. 98% (in etwa). Also brauchst du noch einen Timer, der CCR0 bzw. CCRn regelmäßig ändert. (Oder ohne Timer mit __delay_cycles() order so, aber das ist nicht so genau.) > Mir wäre mit Beispielprogrammen, die ein > sehr ähnliches Thema behandeln, am meisten geholfen. MSP430F55xx_Code_Examples\C\MSP430F55xx_ta1_16.c MSP430F55xx_Code_Examples\C\MSP430F55xx_adc_07.c > -PAP erstellen für beide Varianten (Wie würdet ihr das angehen?) Ein PAP ist hilfreich, um einen Algorithmus zu dokumentieren. Wenn du den Algorithmus noch nicht kennst, dann ist die Erstellung eines PAPs eher der letzte Schritt.
Clemens L. schrieb: > Bei "Wobbel" denke ich an Sinus-Schwingungen, aber ich vermute mal, du > sollst ein Digitalsignal ausgeben? Wo wäre der Unterschied hinsichlich Programm? Clemens L. schrieb: > Für PWM-Signale siehe Abschnitt 17.2.5.1.1. Vielen Dank für den Hinweis! Clemens L. schrieb: > Also brauchst du noch einen Timer, der CCR0 bzw. CCRn regelmäßig ändert. > (Oder ohne Timer mit __delay_cycles() order so, aber das ist nicht so > genau.) Noch einen Timer? meinst du Timer B ? Clemens L. schrieb: > MSP430F55xx_Code_Examples\C\MSP430F55xx_ta1_16.c > MSP430F55xx_Code_Examples\C\MSP430F55xx_adc_07.c https://github.com/noccy80/mspdev/tree/master/reference/MSP430ware/examples/devices/5xx_6xx/MSP430F55xx%20Code%20Examples/C Kann ich mir die Sachen hier ziehen? Clemens L. schrieb: > Ein PAP ist hilfreich, um einen Algorithmus zu dokumentieren. Wenn du > den Algorithmus noch nicht kennst, dann ist die Erstellung eines PAPs > eher der letzte Schritt. uns wurde das im unterrricht so vermittelt, dass der PAP als erste, spontane Idee zu Blatt gebracht wird (als Grundgedanke/ grobe Struktur) und das Programm das daraus re4sultierende Endergebnis ist. VLLT MAL AN ANDERE: wozu nutzt ihr einen PAP? Vor dem eigentlichen Programm sinnvoll? Vielen lieben Dank Clemens
Antonowan225 schrieb: > Clemens L. schrieb: >> Ein PAP ist hilfreich, um einen Algorithmus zu dokumentieren. Wenn du >> den Algorithmus noch nicht kennst, dann ist die Erstellung eines PAPs >> eher der letzte Schritt. Das trifft wohl auch für Anfänger zu. In deinem Fall würde ich auf die Examples aufsetzen um als erstes einen lauffähigen Code zu haben. Nachdem Du ihn verstanden hast würde ich ihn im nächsten Schritt um eine weitere Anforderung erweitern. So gehst Du Schritt für Schritt voran. Irgendwann wird man dann die Struktur womöglich verbessern. Auf jeden Fall ist es wichtig zuerst mit dem ADC und dann mit dem Timer klar zu kommen. Ein PAP ist eigentlich in erster Linie bei komplexeren Zusammenhängen hilfreich, um möglichst alle Entscheidungsvarianten erkennen zu können, bzw. um nicht wichtige Varianten zu übersehen. Zur Doku ist ein PAP auch nicht schlecht, gute Kommentare im Source genügen eigentlich auch. mfg Klaus
Klaus R. schrieb: > Fall ist es wichtig zuerst mit dem ADC und dann mit dem Timer klar zu Danke für deine Meinung. Warum ist das so wichtig? Denn die mir vorliegende Aufgabenstellung verlangt es umgekehrt...
Antonowan225 schrieb: > Clemens L. schrieb: >> Bei "Wobbel" denke ich an Sinus-Schwingungen, aber ich vermute mal, du >> sollst ein Digitalsignal ausgeben? > > Wo wäre der Unterschied hinsichlich Programm? Der MSP hat keinen eingebauten DAC; der Unterschied ist, ob es überhaupt geht. :) > Noch einen Timer? meinst du Timer B ? Du hast 3x Timer_A und 1x Timer_B, mit insgesamt 18 CC-Registern. > Kann ich mir die Sachen hier ziehen? Die offizielle Quelle ist http://www.ti.com/product/MSP430F5529/toolssoftware#softTools > uns wurde das im unterrricht so vermittelt, dass der PAP als erste, > spontane Idee zu Blatt gebracht wird (als Grundgedanke/ grobe Struktur) > und das Programm das daraus re4sultierende Endergebnis ist. In der Praxis sind die Datenstrukturen und ihre Beziehungen meist viel wichtiger als der Code. Aber bei so einem kleinen Mikrocontroller-Programm hast du nicht viele Daten. Wenn dein Lehrer Kästchen und Pfeile sehen will, dann könntest du auch die Hardware-Module (ADC, CPU, Timer, Digital I/O) und ihre Zusammenarbeit darstellen. > Klaus R. schrieb: >> zuerst mit dem ADC und dann mit dem Timer > > Warum ist das so wichtig? Ist es nicht. Und der Timer-Ausgang lässt sich leichter beobachten ...
Clemens L. schrieb: > Wenn dein Lehrer Kästchen und Pfeile sehen will, dann könntest du auch > die Hardware-Module (ADC, CPU, Timer, Digital I/O) und ihre > Zusammenarbeit darstellen. Wie würde das denn zum Beispiel für einen Wobbel-generator aussehen?
Antonowan225 schrieb: > Wie würde das denn zum Beispiel für einen Wobbel-generator aussehen? Deine Hausaufgaben darfst du selber machen. :) Ganz grob so.
Erstmal das Lastenheft komplett befüllen, bevor hier Fragen beantwortet werden, die nie gestellt wurden: Welche Auflösung soll der Frequenz-Wobbel haben? Nur 1 Poti? oder 1 für die Frequenz und 1 für das PWM? Kurvenform Wobbelgenerator: Rechteck/Sinus/Sägezahn?
Antonowan225 schrieb: > Freue mich über jede noch so kleine Antwort. sehr klein Beitrag "MSP430G2553 PWM Duty Cycle mit Poti einstellen"
Henry schrieb: > Welche Auflösung soll der Frequenz-Wobbel haben? > > Nur 1 Poti? oder 1 für die Frequenz und 1 für das PWM? > > Kurvenform Wobbelgenerator: Rechteck/Sinus/Sägezahn? Was meinst du mit Auflösung? Du meinst wenn das diskrtete Signal vom A/D- Wandler ausgegebnen wird? das würde ja nur die zweite Aufgabe mit dem poti betreffen, richtig? Zwei Potis habe ich, also ein Poti je Funktion Kurvenform Rechteck, wie würde ein Pulsbreite-Wobbel aussehen?
Antonowan225 schrieb: > Kurvenform Rechteck, wie würde ein Pulsbreite-Wobbel aussehen? Die Frage lautet: wie würde ein Pulsbreite-Wobbel für eine Sinusfunktion aussehen? MAL EINE ANDERE FRAGE: kennt jemand eine gute IAR EMBEDDED Workbench EInführung auf Deutsch?
Antonowan225 schrieb: > MAL EINE ANDERE FRAGE: kennt jemand eine gute IAR EMBEDDED Workbench > EInführung auf Deutsch? Du arbeitest doch mit einem TI Prozessor. Warum nutzt Du nicht das Code Composer Studio. Ab Version 7 ist CCS kostenlos und nicht mehr im Speicher limitiert. Dazu gibt es einiges an Unterstützung. http://software-dl.ti.com/ccs/esd/documents/ccs_downloads.html mfg klaus
Klaus R. schrieb: > Du arbeitest doch mit einem TI Prozessor. Warum nutzt Du nicht das Code > Composer Studio. Ab Version 7 ist CCS kostenlos und nicht mehr im > Speicher limitiert. Dazu gibt es einiges an Unterstützung. > > http://software-dl.ti.com/ccs/esd/documents/ccs_downloads.html > mfg klaus danke für den Hinweis, leider ist IAR von der Schule vorgegeben
Antonowan225 schrieb: > danke für den Hinweis, leider ist IAR von der Schule vorgegeben Der IAR ist nicht schlecht. Im Gegenteil. Ich konnte vor einigen Jahren damit besser debuggen. Erst mit CCS 7 hat TI für die Free-Version die Einschränkung des nutzbaren Speichers aufgehoben. Jetzt ist TI bei CCS 9.2. Ich könnte mir vorstellen das TI dem MSP - µC besser unterstützt als IAR der nicht so typbezogen ist. Jedenfalls sind IAR und CCS gegen über anderen Entwicklungsumgebungen schon sehr komfortabel. Das wurde mir hier im Forum von Experten so bestätigt. mfg Klaus
Es waere nicht ganz verkehrt, mit dem MSP430 ueberhaupt mal ein Rechteck mit dem Timer zu erzeugen. Mehr als: > Was mir bekannt ist: > > Funktionsweise des Timers im Up-Mode braucht es ja fast nicht. Oder wartest du darauf das dir jemand deinen A.sch hinterhertraegt?
pumuggl schrieb: > Oder wartest du darauf das dir jemand deinen A.sch hinterhertraegt? okay ich weiß jz grob, wie ich die Sache angehen möchte: zunächst den Pulswobbel erarbeiten - Frequenz auf 50 Hz festlegen: Submasterclock verwendet, ergibt 20960 (entspräche doch in Abhängigkeit vom Timer TA0ccr0/TB0CCR0) - maximale Breite festelgen (in Prozent PWM_Max= 0.95*20960) - minimale B. festlegen 0,05 * 20960 - Schrittweite Festlegen PWM_S= 0,05*20960 (sind diese drei Sachen variablen oder definitionen?) - würde dazu den OUTMOD_3 des Timers A wählen (set/reset) -Pulsbreite high, wenn interrupt vektor TA0ccr1 (wird dieser wert automatisch generiert, dadurch dass ich die frequenz mit ta0ccr0= 20960 gesetzt habe? oder muss ich den ausrechnen?) -pulsbreite low, wenn interrupt vektor TA0ccr1 kommt -entprellen der taster -das ergebnis an einer led zeigen woher weiß ich, welche ports ich konfigurieren muss? was gibt es da zu konfigurieren? was schreibt ihr in die Bedienung des watchdog- Timers? Wie kann ich sehen, was in meiner Header-Datei "msp430f5529.h" enthalten ist?
Du musst CCR0 so setzen, dass die gewünschte Frequenz heraus kommt. Du musst CCR1 auf einen Wert zwischen 0 und CCR0 setzen; es bestimmt die Zeitdauer, für die der Ausgang low ist. Wenn du z.B. TA0 für die PWM-Ausgabe nimmst, dann solltest du den Interrupt eines anderen Timer-Moduls (TA1/TA2/TB0) nehmen, um regelmäßig Frequenz bzw. Pulsbreite zu ändern. Antonowan225 schrieb: > woher weiß ich, welche ports ich konfigurieren muss? Wie man in Tabelle 6-11 des MSP430F5529-Datenblatts sieht, gibt es für TA0.1 nur einen möglichen Pin. Die Konfiguration findest du in Abschnitt 6.10. > was schreibt ihr in die Bedienung des watchdog- Timers? Brauchst du ihn? Wenn nicht, abschalten. > Wie kann ich sehen, was in meiner Header-Datei "msp430f5529.h" enthalten > ist? Das ist eine normale Textdatei ...
:
Bearbeitet durch User
Clemens L. schrieb: > Interrupt eines anderen Timer-Moduls (TA1/TA2/TB0) nehmen, um regelmäßig > Frequenz bzw. Pulsbreite zu ändern. was meinst du damit?
TA0 läuft automatisch, und braucht keinen Interrupt-Handler. TA1 hat einen Interrupt-Handler, der TA0CCR0/1 ändert.
Clemens L. schrieb: > TA0 läuft automatisch, und braucht keinen Interrupt-Handler. > > TA1 hat einen Interrupt-Handler, der TA0CCR0/1 ändert. danke für deine Antwort
Wie kann ich die Frequenz und die Pulsbreite verändern, wenn ich nur zwei buttons/ Taster zur Verfügung habe? Taster eins ist für on/off, der zweite Taster müsste dann für die Frequenz/pulsbreite herhalten. Mein erster Einfall ist es, in Abhängigkeit von der Zeit (z.B. >2 sekunden Drücken des Tasters) und einer Bestätigung (z.B. zweimaliges Blinken einer LED) die Frequenz und andersherum die pulsbreite einzustellen. IST jedoch sehr unpraktisch. hat jemand eine praktische Idee?
Clemens L. schrieb: > Du musst CCR1 auf einen Wert zwischen 0 und CCR0 setzen; es bestimmt die > Zeitdauer, für die der Ausgang low ist. habe jetzt schon in einigen Codebeispielen gesehen, dass für den Timer B anstatt CCR1 CCR2 genommen wird, umd die Periodendauer festzulegen. WOran liegt das?
Was hast du denn schon am Laufen? Zeig einmal deinen Code. Wenn immer noch nichts lauffähiges vorliegt, nimm das verlinkte Beispiel undexperimentiere damit. Beitrag "Re: MSP430G2553 PWM Duty Cycle mit Poti einstellen" Mit CCR0 kannst du die Frequenz ändern und mit CCR1 das Tastverhältnis. Wie Clemens schrieb, läuft die PWM - mit dem vorgegebenen Tastverhältnis - vollständig in der HW und braucht keine ISR.
fertig schrieb: > Zeig einmal deinen Code. der Code ist nicht das Problem, hier der Beispielcode, den ich angesprochen hatte: void INIT_TB0(void) TB0CTL = TBCLR; // Timer-Counter RESET auf Null TB0CCR0 = Frequenz; // 50 Hz (0.02s) TB0CCTL2 = OUTMOD_7; // High-Pegel von 0 - CCR2 TB0CCR2 = (int)((float)(PWM_Aktuell) / 100 * (float)(Frequenz)); TB0CTL = TBSSEL_2 + ID_0 + MC_1; // SMCLK, 1:1, UP-Mode fertig schrieb: > Mit CCR0 kannst du die Frequenz ändern und mit CCR1 das Tastverhältnis. so kenne ich das auch. Obwohl im Datenblatt folgendes steht: A transfer is triggered when the TBxCCR2 CCIFG flag is set. The TBxCCR2 CCIFG flag is automatically reset when the transfer starts. If the TBxCCR2 CCIE bit is set, the TBxCCR2 CCIFG flag does not trigger a transfer. muss man deswegen ccr2 setzen? fertig schrieb: > vollständig in der HW und braucht keine ISR woher weißt du das? danke dir schoneinmal im Voraus
Warum das ohne ISR läuft? Weil TI dem MSP eine wundervolle Timer HW spendiert hat. ? Schau dir das Beispiel an, wo ist da eine ISR? Anhand der Frage sehe ich, dass du den MSP Timer nicht richtig verstanden hast. Mit welchem Takt läuft der Timer? Bei welchem Wert erfolgt der Überlauf? Wie funktioniert Outputmode? Das steht alles super erklärt auf den 10 Seiten im Family User Guide. Und Code ist auch ein Problem. Der Einsatz von Float ist hier völlig fehlplatziert. ?
fertig schrieb: > Mit welchem Takt läuft der Timer? Bei welchem Wert > erfolgt der Überlauf? Wie funktioniert Outputmode? ich kann dir die Fragen beantworten, habe ich es dann verstanden? fertig schrieb: > Der Einsatz von Float ist hier völlig > fehlplatziert. es funktioniert aber... fertig schrieb: > Warum das ohne ISR läuft? Weil TI dem MSP eine wundervolle Timer HW > spendiert hat. okay, ISR habe ich auch in einem andrem Zusammenhang gehört, deswegen meine Nachfrage. Hier ein Codebeispiel, um die Periodendauer zu verändern #pragma vector=TIMER2_A0_VECTOR __interrupt void TA2_0_ISR() { P2IES |= T_SET; // Zurück auf negative Flanke if(PWM_Step_Dir == 0) { PWM_Step_Dir = 1; TX_String("\nT_SET: +5%\n"); } else { PWM_Step_Dir = 0; TX_String("\nT_SET: -5%\n"); } P2IFG &= ~(T_SET); } mir ist nicht ganz bewusst, wann ich das Pragma brauche und wie das ISR Zustande kommt. Danke Dir =)
Ich hake die 1sten beiden Punkte ab, Dir ist dabei nicht zu helfen. ? Aber zur ISR, wenn ein interrupt Auftritt - z B Timer - dann wird an eine von TI designte Adresse verzweigt und der Code dort ausgeführt. Die Adressen für die verschiedenen Internets nennt sich InterruptVektorTabelle. In der Regel stehen dort jumps auf die ISR an einer ganz anderen Adresse. Und damit der Compiler/Linker diese Verbindung herstellt, musst du ihm mit dem pragma und __interrupt helfen. Such mal in deinem Projekt nach TIMER2_A0_VECTOR. In irgendeinem Header steht da ne Nummer oder Adresse.
fertig schrieb: > Ich hake die 1sten beiden Punkte ab, Dir ist dabei nicht zu helfen. ? das hört sich böse an haha. Kannst du es nochmal versuchen,mir zu erklären, worauf du hinaus möchtest? fertig schrieb: > Aber zur ISR, > wenn ein interrupt Auftritt - z B Timer - dann wird an eine von TI > designte Adresse verzweigt und der Code dort ausgeführt. Die Adressen > für die verschiedenen Internets nennt sich InterruptVektorTabelle. In > der Regel stehen dort jumps auf die ISR an einer ganz anderen Adresse. > Und damit der Compiler/Linker diese Verbindung herstellt, musst du ihm > mit dem pragma und __interrupt helfen. > > Such mal in deinem Projekt nach TIMER2_A0_VECTOR. In irgendeinem Header > steht da ne Nummer oder Adresse. super Erklärung, danke dir. Ich weiß aber nicht, wo ich die headerdatei finden kann
Markiere das TIMER2_A0_VECTOR und benutze die Suche nach der Deklaration. Und nein, war nicht böse gemeint. Aber z B für die Diskussion, ob float dort angebracht sind oder nicht, ist mir meine Zeit zu schade. Vielleicht findet sich ein anderer.
Antonowan225 schrieb: > Woran es mangelt: > Habe so ziemlich null Erfahrung mit programmieren, C soll ja nicht > unbedingt einfach sein. (Aber bitte jetzt nicht stumpf Link zum > nächstbesten Tutorial schicken) Mir wäre mit Beispielprogrammen, die ein > sehr ähnliches Thema behandeln, am meisten geholfen. Du bist ein Vollidiot, wenn du das tatsächlich glaubst. Nein, eine Programmiersprache (egal welche) ist ein (dein!) Werkzeug. Man muss es beherrschen, um zu einem ordentlichen Ergebnis kommen zu können. Beispielcode ist nur nützlich, wenn man ihn wirklich versteht. Auch dazu ist wieder die Beherrschung des Werkzeugs nötig. Du kannst dich in deiner grenzenlosen Faulheit also winden, wie du willst: du kommst nicht drum herum. Und das finde ich richtig gut!
c-hater schrieb: > Du bist ein Vollidiot, wenn du das tatsächlich glaubst. > > Nein, eine Programmiersprache (egal welche) ist ein (dein!) Werkzeug. > Man muss es beherrschen, um zu einem ordentlichen Ergebnis kommen zu > können. > > Beispielcode ist nur nützlich, wenn man ihn wirklich versteht. Auch dazu > ist wieder die Beherrschung des Werkzeugs nötig. > > Du kannst dich in deiner grenzenlosen Faulheit also winden, wie du > willst: du kommst nicht drum herum. Und das finde ich richtig gut! um eins klarzustellen: ich mache die ganze Sache freiwillig, also gibt es keinen Grund für mich faul zu sein. Nur weil mir grundlegendes Wissen fehlt, heißt es nicht, dass ich mich nicht bemühe! Soll man etwa HEmmungen haben in diesem Forum Fragen zu stellen?? Vielen Dank für deinen gloreichen Beitrag
Mein Senf schrieb: > wieso wendest du dich nicht an deinen Informatiklehrer? weil ich ihn selten sehe und ich dann auch nicht zu hause arbeiten kann
Antonowan225 schrieb: > c-hater schrieb: >> Du bist ein Vollidiot, wenn du das tatsächlich glaubst. >> >> Nein, eine Programmiersprache (egal welche) ist ein (dein!) Werkzeug. >> Man muss es beherrschen, um zu einem ordentlichen Ergebnis kommen zu >> können. >> >> Beispielcode ist nur nützlich, wenn man ihn wirklich versteht. Auch dazu >> ist wieder die Beherrschung des Werkzeugs nötig. >> >> Du kannst dich in deiner grenzenlosen Faulheit also winden, wie du >> willst: du kommst nicht drum herum. Und das finde ich richtig gut! > > um eins klarzustellen: ich mache die ganze Sache freiwillig, also gibt > es keinen Grund für mich faul zu sein. Nur weil mir grundlegendes Wissen > fehlt, heißt es nicht, dass ich mich nicht bemühe! Soll man etwa > HEmmungen haben in diesem Forum Fragen zu stellen?? Vielen Dank für > deinen gloreichen Beitrag alte Forumsweisheit: c-hater nicht weiter ernstnehmen, der hat so schlechte Manieren, egal wo er mitschreibt. Leider, denn manchmal schimmert ein bischen Wissen unter seinem rüpelhaften Ton hervor... manchmal...
void TimerA1 (void) { //TA1CTL = TACLR; // Timer-Counter RESET auf Null TA1CCR0 = (int) ((float) (FRQ_Aktuell) / 100 *(float)(Periodendauer)); TA1CCTL0 = OUTMOD_7; // Interrupt bei TA1CCR0 TA1CCR1 = Periodendauer; TA1CTL = TASSEL1; // Taktquelle ACLKK; 32768 kHz TA1CTL = ID_0; // Teiler 1 TA1CTL = MC_1; // UP-Modus gewählt } void TimerB0 (void) { //TB0CTL = TBCLR; TB0CCR0 = Frequenz; TB0CCTL2 = OUTMOD_7; TB0CCR1 = (int)((float)(PWM_Aktuell) / 100 * (float)(Frequenz)); TB0CTL = TBSSEL_2 + MC_1 + ID_0; // SMCLK, 1:1, UP-Mode } // _________ Interrupt-Funktionen _________________________ void Pulswobbel (void) #pragma vector = TimerB0_TA1_ISR () { if (PWM_Aktuell < PWM_Max && PWM_Dir == 1) { PWM_Aktuell += PWM_Step; } else (PWM_Aktuell > PWM_Max && PWM_Dir == 1) { PWM_Aktuell -= PWM_Step; PWM_Dir = 0; } if (PWM_Aktuell > PWM_Min && PWM_Dir == 0) { PWM_Aktuell -= PWM_Step; } else (PWM_Aktuell < PWM_Min && PWM_Dir == 0) { PWM_Aktuell += PWM_Step; PWM_Dir = 0; } } void Frequenzwobbel (void) #pragma vector = TimerA1_TA0_ISR () { if (FRQ_Aktuell < FRQ_Max && FRQ_Dir == 1) { FRQ_Aktuell += FRQ_Step; } else (FRQ_Aktuell > FRQ_Max && FRQ_Dir == 1) { FRQ_Aktuell -= FRQ_Step; FRQ_Dir = 0; } if (FRQ_Aktuell > FRQ_Min && FRQ_Dir == 0) { FRQ_Aktuell -= FRQ_Step; } else (FRQ_Aktuell < FRQ_Min && FRQ_Dir == 0) { FRQ_Aktuell += FRQ_Step; FRQ_Dir = 1; } } erstens bekomme ich eine Fehlermeldung in ersten else Schleife, kann den Fehler aber nicht finden :/ zweitens die Frage, ob ich tACLR und TBCLR setzen soll, denn sonst wird der Timer neu gestartet und die Information über die FRequenzänderung/ Pulsbreiteänderung geht verloren... zumindest habe ich das so verstanden. Habe ich das so richtig verstanden? Würde mich sehzr über konstruktive Kritik freuen Beste Grüße
Lade Dir von TI das MSP430Ware Paket herunter. Dort sind jede Menge Beispiele vorhanden für alle verfügbaren MSP430 Controller vorhanden, auch zu Deinen Themen. Dann empfehle ich Dir das MSP430 Controller Buch (chttps://www.elektor.de/das-msp430-mikrocontroller-buch-pdf). Das kostet zwar um die 30€, ist aber jeden Cent wert, da die einzelnen Controllerkomponenten Schritt für Schritt, inclusive Codebeispielen, erklärt werden. Zum Dritten solltest Du Dich erst einmal darüber informieren was Wobbeln und Pulsweitenmodulation ist, damit weist was Du programmieren sollst. Es hilft Dir nicht weiter, wenn Du zwar programmieren kannst aber keine Peilung hast was Du da programmieren sollst. Ich habe den Fall gerade bei mir in der Firma. Da soll einer ein von mir geschriebenes Programm in C# neu implementieren. Der Typ kann zwar programmieren, aber er weis nicht was er tut. Demzufolge fummelt er schon 5 Jahre dran rum (ich hatte seinerzeit für die selbe Funktionalität 10 Wochen gebraucht) und das Programm ist immer noch nicht praktisch zu gebrauchen. Dieser kleine Abstecher ist zwar etwas offtopic, aber ich hoffe mal Du verstehst was ich damit sagen will.
Antonowan225 schrieb: > Fehlermeldung in ersten else Schleife else Schleife? Egal, aber wie lautet die Fehlermeldung und wie kann man die Zeilen zuordnen? Du musst die ganze Datei anhängen und die Fehlerausgabe hier rein kopieren. Antonowan225 schrieb: > void Pulswobbel (void) > #pragma vector = TimerB0_TA1_ISR () Mein IAR benötigt eine andere Syntax für ISR. Antonowan225 schrieb: > if (FRQ_Aktuell < FRQ_Max && FRQ_Dir == 1) > { > FRQ_Aktuell += FRQ_Step; > } > else (FRQ_Aktuell > FRQ_Max && FRQ_Dir == 1) > { > FRQ_Aktuell -= FRQ_Step; > FRQ_Dir = 0; > } > if (FRQ_Aktuell > FRQ_Min && FRQ_Dir == 0) > { > FRQ_Aktuell -= FRQ_Step; > } > else (FRQ_Aktuell < FRQ_Min && FRQ_Dir == 0) > { > FRQ_Aktuell += FRQ_Step; > FRQ_Dir = 1; > } Wenn man das umschreibt, erkennt man schnell die Lücken.
1 | if(FRQ_Dir == 1){ |
2 | if(FRQ_Aktuell < FRQ_Max) |
3 | FRQ_Aktuell += FRQ_Step; |
4 | else if(FRQ_Aktuell > FRQ_Max){ |
5 | FRQ_Aktuell -= FRQ_Step; |
6 | FRQ_Dir = 0; |
7 | }
|
8 | else
|
9 | ; // und FRQ_Aktuell == FRQ_Max |
10 | }
|
11 | else if(FRQ_Dir == 0){ |
12 | ...
|
13 | }
|
14 | else
|
15 | ; // und FRQ_Dir > 1 ? |
Da es regnet, suche ich mein Launchpad und schließe es einmal an. ;-)
Zeno schrieb: > das MSP430 Controller Buch Ich kenne das Buch nicht. Aber die meisten Bücher sind nur Abschriften des gut strukturierten Family User Guide. Die ganze TI Doku zum MSP430 ist sehr gut und auch fürs Selbststudium geeignet und ausreichend. Also immer schön den Family User Guide neben die Tastatur legen.
fertig schrieb: > Mein IAR benötigt eine andere Syntax für ISR wie würde die Syntax den aussehen? denn ich bin mir bei meiner auch nicht sicher
fertig schrieb: > Ich kenne das Buch nicht. Aber die meisten Bücher sind nur Abschriften > des gut strukturierten Family User Guide. Die ganze TI Doku zum MSP430 > ist sehr gut und auch fürs Selbststudium geeignet und ausreichend. > > Also immer schön den Family User Guide neben die Tastatur legen. Ja klar sind das im Prinzip Abschriften, aber auf das Wesentliche reduziert. Für den Einstieg ist das Buch besser als die User Guide. Hinzu kommt das das Buch in deutsch ist, wodurch es für die meisten (Einsteiger) besser lesbar ist. Wenn man tiefer einsteigen möchte/muss kommt man um die User Guide, die von TI sehr gut ist, nicht herum. Das was der TO will ist in dem Buch jedenfalls bestens beschrieben. Die TI User Guide erschlägt einen da mit der Fülle der Informationen. Das meiste braucht man für den Anfang eben nicht.
fertig schrieb: > Egal, aber wie lautet die Fehlermeldung und wie kann man > die Zeilen zuordnen? Du musst die ganze Datei anhängen und die > Fehlerausgabe hier rein kopieren. ich schicke dir das ganze Programm okay?
Antonowan225 schrieb: > fertig schrieb: >> Mein IAR benötigt eine andere Syntax für ISR > > wie würde die Syntax den aussehen? denn ich bin mir bei meiner auch > nicht sicher Das merkt man doch, wenn die ISR nicht funktioniert. In aller Regel bekommt man es gar nicht kompiliert. Ansonsten läßt man gerade bei solchen Taktgeschichten in der ISR irgend einen freien Port, den man als Ausgang konfiguriert hat toggeln und hängt einen Oszi dran. Dann weis man ob es passt oder nicht. Und dann habe ich auch den Eindruck, das Du zu faul zum Lesen bist und Dir lieber ein fertiges Ergebnis präsentieren läßt. Ach ja das von mir empfohlene Buch muß man noch nicht mal kaufen, denn es gibt es sogar als Onlineversion, wenn mal Google bemüht.
So, du hast gefragt, wie ich das angehen würde? Ich würde das verlinkte Beispiel ausbauen, Schritt für Schritt: z B Frequenz und Tastverhälnis ändern.
1 | #include <msp430g2553.h> |
2 | #include <stdint.h> |
3 | |
4 | #define LED_GREEN BIT6
|
5 | #define TASTE_S2 BIT3
|
6 | |
7 | #define DUTYCYCLE_DIVIDER 5
|
8 | |
9 | #define CHANGE_ALL_MS 500
|
10 | |
11 | int main(void) { |
12 | |
13 | WDTCTL = WDTPW | WDTHOLD; // WDT stoppen |
14 | |
15 | BCSCTL1 = CALBC1_1MHZ; // Sytemtakt |
16 | DCOCTL = CALDCO_1MHZ; |
17 | |
18 | P1SEL |= LED_GREEN; // LED zeigt PWM |
19 | P1DIR |= LED_GREEN; |
20 | |
21 | P1REN |= TASTE_S2; // Pullup einschalten |
22 | P1OUT |= TASTE_S2; |
23 | |
24 | TACCR0 = 1000; // Frequenz einstellen, 1kHz |
25 | TACCR1 = TACCR0 / DUTYCYCLE_DIVIDER ; // duty cycle default |
26 | TACCTL1 = OUTMOD2 | OUTMOD1 | OUTMOD0; // TAO.1 im Mode 7 |
27 | TACTL = TASSEL1 | MC0 | TACLR; // Timer einstellen und löschen |
28 | |
29 | WDTCTL = WDT_MDLY_32; // WDT timer intr all 32ms |
30 | IE1 |= WDTIE; // unmask WDT timer intr |
31 | |
32 | _BIS_SR(GIE); // (global) enable interrupts |
33 | |
34 | volatile static uint16_t i = 0; |
35 | while (1) { |
36 | if (i > 4711) |
37 | i = 0; |
38 | }
|
39 | }
|
40 | |
41 | // WDT timer ISR
|
42 | #pragma vector = WDT_VECTOR
|
43 | __interrupt void wdt_timerISR(void) { |
44 | |
45 | // not enough time gone; do nothing
|
46 | static uint16_t cnt = 0; |
47 | cnt++; |
48 | if ((cnt * 32) < CHANGE_ALL_MS) { |
49 | return; |
50 | }
|
51 | |
52 | cnt = 0; // restart |
53 | |
54 | // maybe TACCR0 overflow; set defaults
|
55 | if (TACCR0 >= 0x6FFF) { |
56 | TACCR0 = 1000; |
57 | TACCR1 = TACCR0 / DUTYCYCLE_DIVIDER; |
58 | }
|
59 | // inc TACCR1
|
60 | else if (TACCR1 < (TACCR0 - (TACCR0 / DUTYCYCLE_DIVIDER))) { |
61 | TACCR1 += TACCR0 / DUTYCYCLE_DIVIDER; |
62 | }
|
63 | // overflow TACCR1; inc TACCR0
|
64 | else { |
65 | TACCR0 += 4000; |
66 | TACCR1 = TACCR0 / DUTYCYCLE_DIVIDER; |
67 | }
|
68 | }
|
Zeno schrieb: > In aller Regel > bekommt man es gar nicht kompiliert. Das hat er doch geschrieben. Zeno schrieb: > Ansonsten läßt man gerade bei > solchen Taktgeschichten in der ISR irgend einen freien Port, den man als > Ausgang konfiguriert hat toggeln und hängt einen Oszi dran. Oder nutzt den Debugger. Mit dem IAR geht das auch in ISR problemlos.
fertig schrieb: > Zeno schrieb: >> In aller Regel >> bekommt man es gar nicht kompiliert. > Das hat er doch geschrieben. Nö hat er nicht. Er schrieb nur: Antonowan225 schrieb: > wie würde die Syntax den aussehen? denn ich bin mir bei meiner auch > nicht sicher Das kann alles bedeuten. Aber das Problem sollte doch jetzt, nachdem Du eine fertige Lösung präsentiert hast erledigt sein. Man muß halt nur genug jammern, dann findet sich schon einer der es erledigt. fertig schrieb: > Oder nutzt den Debugger. Mit dem IAR geht das auch in ISR problemlos. Kann man sicher auch machen. Oszi hat halt den Vorteil das man das Resultat (z.B. erzeugte Frequenz) besser beurteilen
Zeno schrieb: > Kann man sicher auch machen. Oszi hat halt den Vorteil das man das > Resultat (z.B. erzeugte Frequenz) besser beurteilen nicht jeder hat einen oszi zuhause rumfliegen. Vielen Dank für den Hinweis mit dem Buch, werde gleich google bemühen
Antonowan225 schrieb: > nicht jeder hat einen oszi zuhause rumfliegen. Richtig, ist aber beim Thema µC genau das richtige Werkzeug, um das eine oder andere Problem einzukreisen...
fertig schrieb: > So, du hast gefragt, wie ich das angehen würde? Ich würde das verlinkte > Beispiel ausbauen, Schritt für Schritt: > z B Frequenz und Tastverhälnis ändern. Super nett von dir, dass du dir die Mühe gemacht hast. Soweit ich das nachvollzogen habe, basiert deine Idee aber nicht auf meinem ursprünglichen Ansatz. Wenn ich den jetzt weiter verfolgen wollte, die Frage: du hast oben von Lücken gesprochen, welche Lücken sieht du in meinem code? Grüße
@Zeno > Nö hat er nicht. Doch, hat er, Ich lese > erstens bekomme ich eine Fehlermeldung
fertig schrieb: > Die else nur mit ; und Kommentar. ich habe jetzt im ursprünglichen code anstatt else elseif verwendet, ohne weitere kommtenare oder semikolons. Es funktioniert. Warum?
fertig schrieb: > @Zeno >> Nö hat er nicht. > Doch, hat er, Ich lese >> erstens bekomme ich eine Fehlermeldung Ja Lesen ist eben doch eine Kunst. In dem von mir zitierten Post (Beitrag "Re: MSP430 F5529 Wobbel-Generator") hat er eben nicht geschrieben das er eine Fehler bekommt. Das worauf Du Dich beziehst lese ich in einem anderen Zusammenhang. Ist jetzt aber auch egal, da das Problem ja gelöst ist.
Rechteck, oder Sinus??? Bei 25 MHz sollte es doch möglich sein, einen 2 kHz sinus mit PWM darzustellen. Ob das unter "Anfängerübung" läuft, sei dahingestellt.
so anbei erste Version des Programms. Was ich noch fertigstellen will, ist, dass ich zwischen Frequenzwobbel und Pulsweitewobbel über einen Taster wechseln kann. Ist noch nicht drin. Wahrscheinlich fehlt mir dazu ein Timer Das Problem, welches ich nicht behoben bekomme, ist TX_String und TX_Byte zur aUSGABE AM pc. Vllt hat jmd idee. vielen Dank
Zeno schrieb: > Ach ja das von mir > empfohlene Buch muß man noch nicht mal kaufen, denn es gibt es sogar als > Onlineversion, wenn mal Google bemüht hast du einen Link für mich? Zeno schrieb: > Antonowan225 schrieb: >> fertig schrieb: >>> Mein IAR benötigt eine andere Syntax für ISR >> >> wie würde die Syntax den aussehen? denn ich bin mir bei meiner auch >> nicht sicher zum Syntax: mein Ziel ist es, dass ich beim Interrupt Vektro TA1 des Timers B0 ein code abgearbeitet wird. Ich würde den Code dazu wie folgt velinken: #pragma vector = Timer0_TA1_ISR () __interrupt void TB0_TA1_ISR() ist falsch, bekomme eine Fehlermeldung: kANN MIR JMD SAGEN WIE ES RICHTIG GEHT?
> kANN MIR JMD SAGEN WIE ES RICHTIG GEHT?
Scheinbar rueckt der Abgabetermin naeher. Man wird lauter.
Wenn man sie nicht vorsaetzlich wegloescht, sollte die
Dokumentation unter ${IAR}/msp430/doc als PDF zu finden sein.
Da gibt es dann ein Kapitel "Interrupt functions for ..."
im DevelopmentGuide.
Abyssaler Einspeiser schrieb: > Scheinbar rueckt der Abgabetermin naeher. Man wird lauter. ahja jetzt wird die Feststelltaste überinterpretiert... =) Abyssaler Einspeiser schrieb: > Wenn man sie nicht vorsaetzlich wegloescht, sollte die > Dokumentation unter ${IAR}/msp430/doc als PDF zu finden sein. Was meinst du damit? Danke dir
ich würde unsigned int Modus = 0 // Wahl zwischen Frequenzwobbel und Pulswobbel 0: // Pulswobbel, 1: Frequenzwobbel einführen, wobei bei Systemstart automatisch Modus = 0 aufgerufen ist. Wechsel zwischen den Modi wird herbeigeführt durch drücken des Taster T_OnOff und T_Step für 2 Sekunden. Welchen Timer würdet ihr für diese Funktion verwenden?
oder haltet ihr das überhaupt für sinnvoll? Dankeschön schoneinmal im Voraus
https://homepages.thm.de/~hg6458/mpt-Dateien/MPT.pdf hier steht auf Seite 66, wie ich den Interrupt für einen Timer bei CCR0 auslöse. Ich möchte jedoch für den Pulswobbel, dass die ISR schon bei CCR1 ausgelöst wird. Wie stelle ich das hinsichtlich Syntax ein?
Timer B? Im Header io430f5529.h steht #define TIMER0_B1_VECTOR ... #define TIMER0_B0_VECTOR ... und im Family User Guide http://www.ti.com/lit/pdf/slau208 ab Seite 482: 18.2.6 Timer_B Interrupts Two interrupt vectors are associated with the 16-bit Timer_B module: • TBxCCR0 interrupt vector for TBxCCR0 CCIFG • TBIV interrupt vector for all other CCIFG flags and TBIFG Also, der TIMER0_B0_VECTOR gilt für CCR0 und TIMER0_B1_VECTOR shared den Rest, siehe TBxIV Register auf Seite 505 oder im Header io430f5529.h: /* TB0IV Definitions */ #define TB0IV_NONE (0x0000u) /* No Interrupt pending */ #define TB0IV_TBCCR1 (0x0002u) /* TB0CCR1_CCIFG */ #define TB0IV_TBCCR2 (0x0004u) /* TB0CCR2_CCIFG */ #define TB0IV_TBCCR3 (0x0006u) /* TB0CCR3_CCIFG */ #define TB0IV_TBCCR4 (0x0008u) /* TB0CCR4_CCIFG */ #define TB0IV_TBCCR5 (0x000Au) /* TB0CCR5_CCIFG */ #define TB0IV_TBCCR6 (0x000Cu) /* TB0CCR6_CCIFG */ #define TB0IV_TBIFG (0x000Eu) /* TB0IFG */ So einfach ist das.
Du musst keinen teuren OSZi kaufen. Ein Logikanalysator ( Clone) ist für unter 10€ erhältlich: https://www.roboter-bausatz.de/255/usb-logic-analyzer-24mhz-8ch
fertig schrieb: > Im Header io430f5529.h steht ich habe die datei noch nie bei mir gefunden fertig schrieb: > So einfach ist das. danke, lieb von dir
Otto schrieb: > Du musst keinen teuren OSZi kaufen. ich habe die Möglichkeit, in der Schule einen oszi zu nutzen... aber eben nur unter der Woche
habe ich das so richtig verstanden? #pragma vector = Timer0_B1_ISR () __interrupt void TB0IV_TBCCR1_ISR()
ein weiteres Problem das ich habe: würde gerne unabhängig vom eingestellten Modus die Ausgabe von Puls oder Frequenzwobbel an dem gleichen Pin. So wie die letzte Version des Programm ist (s.o.), wird sowohl an der LED als auch am PIN 7.4 das signal ausgegeben... funktioniert aber nur für den TIMER B0, also für den Pulswobbel. Für den Timer A1 wären, so wie ich das verstanden habe, nur der Pin 2.0 verfügbar. Was würdet ihr dazu machen?
void Modiwechsel (void) { // Von Pulswobbel auf Frequenzwobbel if ( Modus = 1 && P1IFG & T_OnOff && P2IFG & T_Step) { Modus = 2; TimerA1(); } // Von Frequenzwobbel auf Pulswobbel else if (Modus 2 && P1IFG & T_OnOFF && P2IFG & T_Step) { Modus = 1; TimerB0(); } // Flankenereignisse Löschen P1IFG &=~ T_OnOff; P2IFG &=~ T_Step; } so in etwa habe ich mir den Moduiwechsel überlegt.Ich könnte mir vorstellen, dass folgende Probleme auftreten: 1. Niemals drückt jemand beide Taster exakt gleich, damit wäre man sofort in den Routinen für System An/aus oder Pulsbreite/Frequenzänderung. Was kann man dagegen tun? 2. Die ISR der Ports würden aufgerufen werden, dort müsste ich jeweils die beiden Taster gegeneinander negieren um die ISR zu beenden. Scheint mir nicht grade geschickt. 3. Ich habe keinen Timer mehr zur Verfügung, würde Drücken der beiden Taster gerne auf 2 Sekunden verpflichten. Den Timer_A0 habe ich bereits für 2 Sekunden ausgelegt, doch dessen Funktion ist für Pulsweitenänderung/ Frequenzänderung gedacht. Kann ich über einen anderen Kanal den Timer auch für den Modiwechsel nutzen? wenn ja, wie müsste ich das angehen? FÜr die Antworten bedanke ich mich schon jetzt
kleiner Nachtrag: normalerweise hätte ich ja die beiden Inhterrupts ver-und-en sollen, anstatt eine Funktion Modiwechsel daraus zu machen. ich weiß nicht wie das geht =)
Antonowan225 schrieb: > kleiner Nachtrag: > > normalerweise hätte ich ja die beiden Inhterrupts ver-und-en sollen, > anstatt eine Funktion Modiwechsel daraus zu machen. ich weiß nicht wie > das geht =) vllt einfach katergorisch die Funktion Modiwechsel in beide ISR der beiden taster schreiben?
hier nochmal eine kleine korrektur vorgenommen, ändert aber nichts an meinen Fragen void Modiwechsel (void) { // Von Pulswobbel auf Frequenzwobbel if ( Modus == 1 && P1IFG & T_OnOff && P2IFG & T_Step) { Modus = 2; TimerA1(); } // Von Frequenzwobbel auf Pulswobbel else if (Modus == 2 && P1IFG & T_OnOFF && P2IFG & T_Step) { Modus = 1; TimerB0(); } // Flankenereignisse Löschen P1IFG &=~ T_OnOff; P2IFG &=~ T_Step; }
Antonowan225 schrieb: > else if (Modus == 2 && P1IFG & T_OnOFF && P2IFG & T_Step) bekomme in der Zeile übrigens folgende Fehlermeldung: Error[Pe059]: function call is not allowed in a constant expression Error[Pe661]: expected an integer constant
Antonowan225 schrieb: > ich habe die datei noch nie bei mir gefunden Dann lass doch einfach danach suchen. Und zwar auf dem Speichermedium, auf dem IAR installiert ist. Antonowan225 schrieb: > #pragma vector = Timer0_B1_ISR () Nö, was steht im Header? >>> TIMER0_B1_VECTOR Funktioniert analog dem Beispiel fertig schrieb: > // WDT timer ISR > #pragma vector = WDT_VECTOR > __interrupt void wdt_timerISR(void) { Den Rest deiner Überlegungen verstehe ich nicht.
fertig schrieb: > Nö, was steht im Header? >>> TIMER0_B1_VECTOR > Funktioniert analog dem Beispiel > fertig schrieb: >> // WDT timer ISR >> #pragma vector = WDT_VECTOR >> __interrupt void wdt_timerISR(void) { also: fertig schrieb: > Dann lass doch einfach danach suchen. Und zwar auf dem Speichermedium, > auf dem IAR installiert ist. hab ich, finde es wirklich nicht. Frage mal den Lehrer, wahrscheinlich einfach nur zu doof fertig schrieb: > Funktioniert analog dem Beispiel wenn es anlaog ist, dann: #pragma vector = TIMER0_B1_VECTOR >> __interrupt void TIMER0_B1_ISR (void) wobei ich auch gelesen habe das man dann folgendes unterscheidet: { switch( TB0IV ) // Read interrupt vector for TB0 { case 0: // No interrupt pending { break; } case 2: // TB0CCR1 { break; } case 4: // TB0CCR2 { break; } case 6: // TB0CCR3 { break; } case 8: // TB0CCR4 { break; } case 10: // TB0CCR5 { break; } case 12: // TB0CCR6 { break; } case 14: // Overflow - TB0IFG { break; } } } wie komme ich dann in meinem beispiel auf ccr1 ohne die switch case geschichte?
fertig schrieb: > Den Rest deiner Überlegungen verstehe ich nicht. was genau ergibt keinen Sinn? dann versuche ich es zu erklären, vllt habe ich auch nur dummes Zeug geschrieben
nachwievor fliegt mir der string mist um die Ohren. Hatten im Unterricht diese als extern void eingeführt, liegen die Sachen in der Header-Datei oder in einer anderen Quelldatei, z.B. ein seperates C-Programm?
Antonowan225 schrieb: > wie komme ich dann in meinem beispiel auf ccr1 ohne die switch case > geschichte? Gar nicht, denn fertig schrieb: > • TBIV interrupt vector for all other CCIFG flags and TBIFG fertig schrieb: > TIMER0_B1_VECTOR shared den > Rest, siehe TBxIV Register auf Seite 505 oder im Header io430f5529.h Steht alles sehr gut erklärt im Family User Guide. Antonowan225 schrieb: > dann versuche ich es zu erklären Nö, du machst dein Ding und ich muss (will) davon nicht viel wissen.
Antonowan225 schrieb: > nachwievor fliegt mir der string mist um die Ohren. > > Hatten im Unterricht diese als extern void eingeführt, liegen die Sachen > in der Header-Datei oder in einer anderen Quelldatei, z.B. ein seperates > C-Programm? Es wird allerhöchste Zeit mit strukturiertem Arbeiten zu beginne. Schnapp Dir passende Literatur, Tutorials, Datenblätter etc. - Vorschläge dazu ga es ja genug - und lerne die Grundlagen. Die meisten DEiner Probleme werden sich in Luft auflösen. Wenn Dir das allerdings zu viel ist, dann laß es einfach sein - es wird nichts werden.
so hier das Programm, habe noch folgende Probleme: PROblem Nummer eins: Antonowan225 schrieb: > Das Problem, welches ich nicht behoben bekomme, ist TX_String und > TX_Byte zur aUSGABE AM pc. Vllt hat jmd idee. vielen Dank Problem Nummer zwei: Antonowan225 schrieb: > so in etwa habe ich mir den Moduiwechsel überlegt.Ich könnte mir > vorstellen, dass folgende Probleme auftreten: > > 1. Niemals drückt jemand beide Taster exakt gleich, damit wäre man > sofort in den Routinen für System An/aus oder > Pulsbreite/Frequenzänderung. Was kann man dagegen tun? > > 2. Die ISR der Ports würden aufgerufen werden, dort müsste ich jeweils > die beiden Taster gegeneinander negieren um die ISR zu beenden. Scheint > mir nicht grade geschickt. > > 3. Ich habe keinen Timer mehr zur Verfügung, würde Drücken der beiden > Taster gerne auf 2 Sekunden verpflichten. Den Timer_A0 habe ich bereits > für 2 Sekunden ausgelegt, doch dessen Funktion ist für > Pulsweitenänderung/ Frequenzänderung gedacht. Kann ich über einen > anderen Kanal den Timer auch für den Modiwechsel nutzen? wenn ja, wie > müsste ich das angehen? > > FÜr die Antworten bedanke ich mich schon jetzt Problem Nummer drei: die geschichte mit ccr1 für ISR mit timer B0 Problem Nummer vier: Antonowan225 schrieb: > würde gerne unabhängig vom eingestellten Modus die Ausgabe von Puls oder > Frequenzwobbel an dem gleichen Pin. So wie die letzte Version des > Programm ist (s.o.), wird sowohl an der LED als auch am PIN 7.4 das > signal ausgegeben... funktioniert aber nur für den TIMER B0, also für > den Pulswobbel. Für den Timer A1 wären, so wie ich das verstanden habe, > nur der Pin 2.0 verfügbar. > > Was würdet ihr dazu machen? Problem Nummer 5: Wo ist meine Header-Datei =) Das war es schon im Großen und Ganzen. Sollte jemand sehen, dass der Code Probleme bereitet, gerne Melden. Ich möchte jedem ganz herzlich für seine Hilfe danken, ist nicht selbstverständlich! MFG
Zeno schrieb: > Es wird allerhöchste Zeit mit strukturiertem Arbeiten zu beginne. > Schnapp Dir passende Literatur, Tutorials, Datenblätter etc. - > Vorschläge dazu ga es ja genug - und lerne die Grundlagen. Die meisten > DEiner Probleme werden sich in Luft auflösen. > Wenn Dir das allerdings zu viel ist, dann laß es einfach sein - es wird > nichts werden. Ja natürlich, bin unbedarft an die Sache rangegangen. Werde die Theorie weiter vertiefen.
Antonowan225 schrieb: > habe jetzt schon in einigen Codebeispielen gesehen, dass für den Timer B > anstatt CCR1 CCR2 genommen wird, umd die Periodendauer festzulegen. > WOran liegt das? Der Ausgang TB0.1 geht auf einen Pin, der auf dem LaunchPad nicht mit dem BoosterPack-Header verbunden ist.
Antonowan225 schrieb: > Das Problem, welches ich nicht behoben bekomme, ist TX_String und > TX_Byte zur aUSGABE AM pc. Innerhalb eines Interrupt-Handlers keine Warteschleifen! Wenn du wirklich in einem Interrupt-Handler etwas ausgeben willst, dann musst du den String irgendwo zwischenspeichern (FIFO, typischerweise ein Ringpuffer) und die Bytes asynchron ausgeben (im UART-Interrupt-Handler). Antonowan225 schrieb: > Ich habe keinen Timer mehr zur Verfügung Es gäbe da noch den WDT, aber du könntest auch einen Timer für mehrere Aufgaben benutzen.
:
Bearbeitet durch User
Clemens L. schrieb: > Es gäbe da noch den WDT, aber du könntest auch einen Timer für mehrere > Aufgaben benutzen. das würde ich über die Capture Compare Register realisieren? Clemens L. schrieb: > Der Ausgang TB0.1 geht auf einen Pin, der auf dem LaunchPad nicht mit > dem BoosterPack-Header verbunden ist. also funktioniert es so garnicht, wie ich es momentan Programmiert habe? Habe im Code mit CCR1 gearbeitet Clemens L. schrieb: > Innerhalb eines Interrupt-Handlers keine Warteschleifen! wo habe ich denn Warteschleifen? Vielen Dank für deinen Beitrag Clemens. Warst schon in der Vergangenheit eine gr0ße Hilfe
Guten Abend ich habe meinen Code nochmal überarbeitet und kommentiert, er müsste jetzt um einiges einfacher zu vertsteh sein. VLLt könnt ihr eure Meinungen zu den Punkten sagen. Grüße Antonowan225 schrieb: > PROblem Nummer eins: > > Antonowan225 schrieb: >> Das Problem, welches ich nicht behoben bekomme, ist TX_String und >> TX_Byte zur aUSGABE AM pc. Vllt hat jmd idee. vielen Dank > > Problem Nummer zwei: > > Antonowan225 schrieb: >> so in etwa habe ich mir den Moduiwechsel überlegt.Ich könnte mir >> vorstellen, dass folgende Probleme auftreten: >> >> 1. Niemals drückt jemand beide Taster exakt gleich, damit wäre man >> sofort in den Routinen für System An/aus oder >> Pulsbreite/Frequenzänderung. Was kann man dagegen tun? >> >> 2. Die ISR der Ports würden aufgerufen werden, dort müsste ich jeweils >> die beiden Taster gegeneinander negieren um die ISR zu beenden. Scheint >> mir nicht grade geschickt. >> >> 3. Ich habe keinen Timer mehr zur Verfügung, würde Drücken der beiden >> Taster gerne auf 2 Sekunden verpflichten. Den Timer_A0 habe ich bereits >> für 2 Sekunden ausgelegt, doch dessen Funktion ist für >> Pulsweitenänderung/ Frequenzänderung gedacht. Kann ich über einen >> anderen Kanal den Timer auch für den Modiwechsel nutzen? wenn ja, wie >> müsste ich das angehen? >> >> FÜr die Antworten bedanke ich mich schon jetzt > > Problem Nummer drei: die geschichte mit ccr1 für ISR mit timer B0 > > Problem Nummer vier: usw...
Antonowan225 schrieb: > ich habe meinen Code nochmal überarbeitet und kommentiert Funktioniert er denn jetzt? mfg Klaus
Nein, die drei extern voids funktionieren noch nicht...weiß nicht was ich da machen kann. Außerdem habe ich die beiden Taster noch nicht in den ISR negiert. Außerdem die Frage: wenn ich nicht exakt gleichzeitig beide Taster drücken würde, ist doch sofort die jeweilige ISR aktiviert...Ziel war ja ein Modiwechsel bei gleichzeitigem Drücken. Habe auch noch nicht die ISR von Timer B0 für ccr1 korrekt initislisiert Grüße
Clemens L. schrieb: > Antonowan225 schrieb: >> habe jetzt schon in einigen Codebeispielen gesehen, dass für den Timer B >> anstatt CCR1 CCR2 genommen wird, umd die Periodendauer festzulegen. >> WOran liegt das? > > Der Ausgang TB0.1 geht auf einen Pin, der auf dem LaunchPad nicht mit > dem BoosterPack-Header verbunden ist. ich habe daraus jetzt folgendes mitgenommen: - Der Pegel ist bis CCR2 high. danach low - Switch case für ISR. Meine unsicherheit: gehöft bei switch der Zusatz _TBCCR2 dazu oder wird in die Klammer einfacher TB0IV geschrieben. In den Codebeispielen ist es ohne Zusatz, jedoch hatte fertig oben folgendes geschrieben: fertig schrieb: > Also, der TIMER0_B0_VECTOR gilt für CCR0 und TIMER0_B1_VECTOR shared den > Rest, siehe TBxIV Register auf Seite 505 oder im Header io430f5529.h: > /* TB0IV Definitions */ > #define TB0IV_NONE (0x0000u) /* No Interrupt pending */ > #define TB0IV_TBCCR1 (0x0002u) /* TB0CCR1_CCIFG */ > #define TB0IV_TBCCR2 (0x0004u) /* TB0CCR2_CCIFG */ hier der Code dazu: //void Pulswobbel (void) #pragma vector = TIMER0_B1_VECTOR __interrupt void TIMER0_B1_ISR (void) { switch (TB0IV_TBCCR2 ) { case 4: { if (PWM_Aktuell < PWM_Max && PWM_Dir == 1) { PWM_Aktuell += PWM_Step; } else if(PWM_Aktuell > PWM_Max && PWM_Dir == 1) { PWM_Aktuell -= PWM_Step; PWM_Dir = 0; } if (PWM_Aktuell > PWM_Min && PWM_Dir == 0) { PWM_Aktuell -= PWM_Step; } else if(PWM_Aktuell < PWM_Min && PWM_Dir == 0) { PWM_Aktuell += PWM_Step; PWM_Dir = 0; } break; } } }
Antonowan225 schrieb: > - Switch case für ISR. Meine unsicherheit: gehöft bei switch der Zusatz > _TBCCR2 dazu oder wird in die Klammer einfacher TB0IV geschrieben. Jetzt bin ich voll bei Zeno. ... switch(TB0IV) { ... case TB0IV_TBCCR1 : ... break; case TB0IV_TBCCR2 : ... break; ... }
Antonowan225 schrieb: > Clemens L. schrieb: >> du könntest auch einen Timer für mehrere Aufgaben benutzen. > > das würde ich über die Capture Compare Register realisieren? Die Periode des Timers selbst bleibt gleich. Entweder 1) du benutzt den selben Interrupt-Handler für beides (und wenn eine Aufgabe nicht so oft wie die andere ausgeführt werden soll, muss der Handler mitzählen und sie nur jedes x-te Mal ausführen), oder 2) du benutzt zwei CCRs, und für eine kleinere Periode als die des Timers musst du das CCR im Interrupt-Handler anpassen (TAxCCRy += periode). Wenn dein Interrupt-Handler durch andere Interrupt-Handler zu lange verzögert wird, funktioniert das nicht; du musst also dafür sorgen, das alle Interrupt-Handler eine kurze Ausführungszeit haben. >> Der Ausgang TB0.1 geht auf einen Pin, der auf dem LaunchPad nicht mit >> dem BoosterPack-Header verbunden ist. > > also funktioniert es so garnicht, wie ich es momentan Programmiert habe? Willst du den internen Interrupt benutzen, oder das Signal am Pin abgreifen? > wo habe ich denn Warteschleifen?
1 | while(UCA1IFG & UCTXIFG); |
2 | while (!(UCA0IFG & UCTXIFG)); |
Clemens L. schrieb: > 2) du benutzt zwei CCRs, und für eine kleinere Periode als die des > Timers musst du das CCR im Interrupt-Handler anpassen (TAxCCRy += > periode). Wenn dein Interrupt-Handler durch andere Interrupt-Handler zu > lange verzögert wird, funktioniert das nicht; du musst also dafür > sorgen, das alle Interrupt-Handler eine kurze Ausführungszeit haben. danke für deinen hilfreichen Hinweis Clemens L. schrieb: > Willst du den internen Interrupt benutzen, oder das Signal am Pin > abgreifen? Signal am Pin abgreifen
Clemens L. schrieb: >> habe jetzt schon in einigen Codebeispielen gesehen, dass für den Timer B >> anstatt CCR1 CCR2 genommen wird, umd die Periodendauer festzulegen. >> WOran liegt das? > > Der Ausgang TB0.1 geht auf einen Pin, der auf dem LaunchPad nicht mit > dem BoosterPack-Header verbunden ist. da ich nicht weiß, wo du die Infos her hast (im User Guide nichts gefunden), die Frage: gilt das auch für den Timer A1?
so, habe über einen Terminalprogramm überprüft, was der MSP so ausspuckt. Habe ja keinen Oszi. Grundsätzlich passt alles soweit. Also die strings passen zu dem, was ich drücke :D. Das einzige Problem: Die LED1 an P1.0 leuchtet von der ersten Sekunde an nicht. Egal was ich mache. Ist jemand so lieb und guckt nach, ob ich etwas übersehen habe? Also die Initialisierung der Ports scheint mir eigentlich korrekt zu sein. WOllte eine Brücke zwischen Pin 7.4 TB0 und LED an 1.0 programmieren. Die Initialisierung habe ich in der subroutine system_start durchgeführt.
Antonowan225 schrieb: >> Der Ausgang TB0.1 geht auf einen Pin, der auf dem LaunchPad nicht mit >> dem BoosterPack-Header verbunden ist. > > da ich nicht weiß, wo du die Infos her hast (im User Guide nichts > gefunden) Seite 26.
Antonowan225 schrieb: > Die LED1 an P1.0 leuchtet von der ersten Sekunde an nicht. Egal was ich > mache. Was machst du denn? P1DIR initialisieren und P1OUT schreiben jedenfalls nicht ...
Clemens L. schrieb: > Antonowan225 schrieb: >>> Der Ausgang TB0.1 geht auf einen Pin, der auf dem LaunchPad nicht mit >>> dem BoosterPack-Header verbunden ist. >> >> da ich nicht weiß, wo du die Infos her hast (im User Guide nichts >> gefunden) > > Seite 26. also 0.1 oder 0.2 oder 0.3 unsw bedeutet Timernummer.Vectornummer. jetzt verstehe ich es. tut mir echt leid, dass da meine Grundlagen nicht vertieft sind. danke auf jeden Fall :)
Clemens L. schrieb: > Was machst du denn? P1DIR initialisieren und P1OUT schreiben jedenfalls > nicht hatte die LED nicht im P1xxx-Register konfiguriert, sondern im P7 Register. Grund: der Ausgangspin von TimerB0 Vector CCR2 liegt bei 7.4. Wollte dass das Signal des Timers sowohl auf den Pin als auch auf die LED bei 1.0 geht.
Antonowan225 schrieb: > Clemens L. schrieb: >> Was machst du denn? P1DIR initialisieren und P1OUT schreiben jedenfalls >> nicht > > hatte die LED nicht im P1xxx-Register konfiguriert, sondern im P7 > Register. Grund: der Ausgangspin von TimerB0 Vector CCR2 liegt bei 7.4. > Wollte dass das Signal des Timers sowohl auf den Pin als auch auf die > LED bei 1.0 geht. hat jemand eine Idee?
Antonowan225 schrieb: > der Ausgangspin von TimerB0 Vector CCR2 liegt bei 7.4. > Wollte dass das Signal des Timers sowohl auf den Pin als auch auf die > LED bei 1.0 geht. Die möglichen Konfigurationen von P1.0 findest du in Tabelle 6-46 im Datenblatt. Um die LED an P1.0 mit dem Ausgang P7.4 zu steuern, musst du zusätzliche Hardware installieren.
Clemens L. schrieb: > Um die LED an P1.0 mit dem Ausgang P7.4 zu steuern, musst du zusätzliche > Hardware installieren. ofeensichtlich nicht. habe das mal an einem anderen Programm getestet. Da hat der Timer gearbeitet, so wie er jetzt grade in meinem Programm konfiguriert ist. Also nehme ich an das Fehler in meiner Programmlogik liegt
ich habe das Datenbaltt vom msp430f5529 nicht vorliegen. nur den User Guide von der x5xx Family. deswegen habe ich die Seiten auch nie gefunden
Antonowan225 schrieb: > Clemens L. schrieb: >> Um die LED an P1.0 mit dem Ausgang P7.4 zu steuern, musst du zusätzliche >> Hardware installieren. > > ofeensichtlich nicht. habe das mal an einem anderen Programm getestet. Und das hat nicht zufällig einen Interrupt-Handler, der P1OUT.BIT0 schreibt? > ich habe das Datenbaltt vom msp430f5529 nicht vorliegen http://www.ti.com/lit/gpn/MSP430F5529
also habe mal mit meinem lehrer gesprochen, er meinte das Programm wäre zu komplex für die Aufgabe. Er hat mir also vorgeschlagen, anstatt der Fehlersuche ein neuen Lösungsansatz zu verfolgen. Echt schade, denn ich weiß jetzt nicht wo mein Fehler liegt. Das wäre unter Umständen ein guter Lerneffekt gewesen
hey, bin von den Toten auferstanden. so meinen neuen Ansatz könnt ihr euch im Anhang angucken. (noch keine ports initialisiert und nichts) Habe zwei Arrays deklariert, eins für die Frequenz und eins für die Pulsbreite. Die Pulsbreite soll gleich bleiben, d.h. immer halb so groß wie die Frequenz. Mit dem Timer A0 generiere ich eine Wechselzeit, nach derer Ablauf ich die die Frequenz und Pulsbreite ändere. damit es keinen Überlauf gibt, habe ich im Register TB0CL0 bei Load Events CLLD_1 gesetzt. ( So wie ich das dem Datenbaltt entnehme, wird dem Timer die neuen Werte für CCR0 und CCR2 erst dann übergeben, wenn der Timer wieder bei dem wert null ist) Meine Frage lautet: macht es Sinn, die Wechselzeit auf 2000 Hz zu setzten. Ich möchte nach jeder Periode (Rechtecksignal, Outmode 7) die nächst höhere/kleinere (in Abhängigkeit von Wobbel_Dir) einstellen. also müsste die wechselzeit größergleich der größten Wobbelfrequenz entsprechen (2000Hz). Liegt die Wobbelfrequenz bei 100 Hz, wäre die wechselzeit mit 2000 Hz schon 20 mal abgelfaufen. Wird dann trzd die nächste Periode aufgerufen, oder die die 20 größen davon entfernt ist? Vieln Dank im Voraus MfG
1 | int main( void ) |
2 | {
|
3 | // Stop watchdog timer to prevent time out reset
|
4 | WDTCTL = WDTPW + WDTHOLD; |
5 | |
6 | TimerA0 (); |
7 | TimeerB0 (); |
8 | |
9 | _BIS_SR(GIE); |
10 | }
|
Was passiert nach main? Ich hätte zur Sicherheit ein while(1){}; eingebaut.
Bernd schrieb: > int main( void ) > { > // Stop watchdog timer to prevent time out reset > WDTCTL = WDTPW + WDTHOLD; > > TimerA0 (); > TimeerB0 (); > > _BIS_SR(GIE); > } > Was passiert nach main? > Ich hätte zur Sicherheit ein while(1){}; eingebaut. vergiss bitte main etc. wie gesagt, es sind noch nichteinmal die Ports initialisiert. mein Stück Kot...Code... sollte nur die Grundidee des wobbelgenerators verdeutlichen. Die Frage zur Wechselzeit sollte in diesem Kontext beantwortbar sein. Bedanke mich schon jetzt für Hilfe
also nochmal mit anderen worten: habe die Sachen BEWUSST weggelassen, um das Wesentliche übersichtlich darzustellen...
Guten Abend habe euch das komplette Programm einschließlich der asm datei angehängt. Die asm datei wird für die extern voids benötigt. Nachwievor habe ich die Frage zur Wechselzeit. Außerdem die Frage: ich bekomme Fehlermeldungen, so wie ich die beiden Arrays deklariert habe. Hat jmd zufällig eine Ahnung? Über einer Antwort würde ich mich sehr freuen. MfG
Servus finde schade, dass sich bis jetzt niemand zu meinem Problem geäußert hat. MfG
Antonowan225 schrieb: > Die asm datei wird für die extern voids benötigt. Warum überhaupt Assembler? Antonowan225 schrieb: > ich bekomme Fehlermeldungen, so wie ich die beiden Arrays deklariert habe. Die ganzen Zuweisungen (PBreite [1] = Freq [1] >> 1;) sind ausführbarer Code und müssen in irgendeine Funktion.
Clemens L. schrieb: > Warum überhaupt Assembler? die Datei habe ich vom lehrer bekommen, habe damit soweit nichts am Hut. Habe das Programm zum laufen bekommen, ob was Sinnvolles rauskommt, musss ich noch mit einem Oszi überprüfen. Müsste dazu aber bis nächste Woche warten, hat jmd eins griffbereit und könnte einmal kurz nachgucken?
Hallo liebes Forum, ich habe schon lange nicht mehr von mir höhren lassen. Ich habe zwischenzeitlich das Programm weiterentwickelt, beispielsweise frage ich die taster über Timer-ISR ab. Außerdem habe ich mit Breakpoints etc nachvollzogen, dass das Programm zuverlässig arbeitet. Das Einzige, was jetzt noch fehlen würde, ist das aufgeziechnet Signal. D.h., dass mit einem Oszilloskop am P7.4. das Signal abgegriffen wird. Leider hat die Schule zu, das labor wird noch lange geschlossen bleiben. Deswegen die Frage, ob jemand so gütig ist, einmal kurz für das Signal zu messen. Dafür wäre ich wirklich dankbar. Lasst von euch hören! MfG Antonow
Antonowan225 schrieb: > ich habe schon lange nicht mehr von mir höhren lassen Stimmt nicht, du warst doch unter diversen anderen Namen hier und hast in n (n > 1) Threads keine Tipps angenommen. Vielleicht haben die freundlichen Helfer einfach keine Lust mehr, wenn ihnen nicht zugehört wird.
fertig schrieb: > hast > in n (n > 1) Threads keine Tipps angenommen. beispiel? fertig schrieb: > keine Lust mehr, wenn ihnen nicht zugehört > wird. einen Grund findet man doch immer, wenn man nicht möchte...
Antonowan225 schrieb: > Grund findet man doch immer Du hast es immer noch nicht verstanden: Niemand muss sich darum bewerben, dir zu helfen. Aber du solltest dafür sorgen, dass sie Helfer Spaß daran haben, dir zu helfen.
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.