hi, I'm trying to get a sine-pwm signal on my STM32f103rct6. I'm using STM32cube with keil. In an old post i've read that i can pass the sine-tables to the dma or use the irq. In my case i wanted to use the dma. My goal is to have a pulse frequency signal of about 23 KHz and sinus period around 100Hz (even less). Moreover I would like to have the same signal on three different channels, but each of them 120 degrees shifted. I just can't set the dma, how can I do? for this moment what i see on my oscilloscope is a quite random but repetitive signal, This probably means that either the dma is too speed or I have badly set the parameters. tips?
#include "main.h" #include "stm32f1xx_hal.h" #define HUNDRED_ELEMENTS #define PULSE 50 #define PUlSE_FREQ 1000 #define SINE_PERIOD 100 #ifdef HUNDRED_ELEMENTS #define PWM_ELEMENTS 100 uint32_t PWM_Buffer[PWM_ELEMENTS] = {0,0,1,2,2,4,5,6,8,10,11,14,16,18,21,23,26,29,32,35,38,41,44,47,50,50,53,56,59,62,65,68,71,74,77,79,82,84,86,89,90,92,94,95,96,98,98,99,100,100,100,100,100,99,98,98,96,95,94,92,90,89,86,84,82,79,77,74,71,68,65,62,59,56,53,50,47,44,41,38,35,32,29,26,23,21,18,16,14,11,10,8,6,5,4,2,2,1,0,0}; #endif TIM_HandleTypeDef htim8; DMA_HandleTypeDef hdma_tim8_ch1; DMA_HandleTypeDef hdma_tim8_ch2; DMA_HandleTypeDef hdma_tim8_ch3_up; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_DMA_Init(void); static void MX_TIM8_Init(void); void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_DMA_Init(); MX_TIM8_Init(); HAL_TIM_Base_Start(&htim8); //activated only 1 channel HAL_TIM_PWM_Start(&htim8,TIM_CHANNEL_1); HAL_TIM_PWM_Start_DMA(&htim8, TIM_CHANNEL_1,PWM_Buffer ,sizeof(PWM_Buffer)); while (1) { } } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct; RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000); HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK); /* SysTick_IRQn interrupt configuration */ HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); } /* TIM8 init function */ static void MX_TIM8_Init(void) { /*Parameters*/ uint32_t TIMER_frequency = HAL_RCC_GetHCLKFreq(); uint32_t PSC_Value = (TIMER_frequency / PUlSE_FREQ) - 1; uint16_t ARR_Value = SINE_PERIOD - 1; /*end*/ TIM_MasterConfigTypeDef sMasterConfig; TIM_OC_InitTypeDef sConfigOC; TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig; htim8.Instance = TIM8; htim8.Init.Prescaler = PSC_Value; htim8.Init.CounterMode = TIM_COUNTERMODE_UP; htim8.Init.Period = ARR_Value; htim8.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim8.Init.RepetitionCounter = 1; htim8.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_PWM_Init(&htim8) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim8, &sMasterConfig) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = PULSE; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET; sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET; if (HAL_TIM_PWM_ConfigChannel(&htim8, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } if (HAL_TIM_PWM_ConfigChannel(&htim8, &sConfigOC, TIM_CHANNEL_2) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } if (HAL_TIM_PWM_ConfigChannel(&htim8, &sConfigOC, TIM_CHANNEL_3) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE; sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE; sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF; sBreakDeadTimeConfig.DeadTime = 0; sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE; sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH; sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE; if (HAL_TIMEx_ConfigBreakDeadTime(&htim8, &sBreakDeadTimeConfig) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } HAL_TIM_MspPostInit(&htim8); } /** * Enable DMA controller clock */ static void MX_DMA_Init(void) { DMA_HandleTypeDef dmahandle; //DMA_InitTypeDef dmaconfig; /* DMA controller clock enable */ __HAL_RCC_DMA2_CLK_ENABLE(); /* DMA interrupt init */ /* DMA2_Channel1_IRQn interrupt configuration */ HAL_NVIC_SetPriority(DMA2_Channel1_IRQn, 0, 0); HAL_NVIC_EnableIRQ(DMA2_Channel1_IRQn); /* DMA2_Channel3_IRQn interrupt configuration */ HAL_NVIC_SetPriority(DMA2_Channel3_IRQn, 0, 0); HAL_NVIC_EnableIRQ(DMA2_Channel3_IRQn); /* DMA2_Channel4_5_IRQn interrupt configuration */ HAL_NVIC_SetPriority(DMA2_Channel4_5_IRQn, 0, 0); HAL_NVIC_EnableIRQ(DMA2_Channel4_5_IRQn); //DMA init ... I tried to set the dma by hand but it doesn't work /* dmahandle.Init.Mode = DMA_CIRCULAR; dmahandle.State = HAL_DMA_STATE_READY; dmahandle.Init.Direction = DMA_MEMORY_TO_PERIPH; dmahandle.Init.PeriphInc = DMA_PINC_DISABLE; dmahandle.Init.MemInc = DMA_MINC_ENABLE; dmahandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; dmahandle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; // probably missing: Instance, DmaBaseAddress, ChannelIndex e altre cose della lista HAL_DMA_Init(&dmahandle); */ } static void MX_GPIO_Init(void) { __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); }