wuzhengmin 发表于 5 天前

请教AiCube生成的PWM不能工作问题 | I/O口工作模式未设置(已解决)

这几天在跟着冲哥学习PWM,顺带也在看AiCube,昨晚用AiCube生产了一个PWM项目


但是无法让它工作,也没看懂怎么改变它的频率?

我估计是用异步方式写PWMA特殊功能寄存器函数:


void HSPWMA_WriteReg(uint8_t addr, uint8_t dat)


或者

void HSPWMB_WriteReg(uint8_t addr, uint8_t dat)


把 时基单元 PWMA_PSCRH、PWMA_PSCRL、时基最大值PWMA_ARRH+PWMA_ARRL

捕获比较寄存器的PWMA_CCR1H+PWMA_CCR1L


写进去才能工作么?

不知道PWMA_ENO 、 PWMA_PS、PWMA_CCER1、PWMA_CCMR1 这需要我配置么?

哪位大侠能否指导一下?万分感谢!!!
                              

wuzhengmin 发表于 5 天前

主程序是这样的:



void main(void)
{
    //<<AICUBE_USER_MAIN_INITIAL_BEGIN>>
    // 在此添加用户主函数初始化代码
    //<<AICUBE_USER_MAIN_INITIAL_END>>

    SYS_Init();

    //<<AICUBE_USER_MAIN_CODE_BEGIN>>
    // 在此添加主函数中运行一次的用户代码
                PWM_UpdateDuty(PWMA_CH1, 20);
                PWM_UpdateDuty(PWMA_CH2, 30);
                PWM_UpdateDuty(PWMA_CH3, 40);
                PWM_UpdateDuty(PWMA_CH4, 50);
                PWM_UpdateDuty(PWMB_CH5, 20);
                PWM_UpdateDuty(PWMB_CH6, 30);
                PWM_UpdateDuty(PWMB_CH7, 40);
                PWM_UpdateDuty(PWMB_CH8, 50);
       
       
                HSPWM_UpdateDuty(PWMA_CH1, 20);
                HSPWM_UpdateDuty(PWMA_CH2, 30);
                HSPWM_UpdateDuty(PWMA_CH3, 40);
                HSPWM_UpdateDuty(PWMA_CH4, 50);
                HSPWM_UpdateDuty(PWMB_CH5, 20);
                HSPWM_UpdateDuty(PWMB_CH6, 30);
                HSPWM_UpdateDuty(PWMB_CH7, 40);
                HSPWM_UpdateDuty(PWMB_CH8, 50);
       
    //<<AICUBE_USER_MAIN_CODE_END>>

    while (1)
    {
      USBLIB_OUT_Done();            //查询方式处理USB接收的数据

      //<<AICUBE_USER_MAIN_LOOP_BEGIN>>
      // 在此添加主函数中用户主循环代码

               
      //<<AICUBE_USER_MAIN_LOOP_END>>
    }
}



wuzhengmin 发表于 5 天前

自动产生的pwm.c是这样的:


//<<AICUBE_USER_HEADER_REMARK_BEGIN>>
////////////////////////////////////////
// 在此添加用户文件头说明信息
// 文件名称: pwm.c
// 文件描述:
// 文件版本: V1.0
// 修改记录:
//   1. (2025-11-02) 创建文件
////////////////////////////////////////
//<<AICUBE_USER_HEADER_REMARK_END>>


#include "config.h"


//<<AICUBE_USER_INCLUDE_BEGIN>>
// 在此添加用户头文件包含
//<<AICUBE_USER_INCLUDE_END>>


//<<AICUBE_USER_GLOBAL_DEFINE_BEGIN>>
// 在此添加用户全局变量定义、用户宏定义以及函数声明
//<<AICUBE_USER_GLOBAL_DEFINE_END>>



