mesure-frequence.ino
The GD32 GPIOs have the interrupt matrix: each edge calls the routine, and counting over a 1 s window yields frequency. The short-ISR + locked-copy pattern is every counter's blueprint.
Hardware required
A GD32F103C8T6 development board (Cortex-M3 at 108 MHz, Blue Pill pin-to-pin compatible), powered at 3.3 V/5 V, with an ST-Link or serial adapter. A square-wave generator (another board's PWM pin, Hall sensor, encoder).
Wiring
Signal on PA3 (3.3 V max!), common grounds. The generator can be another board's PWM pin through 1 kΩ.
How it works
attachInterrupt maps PA3 to EXTI3; the ISR only increments a volatile. noInterrupts/interrupts bracket the read for a coherent 32-bit counter copy. With Arduino: install the « STM32F1 » core (Roger Clark, board manager) and pick the « GD32F103C » board; the user LED is PC13 (active LOW). In C: GD32F10x firmware library + ST-Link.
Going further
A water/electricity pulse counter (slow), or a tachometer with two differently-sized windows.
mesure-frequence.ino
// Compteur de fronts sur PA3 (signal carre 1 Hz a 5 kHz) via attachInterrupt.
const int ENTREE = PA3;
volatile uint32_t fronts = 0;
unsigned long fenetre = 0;
void surFront() { fronts++; } // ISR minimale
void setup() {
Serial.begin(115200);
pinMode(ENTREE, INPUT);
attachInterrupt(digitalPinToInterrupt(ENTREE), surFront, RISING);
fenetre = millis();
}
void loop() {
if (millis() - fenetre >= 1000) {
noInterrupts();
uint32_t n = fronts; fronts = 0; // copie atomique
interrupts();
fenetre = millis();
Serial.printf("frequence = %lu Hz\n", (unsigned long)n);
}
delay(10);
}