STM32F103C8, einfacher LED Blinkerei

Gast #4900384
Hallo zusammen! Bislang habe ich eigentlich nur uCs á la 328p 
programmiert... und taste mich gerade vorsichtig an einen ARM M3 heran. 
Ich habe mir ein Board und einen Programmer zugelegt (siehe Anhang). 
Nachdem ich mit CooCox diverse Probleme hatte und noch immer habe, bin 
ich auf EmBitz umgestiegen. Hier funktioniert soweit scheinbar alles 
einwandfrei. Zum flashen nutze ich CoFlash von ST (funktioniert wohl 
auch einwandfrei). Nun wollte ich einfach mal eine LED zum blinken 
bringen... doch nun verhält sich der Code recht seltsam und ich weiß 
nicht wieso?!

#include "stm32f10x.h"

int main(void)
{
  unsigned long c = 0;

  SystemInit();

  GPIO_InitTypeDef  GPIO_InitStructure;

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

    while(1)
    {
      GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_SET);
      for(c=0;c<100000;c++);

      GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_RESET);
      for(c=0;c<100000;c++);
    }
}

Wenn man die for-Schleifen wie oben gezeigt bis 100000 zählen läßt, ist 
die LED aus! Zählen sie nur bis 1000, leuchtet die LED minimal. Bei 100 
mit etwa 50% Intensität. Bei 10 und 1 hell!

Wieso? Sollte sie nicht immer langsamer blinken, desto größer die Grenze 
gewählt wird? Und noch mal... es blinkt NICHTS! Es verhält sich ehr wir 
ein DAC... ???
Angehängte Dateien:
Moderator (Firma: Titel) Persönliche Seite #4900390
Welche Optimierungsstufe hast du eingestellt?
Ein halbwegs schlauer Compiler optimiert dir die Schleifen einfach raus, 
weil sie am Programmverlauf an sich nichts, sondern nur die 
Programmdauer ändern. Und das primäre Ziel ist eine möglichst kurze 
Programmausführungszeit bei geringem Speicherbedarf.
Gast #4900406
ordne es anders an:

    while(1)
    {

      for(c=0;c<100000;c++) GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_SET);

      for(c=0;c<100000;c++) GPIO_WriteBit(GPIOC, GPIO_Pin_13, 
Bit_RESET);

    }
Moderator (Firma: Titel) Persönliche Seite #4900410
GG schrieb:
> Bullseye!!! :D
Naja, blind geworfen... ;-)

> Die Optimierung Stand auf Stufe 2. Bei -O0 läuft alles wie gewünscht!
Es ist übrigens eine gute Idee, hin- und wieder mal die 
Optimierungsstrategie umzuschalten und zu schauen, ob das Design noch 
"läuft". Sonst erlebt man evtl. beim nächsten Update mit einer neuen 
Compilerversion eine unliebsame Überraschung.
Gast #4900420
Ok, wird gemacht. Dennoch verstehe ich nicht, was da "optimiert" wurde. 
Selbst wenn dem Compiler die for-Schleifen unsinnig erscheinen und er 
diese einfach entfernt hat, hätte die LED unabhängig vom eingestellten 
Wert immer gleich "leuchten" müssen... ???
Moderator (Firma: Titel) Persönliche Seite #4900445
2cents schrieb:
> dann sollte es mit voller Optimierung auch wieder laufen.
Dann sollte man zumindest das c vorher noch zur globalen Variablen 
machen. Denn c ist innerhalb der main-Routine definiert, deshalb 
kann es sich gar nicht (z.B. durch einen Interrupt) von ausserhalb 
ändern. Das weiß der Compiler auch.

GG schrieb:
> Ok, wird gemacht. Dennoch verstehe ich nicht, was da "optimiert" wurde.
Ich sehe mir da immmer das erzeugte Compilat an. Man lernst mit solchen 
Dreizeilern seinen Compiler ganz gut kennen...
Gast #4901377
Delay über Dummy-Operationen war schon vor 30 Jahren Unsinn.

Damals(tm) hatten DOS-Rechner tatsächlich einen Turbo-Knopf, mit dem man 
von 8MHz auf höhere Taktung gehen konnte, für Anwendungen. Weil viele 
Spieleprogrammierer genau diese Methode für die Warteroutinen genutzt 
haben.
(Firma: keine) #4901397
Nop schrieb:
> Delay über Dummy-Operationen war schon vor 30 Jahren Unsinn.
>
> Damals(tm) hatten DOS-Rechner tatsächlich einen Turbo-Knopf, mit dem man
> von 8MHz auf höhere Taktung gehen konnte, für Anwendungen. Weil viele
> Spieleprogrammierer genau diese Methode für die Warteroutinen genutzt
> haben.


Jim M. schrieb:
>
> Für konstantes Delay muss man Hardware Timer oder Assembler bemühen.

was genau meinst Du mit "Hardware Timern"? Externe RTCs? Jeder 
Prozessortimer leitet sich von der Taktfrequenz ab, also ist Alles, was 
im Controller passiert, bei Änderung der Taktung beeinträchtigt. Das 
passiert aber zumindestens bei Embedded relativ selten, und wenn, 
funktioniert so ziemlich nichts mehr wie erwartet.

WENN schon ein busy waiting, kann man das beim Cortex M über den DWT 
cycle counter machen, dessen Stand abhängig vom Takt immer einen 
verlässlichen Wert liefert. Da die Taktfrequenz i.d. Regel aus dem RCC 
ausgelesen werden kann, ist sogar die Mathematik relativ einfach, das 
erforderliche Delta an Taktzyklen zu einem Delay auch bei sich ändernden 
Taktfrequenzen für ein "absolutes delay" dynamisch zu berechnen, aber 
wie gesagt sind dynamisch variable Taktungen ein eher akademisches 
Problem.

Was Alles natürlich nichts daran ändert, dass busy waiting nur in 
seltenen Fällen eine Berechtigung hat.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 9 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.