////////////////////////////////////////
// PWMA初始化函数
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void PWMA_Init(void)
{
#define PWMA_CLOCK            (0UL)
#define PWMA_PSCR               (0)
#define PWMA_RELOAD             ((float)PWMA_CLOCK / (PWMA_PSCR + 1) * 200 / 1000000 - 1)


    HSPWMA_Disable();                   //关闭高速模式,使用同步方式进行初始化
    PWMA_InternalClockMode();         //选择内部时钟模式
    PWMA_SetCounter(0);               //初始化计数值
    PWMA_SetClockDivider(PWMA_PSCR);    //设置16位预分频
    PWMA_SetReload16(PWMA_RELOAD);      //设置16位重载值

    PWMA_SetIntPriority(0);             //设置中断为最低优先级
    PWMA_EnableUpdateInt();             //使能PWMA更新中断

    PWMA_GenerateUpdateEvent();         //软件产生一次更新事件
    HSPWMA_Enable();                  //使能高速模式
    HSPWMA_EnableInt();               //使能高速模式下的PWM中断

    HSPWMA_Run();                     //PWMA开始运行

    //<<AICUBE_USER_PWM0_INITIAL_BEGIN>>
    // 在此添加用户初始化代码
    //<<AICUBE_USER_PWM0_INITIAL_END>>
}

////////////////////////////////////////
// PWMB初始化函数
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void PWMB_Init(void)
{
#define PWMB_CLOCK            (0UL)
#define PWMB_PSCR               (0)
#define PWMB_RELOAD             ((float)PWMB_CLOCK / (PWMB_PSCR + 1) * 200 / 1000000 - 1)


    HSPWMB_Disable();                   //关闭高速模式,使用同步方式进行初始化
    PWMB_InternalClockMode();         //选择内部时钟模式
    PWMB_SetCounter(0);               //初始化计数值
    PWMB_SetClockDivider(PWMB_PSCR);    //设置16位预分频
    PWMB_SetReload16(PWMB_RELOAD);      //设置16位重载值

    PWMB_SetIntPriority(0);             //设置中断为最低优先级
    PWMB_EnableUpdateInt();             //使能PWMB更新中断

    PWMB_GenerateUpdateEvent();         //软件产生一次更新事件
    HSPWMB_Enable();                  //使能高速模式
    HSPWMB_EnableInt();               //使能高速模式下的PWM中断

    HSPWMB_Run();                     //PWMB开始运行

    //<<AICUBE_USER_PWM1_INITIAL_BEGIN>>
    // 在此添加用户初始化代码
    //<<AICUBE_USER_PWM1_INITIAL_END>>
}

////////////////////////////////////////
// 设置PWM通道输出占空比
// 入口参数: PWMx: (目标PWM组和通道索引)
//         nCompare: (PWM占空比值)
//         iMode: (PWM输出模式:PWM_MODE1/PWM_MODE2)
// 函数返回: 无
////////////////////////////////////////
void PWM_UpdateDuty(uint8_t PWMx, uint16_t nCompare)
{
    switch (PWMx)
    {
    case PWMA_CH1:
      PWMA_SetCCR1Value(nCompare);    //设置通道比较值
      break;
    case PWMA_CH2:
      PWMA_SetCCR2Value(nCompare);    //设置通道比较值
      break;
    case PWMA_CH3:
      PWMA_SetCCR3Value(nCompare);    //设置通道比较值
      break;
    case PWMA_CH4:
      PWMA_SetCCR4Value(nCompare);    //设置通道比较值
      break;
    case PWMB_CH5:
      PWMB_SetCCR5Value(nCompare);    //设置通道比较值
      break;
    case PWMB_CH6:
      PWMB_SetCCR6Value(nCompare);    //设置通道比较值
      break;
    case PWMB_CH7:
      PWMB_SetCCR7Value(nCompare);    //设置通道比较值
      break;
    case PWMB_CH8:
      PWMB_SetCCR8Value(nCompare);    //设置通道比较值
      break;
    }
}

