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... ???
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.
Bullseye!!! :D Die Optimierung Stand auf Stufe 2. Bei -O0 läuft alles wie gewünscht! Perfekt! ... DANKE!
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);
}
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.
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... ???
ersetze unsigned long c = 0; durch volatile unsigned long c = 0; dann sollte es mit voller Optimierung auch wieder laufen.
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...
2cents schrieb: > ersetze > unsigned long c = 0; > durch > volatile unsigned long c = 0; > > dann sollte es mit voller Optimierung auch wieder laufen. ja, das funktioniert! :)
Als Delay-Funktion empfehle ich:
1 | void Delay(__IO uint32_t nCount) |
2 | {
|
3 | while(nCount--) |
4 | {
|
5 | } |
6 | } |
Quatschkopf schrieb: > Als Delay-Funktion empfehle ich: Leider hat die AFAIK je nach Compiler Optimierungsstufe unterschiedliches Delay. Für konstantes Delay muss man Hardware Timer oder Assembler bemühen.
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.
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.
Hat der Cortex M1 überhaupt nen DWT? Ist doch afaik erst in nem M3?!?
Nico W. schrieb: > Hat der Cortex M1 überhaupt nen DWT? Ist doch afaik erst in nem M3?!? guter Punkt, aber wie kommst Du darauf, dass der 32F103xx auf einem M1 basiert? lt. ST Dokument RM0008 ist das ein M3?
Ruediger A. schrieb: > lt. ST Dokument RM0008 ist das ein M3? Ja, da hast du auch wieder recht :) Ich nutze bei meinem Projekt Assembler für ein kurzes Delay. Ich nutze den DWT gerne dazu mein Projekt genauer zu betrachten wie lange die Funktionen brauchen.
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.
