2023-10-11 12:49 AM - edited 2023-10-11 12:51 AM
I'm struggling to get DMA working on a PWM Timer. I've read just about everything i can, but it is not working.
Running this code.. produces a PWM signal as expected on the output.
/* USER CODE BEGIN 2 */
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);
However, when I swap the code to the following, all I get is a one duty signal. It never produces a two duty PWM at all.
/* USER CODE BEGIN 2 */
neo_data[0] = 52; //104(puls)/2
neo_data[1] = 26; //104/4
HAL_TIM_PWM_Start_DMA(&htim3, TIM_CHANNEL_2, (uint32_t *)neo_data, 2); //tim3 ch2
My expectation is that it should this. (youtube((4) STM32F103 네오픽셀 제어(Live Coding) - YouTube) capture)
I have my scope on single shot, and triggered correctly.
I have DMA setup for the timer
2023-10-11 02:35 AM - edited 2023-10-11 02:55 AM
Welcome @Heidi to ST Community,
From what I understood, you want to change the timer's duty cycle using DMA. your code looks fine
But notice that the APB1 timer clock is running at 84 MHz (you're interested in APB1 since TIM3 is connected to the APB1 clock as you can see in your product datasheet :
So, you need to change that value (45MHz) in the clock tree, and since you're using a prescaler 0 that means you are dividing this frequency by 1.
By choosing ARR=100, you are dividing this frequency by 100 => 45KHz ( this will give you the advantage of changing the duty cycle to a percentage of 100)
for example :
neo_data[0] = 50; // 50% duty cycle
neo_data[1] = 30; // 30% duty cycle
Your DMA setup looks functional and it should work!
Edit: I've realized that you're configuring the pulse value in the TIM config, since you're changing the duty cycle in the code, leave the Pulse value as default (0).
Try that and you can always come back if there is an issue
Hope that helps!
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2023-10-11 03:52 AM
Read out and check/post content of TIM and DMA registers.
JW
2023-10-11 06:53 AM
Hello, @Sarra.S
Thank you for your support.
I tried change the parameter settings
APB1 Timer clocks (MHz) : 42
TIM3 CH2
PSC: 0
ARR : 100
Pulse : 0
/* USER CODE BEGIN 0 */
uint8_t neo_data[2];
/* USER CODE BEGIN 2 */
neo_data[0] = 50; //duty 50%
neo_data[1] = 30; //duty
HAL_TIM_PWM_Start_DMA(&htim3, TIM_CHANNEL_2, (uint32_t *)neo_data, 2);
However, when I swap the code to the following, all I get is a one duty signal.
But I want to see 50% 30% duty..
Running this code.. (TIM parameter setting Pulse : 50)
produces a PWM signal as expected on the output.
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);
2023-10-11 07:02 AM
Try defining neo_data as a uint16_t or uint32_t array instead. It definitely shouldn't be uint8_t.
2023-10-11 07:15 AM
Yes, I missed this line :
uint8_t neo_data[2];
I thought it was declared in PV section, uint8_t is definitely incompatible with a parameter of type uint32_t in HAL_TIM_PWM_Start_DMA
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2023-10-11 08:03 PM
I don't know how I can produce diffirent duty like this..
In my code have like this
HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
{
...
}
so I running this code (uint32_t *)neo_data
HAL_TIM_PWM_Start_DMA(&htim3, TIM_CHANNEL_2, (uint32_t *)neo_data, 2);
What do I need to fix in my code to output a PWM with a different duty cycle?