Im Moment experimentiere ich mit dem CH32V003 und diesem Framwork: https://github.com/openwch/arduino_core_ch32?tab=readme-ov-file und versuche hier mal ein paar Eigenheiten zu dokumentieren. Hier gibt es eine Anleitung: https://www.hackster.io/patrick-fitzgerald2/program-ch32v003-risc-v-with-arduino-ide-135f6f Auf welche Pins wird der serielle Port "gemapped".
Hab's raus gekriegt:
1 | /*
|
2 | * CH32V003F4P6 Serial Send Test
|
3 | *
|
4 | * CH32V003F4P6 TX (output) : PD5
|
5 | *
|
6 | * has to be connected to the Programming Dongle RX
|
7 | *
|
8 | * Framework:
|
9 | * https://github.com/openwch/arduino_core_ch32
|
10 | */
|
11 | |
12 | |
13 | void setup() { |
14 | Serial.begin(115200); |
15 | }
|
16 | |
17 | uint8_t Counter = 0; |
18 | |
19 | void loop() |
20 | {
|
21 | Serial.println(Counter++); |
22 | delay(100); |
23 | }
|
Ja, mich hätte halt mal der Unterschied interessiert wieviel langsamer das ist.
Alexander schrieb: > Ja, mich hätte halt mal der Unterschied interessiert wieviel langsamer > das ist. Schau doch mal in die Arduino core library.
Alexander schrieb: > steht da nicht drin ;) Da müßte aber main drinstehen, was dann loop und noch anderen Schrunz aufruft. Ohne ein main beschwert sich jeder C-Compiler heftig.
Christoph M. schrieb: > Geschwindigkeit Pin-Toggle mit digitalWrite: > 255kHz Ich wollte hier nur wissen: 233kHz oder so
Peter D. schrieb: > Da müßte aber main drinstehen, was dann loop und noch anderen Schrunz > aufruft. Tut es. Die Aktionen in der Hauptschleife von main() sind überschaubar (loop(), Interrupts) solange auf der seriellen Schnittstelle Ruhe herrscht:
1 | for (;;) { |
2 | loop(); |
3 | if (serialEventRun) serialEventRun(); |
4 | }
|
Die Interrupts
:
Bearbeitet durch User
>Christoph M. schrieb: >> Geschwindigkeit Pin-Toggle mit digitalWrite: >> 255kHz Alexander (alecxs) 18.06.2025 15:46 >Ich wollte hier nur wissen: 233kHz oder so
1 | * Results: |
2 | *
|
3 | * within while loop 255kHz |
4 | * without while loop 213kHz |
Es wäre interessant zu sehen, wie schnell es maximal wird, wenn man direkt auf den Port schreibt.
:
Bearbeitet durch User
Oha, der Speicherverbrauch des Framworks scheint exorbitant:
1 | /*
|
2 | * trigonometrie speed test
|
3 | */
|
4 | |
5 | void setup() |
6 | {
|
7 | Serial.begin(115200); |
8 | }
|
9 | |
10 | void loop() |
11 | {
|
12 | float sum=0; |
13 | |
14 | float x,y,z; |
15 | |
16 | Serial.println("start"); |
17 | for(uint32_t n=0;n<100000;n++) |
18 | {
|
19 | x=sin(2*PI*n/1000); |
20 | x=cos(2*PI*n/1000); |
21 | sum+=sqrt(x*x+y*y); |
22 | }
|
23 | Serial.print("sum: "); |
24 | Serial.print(sum); |
25 | }
|
/tmp/arduino_build_733415/CH32V003_trigonometrieSpeed.ino.elf section `.text' will not fit in region `FLASH' .arduino15/packages/WCH/tools/riscv-none-embed-gcc/8.2.0/bin/../lib/gcc/ riscv-none-embed/8.2.0/../../../../riscv-none-embed/bin/ld: region `FLASH' overflowed by 8680 bytes
Alexander (alecxs)
18.06.2025 19:16
>Interessant, doch ein gewisser Unterschied.
Beim Arduino-Nano ist der Unterschied relativ gesehen kleiner:
1 | /* |
2 | * Arduino Nano Results: |
3 | * |
4 | * within while loop 149kHz |
5 | * without while loop 146kHz |
6 | * |
7 | */ |
Beim Arduino Nano passt der obige "trigonometrie Speedtest" locker:
1 | Der Sketch verwendet 2570 Bytes (8%) des Programmspeicherplatzes. Das Maximum sind 30720 Bytes. |
2 | Globale Variablen verwenden 200 Bytes (9%) des dynamischen Speichers, 1848 Bytes für lokale Variablen verbleiben. Das Maximum sind 2048 Bytes. |
Christoph M. schrieb: > Oha, der Speicherverbrauch des Framworks scheint exorbitant: Der Grund dafür: Beitrag "Re: CH32V003, float wirklich langsam?"
> Oha, der Speicherverbrauch des Framworks scheint exorbitant: >>Der Grund dafür: >> Beitrag "Re: CH32V003, float wirklich langsam?" Danke. Auszug:
1 | von Yalu X. (yalu) (Moderator) |
2 | 14.04.2025 12:47 |
3 | |
4 | In der Mounriver-Toolchain für die CH32-Controller wird die generische |
5 | soft-fp der glibc verwendet. Diese ist in C implementiert und in |
6 | keinster Weise an spezifische CPU-Typen angepasst. Die AVR-FP-Routinen |
7 | hingegen sind in Assembler speziell für diesen CPU-Typ geschrieben. |
Was mich dabei wundert: Die RISC-V Architektur ist ja ziemlich genau über die Abkürzungen der Erweiterung der Namensbezeichnung. Die Bezeichnung von WCH ist RISCV-V2A https://akizukidenshi.com/goodsaffix/CH32V003.pdf was aber nicht mit der Namenskonvention der RISC-V Organisation übereinstimmt. Im Datenblatt wird dann auf die Bezeichnung des Cores als RV32EC verwiesen . * E => Embedded, nur 16 Register * C => 16-bit compressed instructions https://five-embeddev.com/riscv-user-isa-manual/Priv-v1.12/rv32e.html Da die RISC-V Architekur ja ein mittlerweile recht verbreiteter Standard ist, sollte man erwarten, dass es eine schnelle Assembler-Float-Lib dazu gibt.
:
Bearbeitet durch User
Christoph M. schrieb: > CH32V003_Arduino_toggleSpeedTest.png Christoph M. schrieb: >>Und ohne die while Schleife? > Ist für die Geschwindigkeit. Da es dir anscheinend auf Geschwindigkeit ankommt, ist die relativ langsame Funktion digitalWrite() doch eher ungeeignet. Wäre an deren Stelle das deutlich schlankere digitalWriteFast() nicht naheliegender? p.s. Programmcode als PNG ist schon stark :-(
:
Bearbeitet durch User
Hier mal der Geschwindigkeitstest mit direktem Beschreiben von PC1. Die Frequenz liegt bei knapp 6MHz. Bei 48Mhz wäre das also 48/6/2=4 Zyklen pro Schreiben. Die Frage ist: Wieviel davon braucht der Sprung?
1 | /*
|
2 | * CH32V003
|
3 | *
|
4 | * Pin Toogle Speed Test
|
5 | * Results:
|
6 | *
|
7 | * Toggle Speed: 168ns, ~5.95 MHz
|
8 | *
|
9 | * 2025-06-19 mchris
|
10 | *
|
11 | */
|
12 | |
13 | |
14 | #define RCC_APB2PCENR (*(volatile uint32_t*)0x40021018) // APB2 Peripheral Clock Enable Register
|
15 | // Controls the clock to APB2 peripherals.
|
16 | // You must enable the clock for GPIOC (by setting bit 4, IOPCEN) before using any GPIOC functions.
|
17 | |
18 | #define GPIOC_CFGLR (*(volatile uint32_t*)0x40011000) // GPIOC Port Configuration Low Register
|
19 | // Configures the mode and configuration (input/output, push-pull/open-drain, etc.) for pins PC0-PC7.
|
20 | // Each pin uses 4 bits: [MODE1:0 | CNF1:0]. For PC1, configure bits 7:4.
|
21 | |
22 | #define GPIOC_BSHR (*(volatile uint32_t*)0x40011010) // GPIOC Bit Set/Reset Register
|
23 | // Allows atomic setting or resetting of GPIOC output pins.
|
24 | // Write '1' to bit n (0-15) to set PCn high; write '1' to bit n+16 (16-31) to set PCn low.
|
25 | // Example: GPIOC_BSHR = (1 << 1); // Set PC1 high
|
26 | // GPIOC_BSHR = (1 << (1+16)); // Set PC1 low
|
27 | |
28 | void setup() |
29 | {
|
30 | // Enable GPIOC clock
|
31 | RCC_APB2PCENR |= (1 << 4); // Set bit 4 (IOPCEN) to enable GPIOC peripheral clock |
32 | |
33 | // Configure PC1 as push-pull output, 50MHz
|
34 | GPIOC_CFGLR &= ~(0xF << 4); // Clear configuration bits for PC1 (bits 7:4) |
35 | GPIOC_CFGLR |= (0x3 << 4); // Set MODE1=11 (output 50MHz), CNF1=00 (push-pull) |
36 | }
|
37 | |
38 | void loop() |
39 | {
|
40 | // Blink PC1
|
41 | while (1) { |
42 | GPIOC_BSHR = (1 << 1); // Set PC1 high |
43 | //delay(1000);
|
44 | GPIOC_BSHR = (1 << (1 + 16)); // Set PC1 low |
45 | //delay(1000);
|
46 | }
|
47 | }
|
Rainer W. (rawi) 19.06.2025 06:40 >p.s. >Programmcode als PNG ist schon stark :-( Im Screenshot geht es darum, den Speicherverbrauch anzuzeigen. Ich vertraue darauf, dass du die 2 Zeilen bei Bedarf auch selber eintippen kannst.
Christoph M. schrieb: > Wieviel davon braucht der Sprung? Sieht man doch ganz gut auf dem Oszi. 1 Takt High, 1 Takt Low, 2 Takte für den Sprung. Due könntest auch in der Schleife mehrere High/Low wechsel einbauen und dann siehst du auf dem Oszi die einzelnen zeiten etwas besser.
... ich habe zwar einen ganz anderen Ansatz für die Verwendungsmöglichkeiten von CH32V003, habe aber in meinen Anleitungen zum Schluß auch die Möglichkeit der Programmierung unter Arduino behandelt und verwende in dieser Anleitung denselben (offiziellen) Core wie du, den ich um meine eigenen Programmiermöglichkeiten (unter Linux) erweitert hab. Was ich beim Schreiben einer Anleitung vermisst habe, war ein typisches Pinoutmapping des Chips zur Arduino Programmierung und deshalb habe ich dann dieses hier im Anhang erstellt. :-) vllt. kannst du das für deine Seite zur Programmierung von CH32V003 unter Arduino gebrauchen. Gruß, Ralph
>:-) vllt. kannst du das für deine Seite zur Programmierung von CH32V003 >unter Arduino gebrauchen. Wow, finde ich extrem gut gemacht. Danke :-)
Benjamin K. (bentschie) 19.06.2025 07:42 >Du könntest auch in der Schleife mehrere High/Low wechsel einbauen und >dann siehst du auf dem Oszi die einzelnen zeiten etwas besser. Eine sehr gute Idee :-) Ich meine 2 Cyclen pro Portschreiben zu sehen.
1 | /*
|
2 | CH32V003
|
3 | |
4 | Pin Toogle Speed Test
|
5 | Results:
|
6 | |
7 | Toggle Speed: 82ns or 12.2MHz for ON/OFF
|
8 | |
9 | 2025-06-19 mchris
|
10 | |
11 | */
|
12 | |
13 | |
14 | |
15 | #define GPIOC_BSHR (*(volatile uint32_t*)0x40011010) // GPIOC Bit Set/Reset Register
|
16 | |
17 | void setup() |
18 | {
|
19 | pinMode(PC1, OUTPUT); |
20 | }
|
21 | |
22 | #define LEDON {GPIOC_BSHR = (1 << 1);}
|
23 | #define LEDOFF {GPIOC_BSHR = (1 << (1 + 16));}
|
24 | |
25 | void loop() |
26 | {
|
27 | // Blink PC1
|
28 | while (1) { |
29 | LEDON; |
30 | LEDOFF; |
31 | LEDON; |
32 | LEDOFF; |
33 | }
|
34 | }
|
Ralph S. schrieb: > Was ich beim Schreiben einer Anleitung vermisst habe, war ein typisches > Pinoutmapping des Chips zur Arduino Programmierung und deshalb habe ich > dann dieses hier im Anhang erstellt. Gleich in die README.md mit reinpacken und einen Pull request schicken.
Christoph M. schrieb: > Was mich dabei wundert: Die RISC-V Architektur ist ja ziemlich genau > über die Abkürzungen der Erweiterung der Namensbezeichnung. > > Die Bezeichnung von WCH ist RISCV-V2A > > https://akizukidenshi.com/goodsaffix/CH32V003.pdf > > was aber nicht mit der Namenskonvention der RISC-V Organisation > übereinstimmt. > Im Datenblatt wird dann auf die Bezeichnung des Cores als RV32EC > verwiesen . RV32EC ist der Name einer von der Berkeley-Universität bzw. RISC-V International entwickelten Befehlssatzarchitektur. QingKe V2A ist der Name eines von Nanjing Qinheng Microelectronics entwickelten Prozessorkerns, der die RV32EC-Architektur implementiert. CH32V003 ist der Name eines ebenfalls von Nanjing Qinheng Microelectronics unter der Marke WinChipHead (WCH) entwickelten Mikrocontrollers, der auf dem QingKe-V2A-Kern basiert.
Gerade ist mir eingefallen, dass der PiPico2 ja auch zwei otpionale RISC-V Cöre besitzt. Die beiden RV32IMACZ sollten abwärtskompatibel zum RV32EC des QingKe V2A sein. Man kann den Kern in der IDE auswählen und mein hüpergeniales Programm (Screenshot) braucht nur 56256 Bytes.
:
Bearbeitet durch User
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.