Hallo zusammen Ich verwende das STM32L152RCT6 Discovery-Board von ST. Ich will an einem Ausgang ein PWM Signal erzeugen. Die Realisierung des PWM's soll über die DMA erfolgen. Ich kann das PWM Signal erfolgreich erzeugen. Zum Testen habe ich die PWM Werte 0x00 und 0xFF gesetzt. Am Ausgang erwarte ich ein 50% Duty-Cycle PWM Signal. Das Signal, welches ich am Ausgang messe, stimmt nicht mit den Erwartungen überein. Der Wert 0xFF stimmt, jedoch der Wert 0x00 ist doppelt so lang als erwartet. Folgend ist mein Init Code aufgeführt. Was mache ich falsch, weshalb die beiden Periodendauer verschieden sind? Die Periode des Timers ist auf TIM_Period = 0xFFFF und somit sollte diese doch konstant sein? Vielen Dank für eure Hilfe Gruss
1 | void vInitPWM(void) { |
2 | GPIO_InitTypeDef GPIO_InitStructure; |
3 | TIM_TimeBaseInitTypeDef TimerInitStructure; |
4 | TIM_OCInitTypeDef OutputChannelInit; |
5 | NVIC_InitTypeDef NVIC_InitStructure; |
6 | |
7 | // GPIO
|
8 | RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); |
9 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; |
10 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; |
11 | GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; |
12 | GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; |
13 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz; |
14 | GPIO_Init(GPIOB, &GPIO_InitStructure); |
15 | GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_TIM2); |
16 | |
17 | // TIMER
|
18 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); |
19 | TimerInitStructure.TIM_Prescaler = 0; |
20 | TimerInitStructure.TIM_CounterMode = TIM_CounterMode_Up; |
21 | TimerInitStructure.TIM_Period = 0xFFFF; |
22 | TimerInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; |
23 | TIM_TimeBaseInit(TIM2, &TimerInitStructure); |
24 | |
25 | //PWM CHANNEL
|
26 | |
27 | OutputChannelInit.TIM_OCMode = TIM_OCMode_PWM1; |
28 | OutputChannelInit.TIM_Pulse = 0; |
29 | OutputChannelInit.TIM_OutputState = TIM_OutputState_Enable; |
30 | OutputChannelInit.TIM_OCPolarity = TIM_OCPolarity_Low; |
31 | |
32 | TIM_OC4Init(TIM2, &OutputChannelInit); |
33 | TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable); |
34 | |
35 | TIM_ARRPreloadConfig(TIM2, ENABLE); |
36 | |
37 | TIM_CCxCmd(TIM2, TIM_Channel_4, TIM_CCx_Enable); |
38 | TIM_Cmd(TIM2, ENABLE); |
39 | |
40 | // DMA
|
41 | RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); |
42 | TIM_DMACmd(TIM2, TIM_DMA_CC4, ENABLE); |
43 | DMA_ITConfig(DMA1_Channel7, DMA_IT_TC, ENABLE); |
44 | |
45 | // NVIC for DMA
|
46 | NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn; |
47 | NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; |
48 | NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; |
49 | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; |
50 | NVIC_Init(&NVIC_InitStructure); |
51 | }
|
1 | void vStartDMA(uint8_t *PtrDataToSend, uint16_t LengthOfData) { |
2 | /* DMA Channel7 Configuration ----------------------------------------------*/
|
3 | DMA_InitTypeDef DMAInitStructure; |
4 | |
5 | if (!DMA_BUSY) { |
6 | DMA_BUSY = TRUE; |
7 | DMAInitStructure.DMA_DIR = DMA_DIR_PeripheralDST, |
8 | DMAInitStructure.DMA_BufferSize = LengthOfData, |
9 | DMAInitStructure.DMA_MemoryBaseAddr = (uint32_t) PtrDataToSend, |
10 | DMAInitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte, |
11 | DMAInitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable, |
12 | DMAInitStructure.DMA_Mode = DMA_Mode_Normal, |
13 | DMAInitStructure.DMA_PeripheralBaseAddr = (uint32_t) & TIM2->CCR4, |
14 | DMAInitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte, |
15 | DMAInitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable, |
16 | DMAInitStructure.DMA_Priority = DMA_Priority_VeryHigh, |
17 | DMAInitStructure.DMA_M2M = DMA_M2M_Disable; |
18 | |
19 | DMA_Cmd(DMA1_Channel7, DISABLE); |
20 | DMA_Init(DMA1_Channel7, &DMAInitStructure); |
21 | DMA_Cmd(DMA1_Channel7, ENABLE); |
22 | TIM_DMACmd(TIM2, TIM_DMA_CC4, ENABLE); |
23 | }
|
24 | }
|
1 | void DMA1_Channel7_IRQHandler() |
2 | {
|
3 | disableInterrupts(); |
4 | |
5 | //NoInterrupts lock;
|
6 | DMA_ClearITPendingBit(DMA1_IT_TC7); |
7 | DMA_Cmd(DMA1_Channel7, DISABLE); |
8 | |
9 | DMA_BUSY = FALSE; |
10 | enableInterrupts(); |
11 | }
|