Добрый день, форумчане. Возникла проблема при генерировании ШИМ. Задаю массив из трех чисел и передавал их через DMA Код: uint16_t data[3] = { 100, 250, 400 }; HAL_TIM_PWM_Start_DMA(&htim4, TIM_CHANNEL_1, (uint32_t*)data, 3); Но генерирование начинается со скважности, которая была указана изначально при настройке (там стоит скважность 250) и только потом уже идет генерирование с необходимой скважностью. Понятно, что данные в ARR и CCRx обновляются при событии UEV, но проблема в том, что генерирование события через Код: htim4.Instance->EGR |= TIM_EGR_UG; htim4.Instance->SR &= ~TIM_SR_UIF; не дает никакого эффекта. При пошаговой отладке (использую Stm32CubeIDE) заметил что регистр EGR не активен, т.е. ни стоит никаких значений... Сделал следующим образом: Код: uint16_t data[3] = { 100, 250, 400 }; TIM_OC_InitTypeDef sConfigOC = {0}; sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = data[0]; sConfigOC.OCPolarity = TIM_OCPOLARITY_LOW; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) { Error_Handler(); } htim4.Instance->EGR |= TIM_EGR_UG; htim4.Instance->SR &= ~TIM_SR_UIF; HAL_TIM_PWM_Start_DMA(&htim4, TIM_CHANNEL_1, (uint32_t*)data, 3); Но в этом случает получается, что дважды генерируется сигнал с первым значение скважности, т.е. со значение 100. Вот то что нагенерировал Куб: Код: void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base) { if(htim_base->Instance==TIM4) { /* USER CODE BEGIN TIM4_MspInit 0 */ /* USER CODE END TIM4_MspInit 0 */ /* Peripheral clock enable */ __HAL_RCC_TIM4_CLK_ENABLE(); /* TIM4 DMA Init */ /* TIM4_CH1 Init */ hdma_tim4_ch1.Instance = DMA1_Channel1; hdma_tim4_ch1.Init.Request = DMA_REQUEST_6; hdma_tim4_ch1.Init.Direction = DMA_MEMORY_TO_PERIPH; hdma_tim4_ch1.Init.PeriphInc = DMA_PINC_DISABLE; hdma_tim4_ch1.Init.MemInc = DMA_MINC_ENABLE; hdma_tim4_ch1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; hdma_tim4_ch1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; hdma_tim4_ch1.Init.Mode = DMA_NORMAL; hdma_tim4_ch1.Init.Priority = DMA_PRIORITY_VERY_HIGH; if (HAL_DMA_Init(&hdma_tim4_ch1) != HAL_OK) { Error_Handler(); } __HAL_LINKDMA(htim_base,hdma[TIM_DMA_ID_CC1],hdma_tim4_ch1); /* USER CODE BEGIN TIM4_MspInit 1 */ /* USER CODE END TIM4_MspInit 1 */ } } void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(htim->Instance==TIM4) { /* USER CODE BEGIN TIM4_MspPostInit 0 */ /* USER CODE END TIM4_MspPostInit 0 */ __HAL_RCC_GPIOB_CLK_ENABLE(); /**TIM4 GPIO Configuration PB6 ------> TIM4_CH1 */ GPIO_InitStruct.Pin = GPIO_PIN_6; GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF2_TIM4; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* USER CODE BEGIN TIM4_MspPostInit 1 */ /* USER CODE END TIM4_MspPostInit 1 */ } } /** * @brief TIM_Base MSP De-Initialization * This function freeze the hardware resources used in this example * @param htim_base: TIM_Base handle pointer * @retval None */ void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base) { if(htim_base->Instance==TIM4) { /* USER CODE BEGIN TIM4_MspDeInit 0 */ /* USER CODE END TIM4_MspDeInit 0 */ /* Peripheral clock disable */ __HAL_RCC_TIM4_CLK_DISABLE(); /* TIM4 DMA DeInit */ HAL_DMA_DeInit(htim_base->hdma[TIM_DMA_ID_CC1]); /* USER CODE BEGIN TIM4_MspDeInit 1 */ /* USER CODE END TIM4_MspDeInit 1 */ } } С HAL опыта мало, в основном использовал только CMSIS, но сейчас необходимо сделать через HAL. Пните, где я натупил. Спасибо.
Немного затупил После генерирования события UEV я снова передаю 3 величины скважности и получаю дублирование двух одинаковых интервалов. Код: uint16_t data[3] = { 100, 250, 400 }; TIM_OC_InitTypeDef sConfigOC = {0}; sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = data[0]; sConfigOC.OCPolarity = TIM_OCPOLARITY_LOW; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) { Error_Handler(); } htim4.Instance->EGR |= TIM_EGR_UG; htim4.Instance->SR &= ~TIM_SR_UIF; HAL_TIM_PWM_Start_DMA(&htim4, TIM_CHANNEL_1, (uint32_t*)&data[1], sizeof(data) - 1); Так заработало нормально