////////////////////////////////////////
// 读取PWM通道捕获值
// 入口参数: PWMx: (目标PWM组和通道索引)
// 函数返回: 捕获值
////////////////////////////////////////
uint16_t PWM_ReadCapture(uint8_t PWMx)
{
    uint16_t cap;

    switch (PWMx)
    {
    case PWMA_CH1:cap = PWMA_ReadCCR1Value(); break;
    case PWMA_CH2:cap = PWMA_ReadCCR2Value(); break;
    case PWMA_CH3:cap = PWMA_ReadCCR3Value(); break;
    case PWMA_CH4:cap = PWMA_ReadCCR4Value(); break;
    case PWMB_CH5:cap = PWMB_ReadCCR5Value(); break;
    case PWMB_CH6:cap = PWMB_ReadCCR6Value(); break;
    case PWMB_CH7:cap = PWMB_ReadCCR7Value(); break;
    case PWMB_CH8:cap = PWMB_ReadCCR8Value(); break;
    default: cap = 0;
    }

    return cap;
}

////////////////////////////////////////
// 设置高速模式PWM通道输出占空比
// 入口参数: PWMx: (目标PWM组和通道索引)
//         nCompare: (PWM占空比值)
// 函数返回: 无
////////////////////////////////////////
void HSPWM_UpdateDuty(uint8_t PWMx, uint16_t nCompare)
{
    switch (PWMx)
    {
    case PWMA_CH1:
      HSPWMA_SetCCR1Value(nCompare);//设置通道比较值
      break;
    case PWMA_CH2:
      HSPWMA_SetCCR2Value(nCompare);//设置通道比较值
      break;
    case PWMA_CH3:
      HSPWMA_SetCCR3Value(nCompare);//设置通道比较值
      break;
    case PWMA_CH4:
      HSPWMA_SetCCR4Value(nCompare);//设置通道比较值
      break;
    case PWMB_CH5:
      HSPWMB_SetCCR5Value(nCompare);//设置通道比较值
      break;
    case PWMB_CH6:
      HSPWMB_SetCCR6Value(nCompare);//设置通道比较值
      break;
    case PWMB_CH7:
      HSPWMB_SetCCR7Value(nCompare);//设置通道比较值
      break;
    case PWMB_CH8:
      HSPWMB_SetCCR8Value(nCompare);//设置通道比较值
      break;
    }
}

////////////////////////////////////////
// 读取高速模式PWM通道捕获值
// 入口参数: PWMx: (目标PWM组和通道索引)
// 函数返回: 捕获值
////////////////////////////////////////
uint16_t HSPWM_ReadCapture(uint8_t PWMx)
{
    uint16_t cap;

    switch (PWMx)
    {
    case PWMA_CH1:cap = HSPWMA_ReadCCR1Value();   break;
    case PWMA_CH2:cap = HSPWMA_ReadCCR2Value();   break;
    case PWMA_CH3:cap = HSPWMA_ReadCCR3Value();   break;
    case PWMA_CH4:cap = HSPWMA_ReadCCR4Value();   break;
    case PWMB_CH5:cap = HSPWMB_ReadCCR5Value();   break;
    case PWMB_CH6:cap = HSPWMB_ReadCCR6Value();   break;
    case PWMB_CH7:cap = HSPWMB_ReadCCR7Value();   break;
    case PWMB_CH8:cap = HSPWMB_ReadCCR8Value();   break;
    default: cap = 0;
    }

    return cap;
}

////////////////////////////////////////
// 异步方式读取PWMA特殊功能寄存器
// 入口参数: addr: (PWMA特殊功能寄存器的低7位)
// 函数返回: 寄存器的值
////////////////////////////////////////;
uint8_t HSPWMA_ReadReg(uint8_t addr)
{
    uint8_t dat;

    while (HSPWMA_CheckBusy());         //等待前一个异步读写完成
    HSPWMA_AsyncRead(addr, dat);      //触发异步方式读取寄存器

    return dat;
}

