Forum: Mikrocontroller und Digitale Elektronik STM32F100C4 Unerklärtes Problem. Brauche Ideen


von Leo B. (luigi)


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

von ... (Gast)


Lesenswert?

Was passiert wenn du

GPIOB->BSRRL = (1 << bit_number);

zum setzen bzw.

GPIOB->BSRRH = (1 << bit_number);

zum löschen verwendest?

von Leo B. (luigi)


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
}

von Leo B. (luigi)


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 ?!

von Dirk K. (dekoepi)


Lesenswert?

So unerklärliches Verhalten hatte ich bislang nur, wenn entweder 
Blockkondensatoren in der Schaltung gefehlt haben (bei einer Discovery 
unwahrscheinlich) oder durch "floating inputs". Pullup/Pulldown für 
deine Input-Pins ist gesetzt?

von Leo B. (luigi)


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.

von Multitask (Gast)


Lesenswert?

Leo B. schrieb:
> Der Fehler war

Das du nur Code-Fragmente gezeigt hast! Wenn die Interrupts 
'überlaufen', hast du einen Design Fehler!

von Leo B. (luigi)


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).

von holger (Gast)


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.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

holger schrieb:
>>Und es ist kein Design-Fehler, sondern hart am Limit kalkuliert.
>
> Du hast Mist programmiert. Das wird das eigentliche Problem sein.

 Harte Worte, ohne das ganze Programm gesehen zu haben.

von Leo B. (luigi)


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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.