STM32F100C4 Unerklärtes Problem. Brauche Ideen

OP #3791663
Lesenswert?

Hallo zusammen,

Ich sitze vor einem großen Problem.
Und zwar möchte ich Pulslängen-codierte Daten aus einem STM32F1 senden.
Dazu nutze ich den Timer1 und einen DMA, welcher den Timer befeuert.
Damit die Datenleitung im Ruhezustand auf 0 steht, wird nach dem Senden 
der Daten der Timer in den Singe-Mode versetzt und die Pulslängen-werte 
des DMA-Puffers auf 0 gesetzt. Der Timer schiebt dann noch einmal 
0-Pulse raus (also kein Puls) und stopt dann. Soweit so gut, das 
Funktioniert. Der Code ist zwar ziemlich umfangreich mittlerweile aber 
das ist ja fast schon normal.

Nun mein Problem ist, dass ich festgestellt habe, dass die Datenleitung 
hin und wieder (etwa in 50% der Fälle) nach dem Stop des Timers (also 
nachdem die 0-Pulse gesendet wurde) auf high-level springt. Das sind die 
Pins PA8 und PA9 (TIM1_CH1 und TIM1_CH2).

Jetzt habe ich folgendes festgestellt und hier sehe ich nurnoch Voodoo:
In der Hauptschleife schalte ich eine LED zu debug-zwecken an und aus. 
Die LED hängt an Pin PB12. Steuere ich die LED direkt durch manipulation 
des entspechenden Bits in GPIOB->OCR gibts kein Problem.
Schalte ich sie mit "GPIOB->BRR = GPIO_Pin_12;" bzw. "GPIOB->BSRR = 
GPIO_Pin_12;" dann schaltet bei jedem 2. Zugriff auf eines der beiden 
Register meine Datenleitung nach der Datenübertragung auf highlevel.

Ganz einfach und reproduzierbar zu testen ist das folgensermaßen 
(gekürzter Code):
1
...
2
int main( void )
3
{
4
    init();
5
    GPIOB->BRR = GPIO_Pin_12;
6
    sendeDaten();
7
    // Datenleitung springt auf highlevel
8
}
1
...
2
int main( void )
3
{
4
    init();
5
    GPIOB->BRR = GPIO_Pin_12;
6
    GPIOB->BRR = GPIO_Pin_12;
7
    sendeDaten();
8
    // Datenleitung bleibt auf lowlevel
9
}

Kann mir jemand auch nur eine Idee liefern, was hier der Knoten sein 
kann?
Ich stehe langsam am Ende meiner Geduld (mein Verständnis über die 
Funktionsweise des STM ist damit seit dem Voodoo überfordert). Leider 
muss ich das Problem aber lösen, sonst gibt's haue von den Vorgesetzten.

Ich bin dankbar für jeden Rat und jede Idee.

Vielen Dank
OP #3791682
Lesenswert?

error: 'GPIO_TypeDef' has no member named 'BSRRL'

Ich bin jetzt nicht 100% sicher ob das so krorrekt gepfuscht ist aber:
1
...
2
int main( void )
3
{
4
    init();
5
    *(__IO uint16_t*)(&GPIOB->BSRR) = (uint16_t)(1 << 12);
6
    sendeDaten();
7
    // Datenleitung springt auf highlevel
8
}
1
...
2
int main( void )
3
{
4
    init();
5
    *(__IO uint16_t*)(&GPIOB->BSRR) = (uint16_t)(1 << 12);
6
    *(__IO uint16_t*)(&GPIOB->BSRR) = (uint16_t)(1 << 12);
7
    sendeDaten();
8
    // Datenleitung bleibt auf lowlevel
9
}
OP #3791769
Lesenswert?

OK, jetz fang ich gleich an zu weinen!

Wenn ich vor sendeDaten() eine gerade Anzahl an Operationen habe (auch 
__asm("NOP"); zählt) dann funktioniert es. Bei einer Ungeraden Anzahl 
funktioniert es nicht.
Also:
1
...
2
int main( void )
3
{
4
    init();
5
    while(1)
6
    {
7
        __asm("NOP");
8
        sendeDaten();
9
        warteBisTimerSteht(); // Daten vollständig gesendet
10
        // Datenleitung springt IMMER auf highlevel (nicht nur jedes 2. mal)
11
    }
12
}
1
...
2
int main( void )
3
{
4
    init();
5
    while(1)
6
    {
7
        __asm("NOP");
8
        __asm("NOP");
9
        sendeDaten();
10
        warteBisTimerSteht(); // Daten vollständig gesendet
11
        // Datenleitung bleibt IMMER auf lowlevel
12
    }
13
}

Welcher Quälgeist macht mir hier das leben schwer???

PS: eine beliebige Anzahl an __asm("NOP") in die sendeDaten()-Funktion 
ziehen ändert nichts !!
PPS: KORREKTUR! ein __asm("NOP") am ENDE der sendeDaten()-Funktion 
ändert das Ergebnis ?!
OP #3792153
Lesenswert?

Haha, so eine sch... schöne Gelegenheit zeit zu verschwenden.

Der Fehler war:
STM hat in der core_cm3.h einen Fehler der den Compiler eine 
Fehlermeldung schmeißen lässt wenn die Optimierung aktiv ist. Daher 
wurde die wohl einfach ausgeschaltet und das hat zur folge, das Code, 
der in einem Projekt wunderbar läuft, im neuen zu langsam ist und der 
Prozessor überrennt sich selbst mit Interrupts. Dass es dann mit einem 
Befehl mehr oder weniger plötzlich mal geht und mal nicht 
(reproduzierbar) ist mir zwar noch nicht 100% logisch aber man muss ja 
auch nicht alles verstehen.

Trotzdem Danke an alle, die mit gegrübelt haben.
OP #3792189
Lesenswert?

Ich hätte euch den gesamten code zeigen können, aber dass da ein 
Interrupt überläuft weil der Compiler nicht optimiert hätte keiner 
gesehen.
Und es ist kein Design-Fehler, sondern hart am Limit kalkuliert. Klar 
gibt's auch größere STM als den STM32F100 mit nur 24MHz und minimaler 
Ausstattung (im vergleich zu den großen Brüdern).
Gast #3792259
Lesenswert?

>Der Fehler war:
>STM hat in der core_cm3.h einen Fehler der den Compiler eine
>Fehlermeldung schmeißen lässt wenn die Optimierung aktiv ist.

An welcher Stelle? Das Problem hatte ich noch nie.

>Und es ist kein Design-Fehler, sondern hart am Limit kalkuliert.

Du hast Mist programmiert. Das wird das eigentliche Problem sein.
OP #3792313
Lesenswert?

OK, ich muss mich leider korrigieren. Ich weiß nicht wer den Fehler im 
Code gemacht hat. CooCox, STM, jemand anderes. Ich beschäftige mich aber 
auch nicht weiter damit, da ich noch mehr zu tun habe und für solche 
dinge nicht bezahlt werde. Primär will ich nur meine Anschuldigung 
zurück ziehen. Der Fehler wird dort
http://www.coocox.org/forum/topic.php?id=943
beschrieben und beruht sogar noch auf einer alten Version von dem 
CMSIS-Zeug, das ich eigentlich zu meiden versuche.
Das Optimierungen abschalten ist allerdings so oder so ein hausgemachtes 
Problem.
In diesem Sinne ist der ganze Thread für mich jetzt abgeschlossen.
Tut mir leid eure Zeit beansprucht zu haben, und vielen herzlichen Dank 
noch einmal für eure Hilfe.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren