Forum: Mikrocontroller und Digitale Elektronik STM32F407 & CubeMX DMA-PWM


von A. B. (funky)


Angehängte Dateien:

Lesenswert?

Hi,

ich möchte eine Datenprotokoll senden, welches pro Bit den Aufbau 20us 
low, 20us 0=high/1=low, 20us high hat. Das dann halt 8mal für ein Byte

Ich wollte dafür einen Timer mit 60us Periode benutzen und dann 
entsprechend den DutyCycle mit 33 oder 66% einstellen. Aufgrund der 
knappen Timings per DMA-PWM. Ich benutze CubeMX & ST HAL

Testweise gebe ich ein Byte 0x00 aus.
Prinzipiell klappt das auch, aber ich habe zwei Probleme:

Der erste Puls ist kürzer. Statt 40us nur 36us. Die anderen Pulse 
entsprechen den 20us low & 40us high wie ich sie erwarten würde.

Ich bekomme am Ende noch einen Spike welcher dort nicht hingehört.

Hat jemand eine Idee was da mögliche Ursachen sein können? Ich bin da 
gerade etwas ratlos wo das Verhalten herkommen könnte.

Bei den Spike könnte ich mir vorstellen, dass ich die PWM nicht schnell 
genug abstelle(evtl sind die HAL Funktionen zu lang?) oder ich habe noch 
etwas mit der Polarität verpeilt

Aber warum der erste Pulse eine andere Länge hat verstehe ich überhaupt 
nicht.

Hier mal mein runtergestrippter send-code (das ich sonst sicherstellen 
müßte das meine Daten fertig gesendet sind ist mir klar. Aber das delay 
ist hinreichend lang so dass das nicht die Ursache sein sollte
1
extern TIM_HandleTypeDef htim1;
2
extern DMA_HandleTypeDef hdma_tim1_ch1;
3
uint16_t out_buffer[12*8];
4
5
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef* htim)
6
{
7
  if (htim->Instance == htim1.Instance){
8
  HAL_TIM_PWM_Stop_DMA(htim, TIM_CHANNEL_1);
9
  }
10
}
11
12
void send(uint32_t inp)
13
{
14
  HAL_StatusTypeDef status;
15
  for (int i = 7; i >= 0; i--) {
16
    if (inp & (1 << i)) {
17
      out_buffer[i] = 6719;
18
    } else {
19
      out_buffer[i] = 3356;
20
    }
21
  }
22
  
23
  status = HAL_TIM_PWM_Start_DMA(&htim1, TIM_CHANNEL_1, (uint32_t*)&out_buffer, 8);
24
}
25
26
void sendTask()
27
{
28
 
29
  while (1) {
30
    send(0x00);
31
   
32
    osDelay(1000);
33
  }
34
}

Die CPU läuft mit 168MHz und der Timer ohne Prescaler auch mit 168MHz.

Hat jemand eine Idee was ich da prinzipiell falsch mache? Ich habe mal 
die TimerKonfiguration angehängt.


Danke für evtl. Anregungen

von A. B. (funky)


Lesenswert?

1
void MX_DMA_Init(void)
2
{
3
4
  /* DMA controller clock enable */
5
  __HAL_RCC_DMA2_CLK_ENABLE();
6
7
  /* DMA interrupt init */
8
  /* DMA2_Stream1_IRQn interrupt configuration */
9
  HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 5, 0);
10
  HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);
11
12
}

Das ist noch die DMA Konfiguration.
Fehler wie falsche Reihenfolge der Initialisierung habe ich schon 
behoben. (hatte das ganze mit einer CubeMX Version begonnen, welche die 
Initialisierung des DMA am Schluss machte und dann ging gar nichts)

von Cnt reg not 0 (Gast)


Lesenswert?

Wann wird der timer gestartet?

von A. B. (funky)


Lesenswert?

Das passiert innerhalb meiner send() Funktion mittels 
HAL_TIM_PWM_Start_DMA

Gestoppt wird die PWM dann in HAL_TIM_PWM_PulseFinishedCallback()

von A. B. (funky)


Lesenswert?

Einen prinzipiellen Fehler hat meine PWM aber noch sehe/vermute ich 
gerade.

Ich dachte meine PWM macht 20us low und 60us high
Ich denke aber es sind eher 40us high, 20us low
Der Spike am Ende ist dann evtl meine IRQ Latenz bis zum Abschalten der 
PWM

Die andere Dauer meines ersten Pulses erklärt sich mir damit aber noch 
nicht

von A. B. (funky)


Lesenswert?

ok, manchmal muss man über Probleme sprechen um sich der Lösung zu 
nähern ;)

PWM Mode 2 und der Spike ist weg.

von Cnt reg not 0 (Gast)


Lesenswert?

Das freut mich für dich.

Und gut das es jetzt hier auch als Lösung steht.

von A. B. (funky)


Angehängte Dateien:

Lesenswert?

hmm, mit ein wenig Abstand muss ich leider feststellen, dass es nicht 
funktioniert wie erwartet

Ich habe mal die OsziBilder angehängt mit dem Output den ich bekomme 
wenn ich 0x00, 0x10 und 0x81 sende
0x00 & 0x10 stimmen für mich.
bei 0x81 bekomme ich zwei lange Pulse hintereinander. Ich würde dort am 
Anfang und am Ende einen langen Puls erwarten. Im Speicher stehen die 
Werte auch korrekt drin

Ich habe einen Link gefunden, wo jemand ähnliche Effeket beschreibt
https://electronics.stackexchange.com/questions/422079/stm32-hal-pwm-output-with-dma-misbehavior

Aber leider keine Lösung.

Ich geh mal davon aus, dass ich irgendwas grundsätzlich falsch mache da 
variabler Duty Cycle ja bei anderen ohne Probleme mit DMA zu 
funktionieren scheint aber ich hab gertade null Plan wo ich da ansetzen 
soll

Hat jemand eine Idee was da der Fehler sein kann?

von A. B. (funky)


Lesenswert?

Ich bin einfach auf Tim2 gewechselt und dort funktioniert alles wie 
erwartet. So wirklich habe ich nicht herausgefunden was ich bei Tim1 
falsch gemacht habe, aber ich vermute mal der Fehler sitzt vorm PC und 
ich habe etwas falsch konfiguriert(Tim1 ist ja noch etwas umfangreicher)

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
Noch kein Account? Hier anmelden.