////////////////////////////////////////
// 异步方式写PWMA特殊功能寄存器
// 入口参数: addr: (PWMA特殊功能寄存器的低7位)
//         dat: (待写入的数据)
// 函数返回: 无
////////////////////////////////////////;
void HSPWMA_WriteReg(uint8_t addr, uint8_t dat)
{
    while (HSPWMA_CheckBusy());         //等待前一个异步读写完成
    HSPWMA_AsyncWrite(addr, dat);       //触发异步方式写寄存器
}

////////////////////////////////////////
// 异步方式读取PWMB特殊功能寄存器
// 入口参数: addr: (PWMB特殊功能寄存器的低7位)
// 函数返回: 寄存器的值
////////////////////////////////////////;
uint8_t HSPWMB_ReadReg(uint8_t addr)
{
    uint8_t dat;

    while (HSPWMB_CheckBusy());         //等待前一个异步读写完成
    HSPWMB_AsyncRead(addr, dat);      //触发异步方式读取寄存器

    return dat;
}

////////////////////////////////////////
// 异步方式写PWMB特殊功能寄存器
// 入口参数: addr: (PWMB特殊功能寄存器的低7位)
//         dat: (待写入的数据)
// 函数返回: 无
////////////////////////////////////////;
void HSPWMB_WriteReg(uint8_t addr, uint8_t dat)
{
    while (HSPWMB_CheckBusy());         //等待前一个异步读写完成
    HSPWMB_AsyncWrite(addr, dat);       //触发异步方式写寄存器
}


////////////////////////////////////////
// PWMA中断服务程序
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void PWMA_ISR(void) interrupt PWMA_VECTOR
{
    //<<AICUBE_USER_PWM0_ISR_CODE1_BEGIN>>
    // 在此添加中断函数用户代码
    if (HSPWMA_CheckUpdateFlag())       //判断PWM更新中断
    {
      HSPWMA_ClearUpdateFlag();       //清除PWM更新中断标志
    }
    //<<AICUBE_USER_PWM0_ISR_CODE1_END>>
}

////////////////////////////////////////
// PWMB中断服务程序
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void PWMB_ISR(void) interrupt PWMB_VECTOR
{
    //<<AICUBE_USER_PWM1_ISR_CODE1_BEGIN>>
    // 在此添加中断函数用户代码
    if (HSPWMB_CheckUpdateFlag())       //判断PWM更新中断
    {
      HSPWMB_ClearUpdateFlag();       //清除PWM更新中断标志
    }
    //<<AICUBE_USER_PWM1_ISR_CODE1_END>>
}


//<<AICUBE_USER_FUNCTION_IMPLEMENT_BEGIN>>
// 在此添加用户函数实现代码
//<<AICUBE_USER_FUNCTION_IMPLEMENT_END>>



王昱顺 发表于 5 天前

看起来像是pwm没有配置为输出模式,单纯工作于定时器模式下了
应该是你在aicube中仅打开了pwm功能,但是没有点进去详细配置
你这个没有输出使能端口相关的操作,肯定是没法输出pwm波的

wuzhengmin 发表于 5 天前

王昱顺 发表于 2025-11-2 10:59
看起来像是pwm没有配置为输出模式,单纯工作于定时器模式下了
应该是你在aicube中仅打开了pwm功能,但是没 ...

哦哦,我再仔细看看,谢谢啦

wuzhengmin 发表于 5 天前

确实是没有配置好,谢谢指导!


进行配置的时候,通道1怎么选择“外设管脚”这里都无效?

从PWM2通道2到PWM8都可以选择,就是PWM1不行,好奇怪,也没有提示和谁冲突.............
页: [1]
查看完整版本: 请教AiCube生成的PWM不能工作问题 | I/O口工作模式未设置(已解决)