hallo,
für einen Beleg an der Uni muss ich einen code für einen µC schreiben.
Der ist auch fertig und funktioniert in den vom Prof. geforderten
Paramtern auch ganz gut. Allerdings ergibt sich ab und zu (für mich
nicht nachvollziehbaren Situationen) das der µC nicht mehr reagiert. Ich
muss dann erst die Reset taste auf dem evalboard drücken und ihn neu
Werte übergeben.
Der µC ist ein MSP430g2553 auf dem TI Evalboard Launchpad EXP430G2
Aufgabe des Code:
per Uart bekommt er 3 Byte um eine Frequenz , Tastverhältnis und eine
Slewrate einustellen.
Genutz werden sollte ein timer.
Das Rechtecksignal wird am Port P2 + P1.7 und P1.6 ausgegeben. Danach
folgt ein R2R Netzwerk.
Den Fehler, dass der code plötzlich nicht mehr funktioniert und kein
Rechtecksignal mehr ausgibt kann ich nicht nachvollziehen. Vielleicht
kann jemand von euch drüber schauen.
Meine Vermutung war Anfangs, das der timer interupt und der UART
interupt sich in die Quere kommen. Ich habe versucht bei Sprung in die
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void) den timerinterupt mittels
CCTL0 &= ~ CCIE auszuschalten und vor dem verlassen wieder
einzuschalten, aber leider bringt das nicht das gewünschte Ergebniss.
Kann mir bitte jemand helfen, was habe ich falsch gemacht?
Ps. ich hoffe keine Informationen vergessen zu haben und wenn doch bitte
bescheid sagen.
gruß Sören,
Wenn ich mich recht erinnere, geht der Hardware-Debugger auf dem
Launchpad ganz OK mit mspdebug, wenn auch ohne Komfort? Dann einfach
Applikation aus dem Debugger starten, Absturz provozieren, Im Debugger
reinbreaken und gucken, was los ist.
hallo,
ja du errinerst dich richtig.
Das habe ich schon versucht. Wenn der Fehler auftrat, hängt er immer an
der geschweiften zugehenden Klammer nach __bis_SR_register(LPM0_bits +
GIE); (ende Main)
Da erhebt sich sowieso die Frage, was dein Code macht, wenn er jemals
aus main rauskommt. NOrmalerweise sieht ein main ja so aus
1
intmain()
2
{
3
.....
4
5
while(1){
6
Hauptschleife,HauptlogikdesProgramms
7
}
8
}
und ja, das ist bewusst eine Endlosschleife. Wenn der µC erst mal die
Hauptschleife erreicht hat, dann verlässt er die nie wieder. Wenn es,
wie bei dir, keine Aktionen da drinn gibt, dann reduziert sich das zu
1
intmain()
2
{
3
....
4
5
while(1){
6
;
7
}
8
}
also zu einer leeren Endlosschleife. Aber aus main raus lässt man den µC
nicht mehr.
Hast du schon mal in die Richtung überlegt, was passiert, wenn es bei
der Übertragung zu Fehlern kommt und die Synchronisierung der 3 Bytes
verloren geht? Sprich: wenn der µC fälschlicherweise das Slew-Rate Byte
als eines der Freuqenzbytes auffasst oder vice versa? Dass du dich da
komplett auf die richtige Reihenfolge verlässt, schmeckt mir ehrlich
gesagt gar nicht. Da braucht nur der Sender zuerst eingeschaltet zu
werden und bereits zu senden zu beginnen noch ehe der Empfänger bereit
ist, und schon kommt da alles durcheinander.
in der Main brauche ich keine while(1).
mit __bis_SR_register(LPM0_bits + GIE); geht er in den low power modus
und "erwacht" aus diesem sobald ein interupt kommt.
die 3 Bytes sende ich per PC,
Was meinst du mit:
"Dass du dich da komplett auf die richtige Reihenfolge verlässt"
StudentSören schrieb:> geht er in den low power modus und "erwacht" aus diesem sobald ein> interupt kommt.
Und was passiert nach dem Verlassen der Interrupt-Routine?
StudentSören schrieb:> in der Main brauche ich keine while(1).> mit __bis_SR_register(LPM0_bits + GIE); geht er in den low power modus> und "erwacht" aus diesem sobald ein interupt kommt.
OK. Da kenn ich den MSP zu wenig.
Ich hätt trotzdem eine Endlossschleife reingebaut.
> die 3 Bytes sende ich per PC,>> Was meinst du mit:> "Dass du dich da komplett auf die richtige Reihenfolge verlässt"
Rufus Τ. Firefly schrieb:> Und was passiert nach dem Verlassen der Interrupt-Routine?
Das Status Register SR, das beim Auftreten eines Interrupts auf dem
Stack gesichert wird bevor es zurückgesetzt wird um das Abarbeiten der
Interrupt-Routine zu ermöglichen und Unterbrechungen durch weiterer
Interrupts zu verhindern, wird beim Verlassen der Interrupt-Routine vom
Stack wiederhergestellt, der Controller ist wieder im low power modus
und wartet auf den nächsten Interrup.
StudentSören schrieb:> mit __bis_SR_register(LPM0_bits + GIE); geht er in den low power modus> und "erwacht" aus diesem sobald ein interupt kommt.
Ich entwickele Programme grundsätzlich erstmal ohne allen
Stromspar-Schrunz.
Und erst wenn es perfekt läuft und wenn auch wirklich Batteriebetrieb
gefordert ist, baue ich das Stromsparen ein.
Am Netzteil merkt kein Schwein, ob der MC nun 1mA oder 2mA zieht. Man
muß keine Sachen programmieren, die keinen merkbaren Effekt haben.
Die Standard-Beispiele von TI sind alle so aufgebaut, dass der MSP430
statt einem while(1)-Loop im LPM ist. Dass der TE sich daran gehalten
hat, ist ihm kaum vorzuwerfen.
In der ISR ist das GIE-Bit generell deaktiviert. CCTL0 &= ~ CCIE ist
damit sinnlos, weil während der ISR keine andere ISR aufgerufen wird.
Falls ein weiterer Interrupt während der Ausführung aktiv wird, wird
dieser erst nach Beenden des laufenden Interrupts abgearbeitet.
Aber was um Himmelswillen soll dieser Code in der ISR?
1
for (i = 255;i>=0;i = i-iSRV)
2
{
3
P2OUT = i;
4
}
Soll das ein Delay sein? In der ISR? Ich bin mir nicht ganz sicher, was
das bewirken soll (anscheinend die Slewrate beeinflussen), aber gefühlt
wärst du mit einer Änderung von CCR0 besser bedient.
Ggf. dauert das auch so lange, dass in der Zwischenzeit der RX-Interrupt
verloren geht. Dann hast du den Datensalat, von dem ja schon die Rede
war.
Max
Kann mir einer die Aufgabenstellung übersetzen?
Frequenz und Tastverhältnis bekomme ich noch zusammen, einfach PWM. Aber
was soll Slewrate dabei bedeuten?
Was ist denn jetzt?
@Student...
Kannst du mal die Aufgaben Formulierung des Lehrers Posten. Wie soll das
Ausgangssignal aussehen?
So was http://b2b.cbsimg.net/blogs/digitalsignal.JPG ?
StudentSören schrieb:> Was meinst du mit:> "Dass du dich da komplett auf die richtige Reihenfolge verlässt"
Es gibt kein Protokoll, an dem der Empfänger erkennen kann, welches das
erste Byte ist.
Es reicht z.B. schon aus, daß der Empfänger irgendeine Schaltflanke
(Einschalten des PC) als 1. Byte annimmt und schon sind alle folgenden
Bytes an der falschen Stelle.