We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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(); }