我有一个 STM32G071 nucleo,想通过 tiM2-CH1 在 PA0 上生成任意波形。
我正在使用 HAL_TIM_DMABurst_MultiWriteStart API:它应该对多个寄存器(ARR 和 CCR1)执行 3 次突发写入。
问题是,DMA 只更新 ARR(而不是 ARR + RCR + CCR1)并且只更新一次(而不是两次突发)。如果我将基址寄存器更改为 CCR1,它只会更新 CCR1 一次。
我看到了这一点,因为我在核心停止时冻结了计时器,并且我向 HAL_TIM_PeriodElapsedHalfCpltCallback 和 HAL_TIM_PeriodElapsedCallback 添加了断点(输出波形为 BS)。
正常或循环模式具有相同的效果。
这是主要代码:
- __HAL_DBGMCU_FREEZE_TIM2();
- uint32_t buffer32b[6] = {10, 0, 30, 100, 0, 300};
- HAL_StatusTypeDef result;
- result = HAL_TIM_DMABurst_MultiWriteStart(&htim2, TIM_DMABASE_ARR, TIM_DMA_UPDATE, buffer32b, TIM_DMABURSTLENGTH_3TRANSFERS, 6);
- result = HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
我检查的所有寄存器对我来说都很好。
这可能是硬件问题吗?
完整代码附在下面(它只为 64MHz 操作设置 HSI 并相应地配置 TIM2 和 DMA,然后启动 TIM-DMA 操作):
- #include "main.h"
- /* Private variables ---------------------------------------------------------*/
- TIM_HandleTypeDef htim2;
- DMA_HandleTypeDef hdma_tim2_up;
- /* Private function prototypes -----------------------------------------------*/
- void SystemClock_Config(void);
- static void MX_GPIO_Init(void);
- static void MX_DMA_Init(void);
- static void MX_TIM2_Init(void);
- int main(void)
- {
- HAL_Init();
- SystemClock_Config();
- MX_GPIO_Init();
- MX_DMA_Init();
- MX_TIM2_Init();
- __HAL_DBGMCU_FREEZE_TIM2();
- uint32_t buffer32b[6] = {10, 0, 30, 100, 0, 300};
- HAL_StatusTypeDef result;
- result = HAL_TIM_DMABurst_MultiWriteStart(&htim2, TIM_DMABASE_ARR, TIM_DMA_UPDATE, buffer32b, TIM_DMABURSTLENGTH_3TRANSFERS, 6);
- result = HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
- while (1)
- {
- }
- }
- void SystemClock_Config(void)
- {
- RCC_OscInitTypeDef RCC_OscInitStruct = {0};
- RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
- /** Configure the main internal regulator output voltage
- */
- HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);
- /** Initializes the RCC Oscillators according to the specified parameters
- * in the RCC_OscInitTypeDef structure.
- */
- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
- RCC_OscInitStruct.HSIState = RCC_HSI_ON;
- RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;
- RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
- RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
- RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
- RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1;
- RCC_OscInitStruct.PLL.PLLN = 8;
- RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
- RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
- RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
- if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
- {
- Error_Handler();
- }
- /** Initializes the CPU, AHB and APB buses clocks
- */
- RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
- |RCC_CLOCKTYPE_PCLK1;
- RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
- RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
- RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
- if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
- {
- Error_Handler();
- }
- }
- static void MX_TIM2_Init(void)
- {
- TIM_ClockConfigTypeDef sClockSourceConfig = {0};
- TIM_MasterConfigTypeDef sMasterConfig = {0};
- TIM_OC_InitTypeDef sConfigOC = {0};
- htim2.Instance = TIM2;
- htim2.Init.Prescaler = 63;
- htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
- htim2.Init.Period = 10000;
- htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
- htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
- if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
- {
- Error_Handler();
- }
- sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
- if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
- {
- Error_Handler();
- }
- if (HAL_TIM_PWM_Init(&htim2) != HAL_OK)
- {
- Error_Handler();
- }
- sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
- sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
- if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
- {
- Error_Handler();
- }
- sConfigOC.OCMode = TIM_OCMODE_PWM1;
- sConfigOC.Pulse = 0;
- sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
- sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
- if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
- {
- Error_Handler();
- }
- HAL_TIM_MspPostInit(&htim2);
- }
- static void MX_DMA_Init(void)
- {
- /* DMA controller clock enable */
- __HAL_RCC_DMA1_CLK_ENABLE();
- /* DMA interrupt init */
- /* DMA1_Channel1_IRQn interrupt configuration */
- HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
- HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
- }
- static void MX_GPIO_Init(void)
- {
- /* GPIO Ports Clock Enable */
- __HAL_RCC_GPIOA_CLK_ENABLE();
- }
- void Error_Handler(void)
- {
- __disable_irq();
- while (1)
- {
- }
- }
- void HAL_MspInit(void)
- {
- __HAL_RCC_SYSCFG_CLK_ENABLE();
- __HAL_RCC_PWR_CLK_ENABLE();
- /* System interrupt init*/
- /** Disable the internal Pull-Up in Dead Battery pins of UCPD peripheral
- */
- HAL_SYSCFG_StrobeDBattpinsConfig(SYSCFG_CFGR1_UCPD1_STROBE | SYSCFG_CFGR1_UCPD2_STROBE);
- }
- void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
- {
- if(htim_base->Instance==TIM2)
- {
- /* Peripheral clock enable */
- __HAL_RCC_TIM2_CLK_ENABLE();
- /* TIM2 DMA Init */
- /* TIM2_UP Init */
- hdma_tim2_up.Instance = DMA1_Channel1;
- hdma_tim2_up.Init.Request = DMA_REQUEST_TIM2_UP;
- hdma_tim2_up.Init.Direction = DMA_PERIPH_TO_MEMORY;
- hdma_tim2_up.Init.PeriphInc = DMA_PINC_DISABLE;
- hdma_tim2_up.Init.MemInc = DMA_MINC_ENABLE;
- hdma_tim2_up.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
- hdma_tim2_up.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
- hdma_tim2_up.Init.Mode = DMA_CIRCULAR;
- hdma_tim2_up.Init.Priority = DMA_PRIORITY_LOW;
- if (HAL_DMA_Init(&hdma_tim2_up) != HAL_OK)
- {
- Error_Handler();
- }
- __HAL_LINKDMA(htim_base,hdma[TIM_DMA_ID_UPDATE],hdma_tim2_up);
- }
- }
- void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim)
- {
- GPIO_InitTypeDef GPIO_InitStruct = {0};
- if(htim->Instance==TIM2)
- {
- __HAL_RCC_GPIOA_CLK_ENABLE();
- /**TIM2 GPIO Configuration
- PA0 ------> TIM2_CH1
- */
- GPIO_InitStruct.Pin = GPIO_PIN_0;
- GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
- GPIO_InitStruct.Alternate = GPIO_AF2_TIM2;
- HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
- }
- }
0
|
1个回答
|
|
|