Ich benutze den CH32V003 im SOT8(!) jetzt schon so ein Jahr fuer diverse kleine Spielereien. Bisher hat alles im grossen und ganze so funktioniert wie ich mir das vorstelle. Aber gelegentlich kam es schon mal zu irgendeinem komischen Verhalten und ich hab das Teil dann mit minichlink -u wieder auf die Beine geholfen. Aktuell hab ich gerade eine kleine Anwendung laufen die nichts anders macht als mit tim1 300khz erzeugen zu lassen und dies an PC4, PA1 und PA2 auszugeben. Das funktioniert auch! Aber erstaunlich oft haengt sich der Controller beim starten weg! Das Programm laeuft dann direkt nach dem flashen wenn es vom debugger gestartet wird, aber nur sehr gelegentlich nach einem Powercycle in meiner Hardware. Ich wuerde ja sagen irgendwas stimmt mit meiner Resetbeschaltung nicht, aber der SOT8 hat keinen Reseteingang. Ich hab auch schon minichlink mit -d oder -D probiert ohne das ich da eine Besserung sehen wuerde. Hab ich da was uebersehen? Vanye
Ja, der Gedanke liegt natuerlich nahe. Ich hatte aber schon direkt an den Beinen des SOT8 einen 100nF drueber geloetet. Und mehr ist da ja nicht....
Häng mal ein Oszi an den Versorgungsspannungseingang und nimm den Verlauf auf.
Ich hab da wohl wirklich einen Bug der Extraklasse in meinem System. :-D Mein Programm sieht so aus: int main() { SystemInit48HSI(); //Systemclock auf 48Mhz setzen pwm_init(); //PWM Initialisieren fuer 300khz an PA1 und PA2 while(1); } Das funktioniert IMMER wenn ich es vom Debugger in den STM32V003 reinlade. Stoepsel ich den Debugger an und lasse es ueber mein Labornetzteil laufen, so funktionier es meistens nicht. Aber so jedes 30-40x startet es doch und laeuft dann auch! Wenn es nicht läuft dann kommen komische Impulse aus PA2 raus. (siehe Bild) Kommentiere ich SystemInit48HSI() aendert sich nichts am problematischen Startverhalten, aber wenn es geht dann sind natuerlich die Frequenzen anders weil der Systemtakt niedriger ist. Als ich damals meine Umgebung aufgesetzt habe, da habe ich ch32fun kopiert und als erstes ein einfaches LED-Blink Programm geschrieben. Das zeigt dieses verhalten nicht! Es startet also immer. Nehme ich das als Basis und änder das auf obiges main ab, so funktioniert es auch immer! Der Timer gibt also die gewuenschten Signale aus. Danach hab ich damals etwas am "Design" der Umgebung rumgespielt. Also nur die Libaries kopiert die ich brauche, andere Verzeichnisse, Startup verschlankt, usw. Dabei muss ich wohl einen Fehler gemacht haben der mir nicht aufgefallen ist weil es halt immer problemlos funktioniert wenn es ueber den Debugger gestartet wird. Da muss ich wohl noch mal tief in mich gehen und beide Startupcodes genau vergleichen. Vermutlich initialisiert der Debugger irgendetwas das ich selber vergessen habe. Aber bizarr das es manchmal halt doch funktioniert. Vanye
Weiß nicht, ob es das bei diesem Controller auch gibt, aber die NXP LPC Controller können ähnlich herumzicken, wenn man die Brown-Out BOD nicht sofort als erstes beim Reset setzt.
Harald A. schrieb: > Weiß nicht, ob es das bei diesem Controller auch gibt Tut es:
1 | 1.4.4 Power Supply Monitor |
2 | |
3 | This product integrates a power-on reset (POR)/power-down reset (PDR) |
4 | circuit, which is always in working condition to ensure that the |
5 | system is in supply. It works when the power exceeds 2.7V; when VDD |
6 | is lower than the set threshold (VPOR/PDR), the device is placed in |
7 | the reset state without using an external reset circuit. |
8 | |
9 | In addition, the system is equipped with a programmable voltage |
10 | monitor (PVD), which needs to be turned on by software to compare |
11 | the voltage of VDD power supply with the set threshold VPVD. |
12 | Turn on the corresponding edge interrupt of PVD, and you can |
13 | receive interrupt notification when VDD drops to the PVD threshold |
14 | or rises to the PVD threshold. Refer to Chapter 4 for the values of |
15 | VPOR/PDR and VPVD. |
(Seite 5 im Datenblatt CH32V003 V1.7)
:
Bearbeitet durch User
Ich muss den Thread noch mal nach oben holen, weil ich gerade etwas Zeit gefunden habe mich damit zu beschaeftigen und etwas Rat gebrauchen koennte. :) Zuerst mal die Probleme hier treten mit verschiedenen Programmen auf. Ich denke daher nicht das sie an einem Programmierfehler in einem bestimmten Programm liegen. Im folgenden betrachten wir aber nur ein Programm!
1 | int main() |
2 | {
|
3 | SystemInit48HSI(); //Systemclock auf 48Mhz setzen |
4 | pwm_init(); //PWM Initialisieren fuer 300khz an PA1 und PA2 |
5 | uart_write(buffer, 0); //Bullshit, dazu später mehr! |
6 | while(1); |
7 | }
|
Hier noch mal mein Hardfault handler
1 | void HardFault_Handler(void) |
2 | {
|
3 | |
4 | //Port PA2 als Ausgang für LED initialisieren
|
5 | RCC->APB2PCENR |= RCC_APB2Periph_GPIOA; |
6 | GPIOA->CFGLR &= ~(0xf<<(4*2)); |
7 | GPIOA->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*2); |
8 | |
9 | //LED blinkt so grob 5x pro Sekunde mit LED an PA2.
|
10 | volatile int i; |
11 | doof:
|
12 | GPIOA->BSHR = (1<<2); // PA2 = grüne LED auf High setzen |
13 | i=100000; while(i-- > 0); |
14 | GPIOA->BSHR = (1<<16) | (1<<(16+2)); //grüne LED auf low=aus setzen |
15 | i=100000; while(i-- > 0); |
16 | goto doof; |
17 | |
18 | |
19 | }
|
Uebersetze ich das und lade das mit dem Debugger in mein Testboard so passiert das erwartete. Der in pwm_init() initialisierte Timer gibt mir ein PWM/Rechteck an PA1 und PA2 aus. Die CPU selber bleibt in der whileschleife stehen. Alles wie erwartet. Die Zeile: uart_write(buffer, 0); gibt einen Buffer von 0Byte aus. Macht also nix! Kommentiere ich die aus so wird mein Programm um ein paar hundert Byte kleiner weil der Compiler erkennt das diese Funktionen die dahinter haengen nicht aufgerufen werden. Eine der nicht genutzten Funktionen liegt im Flash-Speicher vor main. Hier mal ein Ausschnitt aus dem mapfile mit uart_write
1 | *(.text.*) |
2 | .text.uart_getFifoSend |
3 | 0x00000000000000a0 0x2e /tmp/ccvJfodc.ltrans0.ltrans.o |
4 | .text.startup.main |
5 | 0x00000000000000ce 0x216 /tmp/ccvJfodc.ltrans0.ltrans.o |
6 | 0x00000000000000ce main |
7 | .text.USART1_IRQHandler |
8 | 0x00000000000002e4 0x6c /tmp/ccvJfodc.ltrans0.ltrans.o |
und hier ohne:
1 | *(.text.*) |
2 | .text.startup.main |
3 | 0x00000000000000a0 0x1b4 /tmp/ccPdPsYu.ltrans0.ltrans.o |
4 | 0x00000000000000a0 main |
5 | .text.USART1_IRQHandler |
6 | 0x0000000000000254 0x84 /tmp/ccPdPsYu.ltrans0.ltrans.o |
Im zweiten Fall bin ich mir ziemlich sicher das mein "main" garnicht mehr aufgerufen wird. Der CH32 wirft einen HardFault und ich sehe meine LED blinken die ich dort im Handler ansteuere. Auch wenn ich vor der Uartaufruf einen while(1) einfuege funktioniert das Programm nicht mehr. Grund dafuer ist das der Compiler erkennt das uart_write nicht aufgerufen wird und alle ungenutzten Funktionen aus dem Programm wirft. Spiele ich aber etwas mit den Compileroptionen -flto -ffunction-sections -fdata-sections Llaesst er den Code drin und das Programm laeuft wieder. Funktion und Nichtfunktion haengt also davon ab an welcher Stelle main im Programm steht! Das erstaunt mich! Dabei wird main aus dem startupCode aufgerufen:
1 | //Sprung nach Main
|
2 | __set_MEPC( (uint32_t)main ); |
3 | // set mepc to be main as the root app.
|
4 | asm volatile( "mret\n" ); |
Ich sehe nicht wieso das manchmal gehen soll und wieso manchmal nicht! Aber es kommt noch besser! All das gesagte gilt immer wenn ich das lauffaehige Programm ueber den angeschlossenen Debugger in die MCU reinlade.
1 | ./minichlink -3w ./template.bin flash -b |
Dabei ist meine TestPlatine die ganze Zeit am Debuger angeschlossen und wird auch von diesem mit Spannung versorgt. Ziehe ich die Platine ab und steck sie wieder an, oder versorge sie extern mit Spannung, funktioniert das Programm auch nicht mehr richtig. Ich lande dann wieder im Hardfaulthandler! Ein paar brilliante Ideen wie man da weiter kommt? :) Vanye
Keine Idee, aber super interessanter Krimi... Im Falle vom UART Code, er ja dann da liegt wo "main nicht tut", wenn du mal ein Byte sendest, so dass er da auch "durchlaufen muss", knallt es dann auch?
Vanye R. schrieb: > Ein paar brilliante Ideen wie man da weiter kommt? :) Knifflig. Einen "frischen" CH32V003 hast du schon probiert? Nicht dass das Flash (schon) Macken hat und beim "miteincompilieren" von uart_getFifoSend liegt das im fehlerhaften Flash (und wird ja nicht benutzt...)
> Knifflig. Einen "frischen" CH32V003 hast du schon probiert?
Klar. Hab ja genug. Es liegt nicht an einem defekten CH32V003.
Ich hab sogar zwei verschiedene Chargen, einmal in SOT8 und
einmal in SOT16. Beide identisches Verhalten.
Ich hab gerade mal eine Ausgabe des mcause Register programmiert,
dazu schreibe ich gleich noch was im anderen Thread. Ist vielleicht doof
das ich das getrennt habe, aber ist vielleicht auch von allgemeineren
Interesse wenn man dieses Register auslesen kann.
Jedenfalls fuehrt das nun dazu das der code mit auskommentierten
usart_write immer noch laeuft. Aber nicht wenn ich das Teil
neu starte. Dann gibt es Hardfault, noch dazu einen sehr merkwuerdigen.
Aber dazu anderer Thread.
Vanye
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.