LiuDW091 发表于 2025-8-25 16:45

【APM32E030R Micro-EVB开发板评测】+输出PWM波,并驱动电机

本帖最后由 LiuDW091 于 2025-8-25 17:02 编辑

最近研究了下怎么输出波形,现在来呈现给大家

一、硬件
通过查找datasheet可以知道TMR1在PA8脚属于复位引脚。准备配置PA8为PWM输出脚
还可以得知在AF2,挂在APB2上,如果不知道在哪里,也可以通过程序查找



硬件原理图查到PA8在哪里,方便连线


二、代码

#include "apm32e030.h"
#include "apm32e030_gpio.h"
#include "apm32e030_tmr.h"
#include "apm32e030_rcm.h"
#include "delay.h"


/**
* @brief初始化TIM1通道1输出PWM
* @paramTIM1_CH1输出,产生1kHz PWM,初始占空比50%
*/
void PWM_Init_TMR1_CH1(void)
{
    GPIO_Config_T gpioConfig;
    TMR_TimeBase_T baseConfig;
    TMR_OCConfig_T ocConfig;

    /* 1. 开启外设时钟 */
    RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOA);    // 开启GPIOA时钟
    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR1);   // TMR1挂在APB2总线

    /* 2. 配置GPIOA Pin8 为复用功能(AF) - TMR1_CH1 */
    GPIO_ConfigStructInit(&gpioConfig);                // 初始化结构体为默认值
    gpioConfig.pin = GPIO_PIN_8;
    gpioConfig.mode = GPIO_MODE_AF;                  // 复用功能模式
    gpioConfig.speed = GPIO_SPEED_50MHz;                // 高速
    gpioConfig.outtype = GPIO_OUT_TYPE_PP;             // 推挽输出
    gpioConfig.pupd = GPIO_PUPD_NO;                // 无上下拉
    GPIO_Config(GPIOA, &gpioConfig);

    // 配置PA8的复用功能为TIM1_CH1
    // 根据APM32E030参考手册确认正确的AF编号,是GPIO_AF_PIN2
    GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_8, GPIO_AF_PIN2);

    /* 3. 配置TIM1时基单元 - 产生1kHz PWM */
    // 系统时钟为72MHz
    baseConfig.div = 72 - 1;         // PSC = 71, 72分频 → 1MHz定时器时钟
    baseConfig.period = 1000 - 1;          // ARR = 999 → PWM周期1000个计数
    baseConfig.counterMode = TMR_COUNTER_MODE_UP; // 向上计数模式
    baseConfig.clockDivision = TMR_CKD_DIV1;      // 时钟不分频
    baseConfig.repetitionCounter = 0;      // 重复计数寄存器(高级定时器必需)
    TMR_ConfigTimeBase(TMR1, &baseConfig);

    /* PWM频率计算:
   * 定时器时钟 = 72MHz / (71+ 1) = 1MHz
   * PWM频率 = 1MHz / (999 + 1) = 1000Hz = 1kHz
   */

    /* 4. 配置TIM1通道1为PWM模式 */
                TMR_OCConfigStructInit(&ocConfig);
                ocConfig.OC_Mode = TMR_OC_MODE_PWM1;// 使用辅助函数初始化结构体
    ocConfig.OC_OutputState = TMR_OUTPUT_STATE_ENABLE;    // 使能主输出
    ocConfig.OC_OutputNState = TMR_OUTPUT_NSTATE_DISABLE; // 禁用互补输出
    ocConfig.Pulse = 500;                     // 初始占空比50% (500/1000)
    ocConfig.OC_Polarity = TMR_OC_POLARITY_HIGH;      // 高电平有效
    ocConfig.OC_NPolarity = TMR_OC_NPOLARITY_HIGH;      // 互补输出极性
    ocConfig.OC_Idlestate = TMR_OCIDLESTATE_RESET;    // 空闲状态输出低
    ocConfig.OC_NIdlestate = TMR_OCNIDLESTATE_RESET;// 互补空闲状态输出低
    TMR_OC1Config(TMR1, &ocConfig);         // 应用配置到通道1

    /* 5. 使能自动重装载预装载寄存器 */
    TMR_EnableAUTOReload(TMR1);

    /* 6. 【重要】对于高级定时器TMR1,必须使能主输出(MOE) */
   TMR_EnablePWMOutputs(TMR1);

    /* 7. 启动TMR1计数器 */
   TMR_Enable(TMR1);
}

/**
* @brief动态改变PWM占空比
* @paramduty: 占空比值 (0-1000, 对应0%-100%)
* @retval 无
*/
void PWM_SetDuty(uint16_t duty)
{
    // 确保duty值不超过ARR范围
    if (duty > 1000) {
      duty = 1000;
    }
    TMR_SetCompare1(TMR1, duty);// 使用TMR_SetCompare1
}

/**
* @brief主函数示例
*/
int main(void)
{
    // 系统时钟初始化
    SystemInit();
   
    // 初始化PWM
    PWM_Init_TMR1_CH1();
   
    // 设置初始占空比
//    PWM_SetDuty(300); // 30%占空比
      
                // 固定占空比变化

                PWM_SetDuty(100);   // 50%占空比
          Delay_ms(10);

/*
    while (1) {
      // 在这里可以动态调整占空比
      // 例如:呼吸灯效果
      for (uint16_t i = 0; i <= 1000; i += 10) {
            PWM_SetDuty(i);
            Delay_ms(10);
      }
      for (uint16_t i = 1000; i > 0; i -= 10) {
            PWM_SetDuty(i);
            Delay_ms(10);
      }
    }
               
      */      
               
               
}

/**
* @brief简单延时函数
*/
延迟函数就不写了,这个网上都有,可以找到,或者看我前面的测评

注:不同的库版本对应的变量名可能不同,需要自己更改
注:可以输出固定占空比的方波,也可以输出占空比可变的方波

三、实验效果
视频:https://www.bilibili.com/video/BV1byeRz6E9e/
代码:

将PWM波通过转接板,接入电机,驱动电机效果如下:
视频:https://www.bilibili.com/video/BV1UNeRzTEiY/?vd_source=ba772c0e85968405f3278035d0e204a0

记忆花园 发表于 2025-8-25 16:53

PWM波成功实现。
楼主的代码我拿走了啊
谢谢了

LiuDW091 发表于 2025-8-25 16:55

记忆花园 发表于 2025-8-25 16:53
PWM波成功实现。
楼主的代码我拿走了啊
谢谢了

拿走吧

抒情黎明 发表于 2025-8-27 16:59

是不是实现了PWM波发生,电机驱动就可以搞定了呀

LiuDW091 发表于 2025-8-27 17:02

抒情黎明 发表于 2025-8-27 16:59
是不是实现了PWM波发生,电机驱动就可以搞定了呀

不是,你的看你是什么电机,如果是三项的那种电机,还复杂点。

抒情黎明 发表于 2025-9-9 15:56

我对电机的了解非常有限。正在起步阶段

迷雾隐者 发表于 2025-9-29 08:09

LiuDW091的评测很详细,特别是代码部分,注释很到位
页: [1]
查看完整版本: 【APM32E030R Micro-EVB开发板评测】+输出PWM波,并驱动电机