Ich habe 3 DMAs die von einem Timer getriggerd werden.
Um die die DMAs neu zu starten will ich den Timer stoppen und später
wieder neu starten.
PWM_richtig.PNG beschreibt das Ideal (was leider nur zufällig eintritt)
PWM_falsch.PNG tritt leider auch manchmal ein
PWM_Lösung.PNG einziger Unterschied zum Rest ist das hinzufügen von:
1 | TIM1->CNT = TIM1->ARR-20;
|
Wie löst man dieses Problem richtig?
1 | __disable_irq();
|
2 | // auf letzte Flanke warten
|
3 | while (TIM1->CNT <= TIM1->CCR2);
|
4 | while (TIM1->CNT > TIM1->CCR2);// funktioniert nicht wie gedacht
|
5 | TIM_Cmd(TIM1 , DISABLE);
|
6 |
|
7 | TIM_DMACmd(TIM1, TIM_DMA_CC3 | TIM_DMA_CC1 | TIM_DMA_CC2, DISABLE);
|
8 | DMA_Cmd(DMA2_Stream6, DISABLE);
|
9 | while(DMA_GetCmdStatus(DMA2_Stream6));
|
10 | DMA_Cmd(DMA2_Stream3, DISABLE);
|
11 | while(DMA_GetCmdStatus(DMA2_Stream3));
|
12 | DMA_Cmd(DMA2_Stream2, DISABLE);
|
13 | while(DMA_GetCmdStatus(DMA2_Stream2));
|
14 |
|
15 | // interrupt flags
|
16 | DMA2->LISR = 0x00000000;
|
17 | DMA2->HISR = 0x00000000;
|
18 |
|
19 | DMA_SetCurrDataCounter(DMA2_Stream6, PWM_BUFFER_SIZE);
|
20 | DMA_SetCurrDataCounter(DMA2_Stream3, PWM_BUFFER_SIZE);
|
21 | DMA_SetCurrDataCounter(DMA2_Stream2, PWM_BUFFER_SIZE);
|
22 |
|
23 | DMA_Cmd(DMA2_Stream6, ENABLE);
|
24 | DMA_Cmd(DMA2_Stream3, ENABLE);
|
25 | DMA_Cmd(DMA2_Stream2, ENABLE);
|
26 |
|
27 | //clear TIM_DMA_CC3 | TIM_DMA_CC1 | TIM_DMA_CC2
|
28 | //TIM1->EGR &= ~0x38;
|
29 |
|
30 | TIM1->CNT = TIM1->ARR-20;// LÖSUNG!!!!!!!!!!
|
31 |
|
32 | TIM_DMACmd(TIM1, TIM_DMA_CC3 | TIM_DMA_CC1 | TIM_DMA_CC2, ENABLE);
|
33 |
|
34 | TIM_Cmd(TIM1 , ENABLE);
|
35 | __enable_irq();
|