Hello,
I'm tyring to program a STM32F4 (with ARM F4) board to generate a sinusoidal PWM, that is a sequence of pulses with variable width that, once filtered by a LPF, gives a sinusoid.
I was told the best way to get it is by generating a sequence of single pulses synchronized to timer by interrupts.
I've tried several solutions but I'm not good at managing interrupts.
Do you have any idea how to achieve this goal? Can you attach a piece of code where it's explained how to do it?
Thanks in advance! ;)
Mara
Hi Clive,
There is below the code I've modified starting from the code you've posted.
I used the library functions associated to my board (STM32F401RE) and not the functions of the standard library, but the firmware didn't work: I have no signal at output.
Do you have any idea why it doesn't work?
Thanks, Mara
#include "stm32f4xx_hal.h" #include "stm324x9i_eval.h" #include "stm32f4xx_hal_tim.h" #include "core_cm4.h" /* Private typedef -----------------------------------------------------------*/ #define Period_Value (1000-1) /* Period Value */ // Timer handler declaration TIM_HandleTypeDef TimHandle; // OC structure definition TIM_OC_InitTypeDef OCConfig; // GPIO PWM structure definition GPIO_InitTypeDef GPIOConfig; // Counter Prescaler value uint32_t uwPrescalerValue = 0; int sintable[300] = {250,255,260,266,271,...}; // max sin value = 500 /* Function prototypes -----------------------------------------------*/ static void SystemClock_Config(void); static void Timer_Config(void); static void GPIO_Config(void); static void Timer_OC (void); static void NVIC_Config(void); int main(void) { // Hal library initialization HAL_Init(); // Set Systemclock @ 180 Mhz SystemClock_Config(); // Timer configuration Timer_Config(); // "Output compare mode" configuration Timer_OC(); // TIM2 interrupt configuration NVIC_Config(), // Output PIN configuration GPIO_Config(); // Infitite cycle while (1) { } } /** * @brief System Clock Configuration * The system Clock is configured as follow : * System Clock source = PLL (HSE) * SYSCLK(Hz) = 180000000 * HCLK(Hz) = 180000000 * AHB Prescaler = 1 * APB1 Prescaler = 4 * APB2 Prescaler = 2 * HSE Frequency(Hz) = 25000000 * PLL_M = 25 * PLL_N = 360 * PLL_P = 2 * PLL_Q = 7 * VDD(V) = 3.3 * Main regulator output voltage = Scale1 mode * Flash Latency(WS) = 5 * @param None * @retval None */ static void SystemClock_Config(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; /* Enable Power Control clock */ __HAL_RCC_PWR_CLK_ENABLE(); /* The voltage scaling allows optimizing the power consumption when the device is clocked below the maximum system frequency, to update the voltage scaling value regarding system frequency refer to product datasheet. */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /* Enable HSE Oscillator and activate PLL with HSE as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = 25; RCC_OscInitStruct.PLL.PLLN = 360; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 7; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* Activate the Over-Drive mode */ HAL_PWREx_EnableOverDrive(); /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5); } void Timer_Config() { /* Compute the prescaler value to have TIM2 counter clock equal to 7,5 MHz */ uwPrescalerValue = ((SystemCoreClock /2) / 7500000) - 1; /* Configure the TIM peripheral */ /* Initialize TIMx peripheral as follow: + Prescaler = (SystemCoreClock/2)/10000000 + Period = 500 (to have an output frequency equal to 15 KHz) + ClockDivision = 0 + Counter direction = Up */ TimHandle.Instance = TIM2; TimHandle.Init.Prescaler = uwPrescalerValue; TimHandle.Init.Period = Period_Value; TimHandle.Init.ClockDivision = 0; TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP; TimHandle.Init.RepetitionCounter = 0; HAL_TIM_Base_Init(&TimHandle); } void Timer_OC() { OCConfig.OCMode = TIM_OCMODE_PWM1; OCConfig.OCPolarity = TIM_OCPOLARITY_HIGH; OCConfig.Pulse = sintable[0]; OCConfig.OCPolarity = TIM_ICPOLARITY_RISING; // OCConfig.OCIdleState = TIM_OCIDLESTATE_RESET only for TIM1 e TIM8 HAL_TIM_OC_Init(&TimHandle); } void NVIC_Config() { // Enable the TIM2 associated interrupt HAL_NVIC_EnableIRQ(TIM2_IRQn); // Set interrupt priority HAL_NVIC_SetPriority(TIM2_IRQn, 1, 0); } void TIM2_IRQHandler(void) { static int index = 0; if (HAL_NVIC_GetPendingIRQ(TIM2_IRQn) != RESET) { HAL_NVIC_ClearPendingIRQ(TIM2_IRQn); TIM2->CCR1 = sintable[index]; index = (index + 1) % 300; } } void GPIO_Config() { // Enable clock for GPIOs __GPIOA_CLK_ENABLE(); GPIOConfig.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2; GPIOConfig.Mode = GPIO_MODE_AF_PP; GPIOConfig.Pull = GPIO_NOPULL; GPIOConfig.Speed = GPIO_SPEED_HIGH; HAL_GPIO_Init(GPIOA, &GPIOConfig); } #ifdef USE_FULL_ASSERT void assert_failed(uint8_t* file, uint32_t line) { /* Infinite loop */ while (1) { } } #endif
I'm not using HAL/Cube, you're on your own there.
But the 401RE doesn't not run at 180MHz, it's a part limited to 84 MHz as I recall
try using a table for the values 1 7 8 1 5 23 7 6 3 6 5 45 3 5 7 5 4 34 5 7 6 45 3 4 56 5 6 34 43 5 4 3 43 5 5 4 3 3 4 5 6 7 87 65 5 65 6 4 342 4 5 54 3 3 43 5 53 34 34 35 5 5 4 32 2 1 34 56 47 45 45 3 3 8 2 67 7 54 56 643 346 436 1 7 8 1 5 23 7 6 3 6 5 45 3 5 7 5 4 34 5 7 6 45 3 4 56 5 6 34 43 5 4 3 43 5 5 4 3 3 4 5 6 7 87 65 5 65 6 4 342 4 5 54 3 3 43 5 53 34 34 35 5 5 4 32 2 1 34 56 47 45 45 3 3 8 2 67 7 54 56 643 346 436 1 7 8 1 5 23 7 6 3 6 5 45 3 5 7 5 4 34 5 7 6 45 3 4 56 5 6 34 43 5 4 3 43 5 5 4 3 3 4 5 6 7 87 65 5 65 6 4 342 4 5 54 3 3 43 5 53 34 34 35 5 5 4 32 2 1 34 56 47 45 45 3 3 8 2 67 7 54 56 643 346 436 1 7 8 1 5 23 7 6 3 6 5 45 3 5 7 5 4 34 5 7 6 45 3 4 56 5 6 34 43 5 4 3 43 5 5 4 3 3 4 5 6 7 87 65 5 65 6 4 342 4 5 54 3 3 43 5 53 34 34 35 5 5 4 32 2 1 34 56 47 45 45 3 3 8 2 67 7 54 56 643 346 436 1 7 8 1 5 23 7 6 3 6 5 45 3 5 7 5 4 34 5 7 6 45 3 4 56 5 6 34 43 5 4 3 43 5 5 4 3 3 4 5 6 7 87 65 5 65 6 4 342 4 5 54 3 3 43 5 53 34 34 35 5 5 4 32 2 1 34 56 47 45 45 3 3 8 2 67 7 54 56 643 346 436 1 7 8 1 5 23 7 6 3 6 5 45 3 5 7 5 4 34 5 7 6 45 3 4 56 5 6 34 43 5 4 3 43 5 5 4 3 3 4 5 6 7 87 65 5 65 6 4 342 4 5 54 3 3 43 5 53 34 34 35 5 5 4 32 2 1 34 56 47 45 45 3 3 8 2 67 7 54 56 643 346 436 1 7 8 1 5 23 7 6 3 6 5 45 3 5 7 5 4 34 5 7 6 45 3 4 56 5 6 34 43 5 4 3 43 5 5 4 3 3 4 5 6 7 87 65 5 65 6 4 342 4 5 54 3 3 43 5 53 34 34 35 5 5 4 32 2 1 34 56 47 45 45 3 3 8 2 67 7 54 56 643 346 436 1 7 8 1 5 23 7 6 3 6 5 45 3 5 7 5 4 34 5 7 6 45 3 4 56 5 6 34 43 5 4 3 43 5 5 4 3 3 4 5 6 7 87 65 5 65 6 4 342 4 5 54 3 3 43 5 53 34 34 35 5 5 4 32 2 1 34 56 47 45 45 3 3 8 2 67 7 54 56 643 346 436 1 7 8 1 5 23 7 6 3 6 5 45 3 5 7 5 4 34 5 7 6 45 3 4 56 5 6 34 43 5 4 3 43 5 5 4 3 3 4 5 6 7 87 65 5 65 6 4 342 4 5 54 3 3 43 5 53 34 34 35 5 5 4 32 2 1 34 56 47 45 45 3 3 8 2 67 7 54 56 643 346 436 1 7 8 1 5 23 7 6 3 6 5 45 3 5 7 5 4 34 5 7 6 45 3 4 56 5 6 34 43 5 4 3 43 5 5 4 3 3 4 5 6 7 87 65 5 65 6 4 342 4 5 54 3 3 43 5 53 34 34 35 5 5 4 32 2 1 34 56 47 45 45 3 3 8 2 67 7 54 56 643 346 436 1 7 8 1 5 23 7 6 3 6 5 45 3 5 7 5 4 34 5 7 6 45 3 4 56 5 6 34 43 5 4 3 43 5 5 4 3 3 4 5 6 7 87 65 5 65 6 4 342 4 5 54 3 3 43 5 53 34 34 35 5 5 4 32 2 1 34 56 47 45 45 3 3 8 2 67 7 54 56 643 346 436 1 7 8 1 5 23 7 6 3 6 5 45 3 5 7 5 4 34 5 7 6 45 3 4 56 5 6 34 43 5 4 3 43 5 5 4 3 3 4 5 6 7 87 65 5 65 6 4 342 4 5 54 3 3 43 5 53 34 34 35 5 5 4 32 2 1 34 56 47 45 45 3 3 8 2 67 7 54 56 643 346 436 1 7 8 1 5 23 7 6 3 6 5 45 3 5 7 5 4 34 5 7 6 45 3 4 56 5 6 34 43 5 4 3 43 5 5 4 3 3 4 5 6 7 87 65 5 65 6 4 342 4 5 54 3 3 43 5 53 34 34 35 5 5 4 32 2 1 34 56 47 45 45 3 3 8 2 67 7 54 56 643 346 436 1 7 8 1 5 23 7 6 3 6 5 45 3 5 7 5 4 34 5 7 6 45 3 4 56 5 6 34 43 5 4 3 43 5 5 4 3 3 4 5 6 7 87 65 5 65 6 4 342 4 5 54 3 3 43 5 53 34 34 35 5 5 4 32 2 1 34 56 47 45 45 3 3 8 2 67 7 54 56 643 346 436 1 7 8 1 5 23 7 6 3 6 5 45 3 5 7 5 4 34 5 7 6 45 3 4 56 5 6 34 43 5 4 3 43 5 5 4 3 3 4 5 6 7 87 65 5 65 6 4 342 4 5 54 3 3 43 5 53 34 34 35 5 5 4 32 2 1 34 56 47 45 45 3 3 8 2 67 7 54 56 643 346 436 1 7 8 1 5 23 7 6 3 6 5 45 3 5 7 5 4 34 5 7 6 45 3 4 56 5 6 34 43 5 4 3 43 5 5 4 3 3 4 5 6 7 87 65 5 65 6 4 342 4 5 54 3 3 43 5 53 34 34 35 5 5 4 32 2 1 34 56 47 45 45 3 3 8 2 67 7 54 56 643 346 436 1 7 8 1 5 23 7 6 3 6 5 45 3 5 7 5 4 34 5 7 6 45 3 4 56 5 6 34 43 5 4 3 43 5 5 4 3 3 4 5 6 7 87 65 5 65 6 4 342 4 5 54 3 3 43 5 53 34 34 35 5 5 4 32 2 1 34 56 47 45 45 3 3 8 2 67 7 54 56 643 346 436 1 7 8 1 5 23 7 6 3 6 5 45 3 5 7 5 4 34 5 7 6 45 3 4 56 5 6 34 43 5 4 3 43 5 5 4 3 3 4 5 6 7 87 65 5 65 6 4 342 4 5 54 3 3 43 5 53 34 34 35 5 5 4 32 2 1 34 56 47 45 45 3 3 8 2 67 7 54 56 643 346 436 1 7 8 1 5 23 7 6 3 6 5 45 3 5 7 5 4 34 5 7 6 45 3 4 56 5 6 34 43 5 4 3 43 5 5 4 3 3 4 5 6 7 87 65 5 65 6 4 342 4 5 54 3 3 43 5 53 34 34 35 5 5 4 32 2 1 34 56 47 45 45 3 3 8 2 67 7 54 56 643 346 436 1 7 8 1 5 23 7 6 3 6 5 45 3 5 7 5 4 34 5 7 6 45 3 4 56 5 6 34 43 5 4 3 43 5 5 4 3 3 4 5 6 7 87 65 5 65 6 4 342 4 5 54 3 3 43 5 53 34 34 35 5 5 4 32 2 1 34 56 47 45 45 3 3 8 2 67 7 54 56 643 346 436 1 7 8 1 5 23 7 6 3 6 5 45 3 5 7 5 4 34 5 7 6 45 3 4 56 5 6 34 43 5 4 3 43 5 5 4 3 3 4 5 6 7 87 65 5 65 6 4 342 4 5 54 3 3 43 5 53 34 34 35 5 5 4 32 2 1 34 56 47 45 45 3 3 8 2 67 7 54 56 643 346 436 1 7 8 1 5 23 7 6 3 6 5 45 3 5 7 5 4 34 5 7 6 45 3 4 56 5 6 34 43 5 4 3 43 5 5 4 3 3 4 5 6 7 87 65 5 65 6 4 342 4 5 54 3 3 43 5 53 34 34 35 5 5 4 32 2 1 34 56 47 45 45 3 3 8 2 67 7 54 56 643 346 436 1 7 8 1 5 23 7 6 3 6 5 45 3 5 7 5 4 34 5 7 6 45 3 4 56 5 6 34 43 5 4 3 43 5 5 4 3 3 4 5 6 7 87 65 5 65 6 4 342 4 5 54 3 3 43 5 53 34 34 35 5 5 4 32 2 1 34 56 47 45 45 3 3 8 2 67 7 54 56 643 346 436 1 7 8 1 5 23 7 6 3 6 5 45 3 5 7 5 4 34 5 7 6 45 3 4 56 5 6 34 43 5 4 3 43 5 5 4 3 3 4 5 6 7 87 65 5 65 6 4 342 4 5 54 3 3 43 5 53 34 34 35 5 5 4 32 2 1 34 56 47 45 45 3 3 8 2 67 7 54 56 643 346 436 1 7 8 1 5 23 7 6 3 6 5 45 3 5 7 5 4 34 5 7 6 45 3 4 56 5 6 34 43 5 4 3 43 5 5 4 3 3 4 5 6 7 87 65 5 65 6 4 342 4 5 54 3 3 43 5 53 34 34 35 5 5 4 32 2 1 34 56 47 45 45 3 3 8 2 67 7 54 56 643 346 436 1 7 8 1 5 23 7 6 3 6 5 45 3 5 7 5 4 34 5 7 6 45 3 4 56 5 6 34 43 5 4 3 43 5 5 4 3 3 4 5 6 7 87 65 5 65 6 4 342 4 5 54 3 3 43 5 53 34 34 35 5 5 4 32 2 1 34 56 47 45 45 3 3 8 2 67 7 54 56 643 346 436 1 7 8 1 5 23 7 6 3 6 5 45 3 5 7 5 4 34 5 7 6 45 3 4 56 5 6 34 43 5 4 3 43 5 5 4 3 3 4 5 6 7 87 65 5 65 6 4 342 4 5 54 3 3 43 5 53 34 34 35 5 5 4 32 2 1 34 56 47 45 45 3 3 8 2 67 7 54 56 643 346 436 1 7 8 1 5 23 7 6 3 6 5 45 3 5 7 5 4 34 5 7 6 45 3 4 56 5 6 34 43 5 4 3 43 5 5 4 3 3 4 5 6 7 87 65 5 65 6 4 342 4 5 54 3 3 43 5 53 34 34 35 5 5 4 32 2 1 34 56 47 45 45 3 3 8 2 67 7 54 56 643 346 436 1 7 8 1 5 23 7 6 3 6 5 45 3 5 7 5 4 34 5 7 6 45 3 4 56 5 6 34 43 5 4 3 43 5 5 4 3 3 4 5 6 7 87 65 5 65 6 4 342 4 5 54 3 3 43 5 53 34 34 35 5 5 4 32 2 1 34 56 47 45 45 3 3 8 2 67 7 54 56 643 346 436 1 7 8 1 5 23 7 6 3 6 5 45 3 5 7 5 4 34 5 7 6 45 3 4 56 5 6 34 43 5 4 3 43 5 5 4 3 3 4 5 6 7 87 65 5 65 6 4 342 4 5 54 3 3 43 5 53 34 34 35 5 5 4 32 2 1 34 56 47 45 45 3 3 8 2 67 7 54 56 643 346 436
Hi Mara,
have a look at the "stm32f4xx_hal_tim.h". I can't see that you are starting the timer. Try one of the functions in the mentioned header file e.g. "HAL_TIM_Base_Start_IT". The function "HAL_TIM_Base_Start_DMA" might also be interesting for you. Try to find out which one of the functions you need as I'm also not as familiar with the HAL of ST.
Also, as Clive said, be careful with the frequency you want to run the timer with and with choosing the prescaler. The clock the timers are running with is not always the system clock. In ST's datasheets you always find an "block diagram" of the controller. In that picture you can see the maximum possible frequency the timer can run with, which is also most likely the frequency that will be configured for the timer. Good luck!
Regards, Niclas
Also, at the beginning of the corresponding c-file to the driver's header-file there is always a section "##### How to use this driver #####". Have a look at that section in the "stm32f4xx_hal_tim.c". I think it mentions some function-calls which are missing in your code.
Thanks for your advices, I'll let you know!
I want to create 5kHz sin wave and I used the code which you shared. I have to set 500kHz sampling frequency for 5 kHz sin wave. What should be cut off frequency RC filter for 5kHz sinwave?
Best regards,