AT32F4xx_使用DMA动态更新PWM占空比

AT32F4xx_使用DMA动态更新PWM占空比
示例目的
本示例代码基于AT32F403A,展示了如何使用AT32 的TMR 和DMA 动态更新PWM 占空比。
该示例使用TMR4 的更新事件触发DMA1 搬运数据至TMR4 的通道2 数据寄存器(TMRx_C2DT),达到在TMR4 的通道2(PB7)动态输出占空比不同的PWM 波的效果。

支持型号列表:
AT32F403xx
AT32F403Axx
AT32F407xx
AT32F413xx
AT32F415xx
AT32F421xx

主要使用外设列表:
TMR4
DMA

  1. 硬件资源
  1. AT-START-F403A V1.0开发板
  1. 软件资源
  1. 该Demo 以AT32F403A 为例,BSP 版本AT32F403A_407_Firmware_Library_V2.0.6。
  2. TMR 配置:
    配置TMR4 的通道2(PB7)产生PWM 波。
    配置DMA1 并将其请求映射选择为通道7(TMR4 的更新事件),搬运内存中的不同占空比数据至TMR4 的通道2 数据寄存器(TMRx_C2DT),动态更新占空比。
  3. 对main.c 的“src_buffer[]”数组直接做相应修改可配置想要的占空比,数组长度软件会自动计算。
    注: 所有project 都是基于keil 5 而建立, 若用户需要在其他编译环境上使用, 请参考
    AT32xxx_Firmware_Library_V2.x.x\project\at_start_xxx\templates中各种编译环境(例如IAR6/7,keil 4/5)进行简单修
    改即可。
  1. 示例使用
  1. 硬件连接:将PB7(TMR4_CH2)接入逻辑分析仪或示波器。
  2. 打开\SourceCode\SC0069_SourceCode_V2.0.0\utilities\SC0069_Demo\mdk_v5\Duty.uvprojx 源程序,编译后下载到实验板。
  3. 抓取PB7 波形,验证程序效果。当正常运行时,TMR4_CH2(PB7)将按照uint16_t src_buffer[]= {10,20,30,40,50,60,70,80,90,10,20,30,40,50,60,70,80,90};中的变量输出对应占空比的PWM波形,Demo 中的PWM 波形如下图
    图 2. Demo 中 DMA 动态更新 PWM 占空比波形

进版到V2.0.1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32F4系列微控制器的HAL库提供了用于PWMDMA输出方波的函数和接口。 首先,我们需要配置GPIO引脚用于PWM输出。选择合适的引脚并将其配置为替代功能模式。然后,我们可以使用HAL库函数 `HAL_TIM_PWM_Init()` 来进行PWM定时器的初始化,设置周期和占空比。 接下来,我们需要配置DMA以实现连续的方波输出。使用 `HAL_DMA_Init()` 函数来初始化DMA控制器,并设置传输方向和数据宽度。然后,使用 `HAL_DMA_Start()` 函数启动DMA传输。 在方波输出的主循环中,我们可以使用 `HAL_TIM_PWM_Start()` 函数来启动PWM输出。通过更改占空比的值,我们可以实现方波的高电平和低电平持续时间的控制。 最后,我们需要在代码中实现一个循环,以便无限循环发送DMA传输以保持方波的连续输出。 以下是一个简单的示例代码: ''' #include "stm32f4xx_hal.h" #define PWM_TIM TIM1 #define PWM_CHANNEL TIM_CHANNEL_1 #define PWM_FREQ 100 // 指定PWM周期 #define DMA_STREAM DMA2_Stream0 #define DMA_CHANNEL DMA_CHANNEL_5 #define BUFFER_SIZE 2 uint16_t dmaBuffer[BUFFER_SIZE] = {0}; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_DMA_Init(void); static void MX_TIM_Init(void); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_DMA_Init(); MX_TIM_Init(); HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); while (1) { HAL_DMA_Start(&hdma_tim1_ch1, (uint32_t)&dmaBuffer, (uint32_t)&PWM_TIM->CCR1, BUFFER_SIZE); HAL_Delay(1000); } } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; __PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); 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 = 8; RCC_OscInitStruct.PLL.PLLN = 336; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 7; HAL_RCC_OscConfig(&RCC_OscInitStruct); 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_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5); __SYSCFG_CLK_ENABLE(); } static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; __GPIOA_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_8; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF1_TIM1; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } void MX_DMA_Init(void) { __HAL_RCC_DMA2_CLK_ENABLE(); HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0); HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn); } void MX_TIM_Init(void) { TIM_MasterConfigTypeDef sMasterConfig = {0}; TIM_OC_InitTypeDef sConfigOC = {0}; htim1.Instance = TIM1; htim1.Init.Prescaler = 0; htim1.Init.CounterMode = TIM_COUNTERMODE_UP; htim1.Init.Period = (HAL_RCC_GetHCLKFreq() / (PWM_FREQ - 1)); htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; HAL_TIM_PWM_Init(&htim1); sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC1REF; sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE; HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig); sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = ((HAL_RCC_GetHCLKFreq() / (PWM_FREQ - 1)) / 2); sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1); __HAL_TIM_ENABLE_DMA(&htim1, TIM_DMA_CC1); } void DMA2_Stream0_IRQHandler(void) { HAL_DMA_IRQHandler(&hdma_tim1_ch1); } ''' 这是一个简单的代码示例,用于输出具有1秒周期的方波。实际应用中,可以根据需要调整周期和占空比的值以实现不同的方波输出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值