Guten Tag,
ich versuche in STM32CubeIDE mit Hilfe von PWM flexible Rechtecksignale
(es geht nur um TTL, also keine Stromschleife oder ähnliches) im
zweistelligen Mikrosekundenbereich an einem Port-Pin zu erzeugen. Der µC
ist ein STM32F411 @50 MHz und ich benutze Timer 11 in Verbindung mit Pin
PB9. Meine Tests funktionieren halbwegs gut, so lange die Periodendauer
konstant ist und ich nur die Pulsweite anpasse. Aber selbst dann sind
der erste Puls und die erste Periode laut Speicheroszi ein paar µS zu
kurz oder zu lang.
Dies ist der Code für Clock- und Timer-Initialisierung, der aufgrund
meiner Einstellungen in STM32CubeIDE erzeugt wurde:
1
void SystemClock_Config(void)
2
{
3
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
4
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
5
6
/** Configure the main internal regulator output voltage
Das funktioniert wie bereits gesagt bis auf die Ungenauigkeit des ersten
Puls ganz gut, aber sobald ich die 2 Zeilen für die Periode
einkommentiere und Array-Werte mit wechselnden Perioden benutze, bekomme
ich echt merkwürdige Kurven auf dem Speicheroszi angezeigt. Zum Testen
habe ich hier einfach immer kürzere Perioden mit 50:50 Tastverhältnis
gewählt, es ist aber nur ein Beispiel:
1
/* USER CODE BEGIN PV */
2
int16_t pwm_tx_array [4][2] = {
3
{ 799, 400 },
4
{ 599, 300 },
5
{ 399, 200 },
6
{ 199, 100 },
7
};
8
int pwm_tx_finished = 0;
9
int16_t pwm_tx_array_counter = 0;
10
int pwm_tx_array_size = sizeof(pwm_tx_array)/sizeof(pwm_tx_array[0]);
11
int16_t pwm_tx_period = 0;
12
int16_t pwm_tx_pulse = 0;
13
/* USER CODE END PV */
Der Main Loop ist leer und der µC erzeugt momentan nur diese PWM. Ich
benötige später nicht wirklich 2 Mikrosekunden lange Pulse und
eigentlich würden mir +-2 Mikrosekunden Genauikgeit ausreichen, aber da
ist ja noch das Problem mit der zu ändernden Periode und ich wollte auch
wegen des ersten ungenauen Puls wissen, ob die nachfolgenden Pulse exakt
sind...Aber sie sind es: der 2 µS Puls zum Schluss wird auf dem
Speicheroszi exakt mit 2 µS gemessen. Wenn ich im Callback vor dem
Stoppen des Interrupts einen Breakpoint setze, sehen die verschiedenen
Pulse bei konstanter Periode bis auf den ersten PWM Durchlauf stets
präzise aus.
Kann mir jemand bei diesem Problem helfen? Oder gibt es eine andere
Möglichkeit, eine Abfolge von Rechtecksignalen bis runter in den
zweistelligen Mikrosekundenbereich zu erzeugen?
Vielen Dank und liebe Grüße
Hendrik
Nein, das kannte ich noch nicht. Vielen Dank, ich beschreibe die
Register ARR und CCR1 jetzt direkt und damit konnte ich immerhin schon
mal das Problem mit den dynamischen Perioden lösen.
Für meine Problem mit dem ungenauen ersten Puls habe ich leider noch
keine Lösung finden können. Ich habe zum Testen ein neues Projekt für
mein Nucleo Board erstellt und nur den Timer11 auf PWM gestellt (Periode
auf 1999 , Puls auf 1000). Ansonsten alles auf Default gelassen, Clock
ist dann HSI 16 MHz, also dauern 1000 Pulse 62,5 µS. Dann habe ich
direkt vor der Main-Loop mit HAL_TIM_PWM_Start() die PWM gestartet.
Ergebnis: der erste Puls dauert 67,5 µS, alle nachfolgenden 62,5 µS. Ich
meine, ich kann da ja eigentlich nicht so viel falsch gemacht haben, da
ja fast alles von der IDE erstellt wird und ich lediglich die PWM im
Blocking Mode gestartet habe. Weiß echt keiner, woran diese erste
Ungenauigkeit liegen könnte?
Oder mein Speicheroszi spinnt...muss ich mal mit nem externen Trigger
prüfen, den ich über den 2. Kanal des Oszis etwas eher als die PWM
auslöse.
Man kann den Inhalt der PWM-Register auch per DMA füllen lassen. Das
kann der Timer selbst triggern, z.B. bei jedem n-ten Durchlauf
(n=1..256).
Damit kann man sehr komplexe Pattern generieren oder auch eine
3-Phase-Sinus-Spannung erzeugen, wenn man mehrere Compare-Register so
füttert.
Das braucht etwas Spucke und Geduld, aber danach macht das die HW quasi
von selbst. Man fragt sich, was man mit der schlafenden 32-Bit-CPU
anfangen könnte.
Eine eigene Frage?
Dieser Thread ist über 4 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.