找回密码
 立即注册
楼主: 今晚打老虎

STC15W4K56S4使用pwm6点亮指示灯无输出

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:6
  • 最近打卡:2026-01-23 11:30:49
已绑定手机

1

主题

13

回帖

101

积分

注册会员

积分
101
发表于 2026-1-10 09:57:38 | 显示全部楼层
Debu*** 发表于 2025-12-30 09:56
EAXFR初始化时先打开,不需要再关闭
新手必读:
https://www.stcaimcu.com/thread-16535-1-1.html ...

现在目前来看两路pwm波没有起作用,pwm6和pwm2,pwm2没有能够对风扇外设起到控制作用,为什么就pwm6和pwm2无法使用?这个是什么机理?
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:6
  • 最近打卡:2026-01-23 11:30:49
已绑定手机

1

主题

13

回帖

101

积分

注册会员

积分
101
发表于 2026-1-10 11:45:32 | 显示全部楼层
今晚*** 发表于 2026-1-10 09:57
现在目前来看两路pwm波没有起作用,pwm6和pwm2,pwm2没有能够对风扇外设起到控制作用,为什么就pwm6和pwm2 ...

现在目前来看pwm2有信号,是因为风扇不是可调速的风扇导致的,这边询问ai发现我这边配置寄存器代码出现大量问题,感觉还是有必要咨询一下的,
*****************************************************************
你已经将EAXFR=0x01;移到初始化开头,解决了前置权限问题,但代码中仍存在多处致命残留问题和潜在隐患,这些问题会直接导致 PWM2/PWM6 无输出或工作异常,我们逐一排查并给出修正方案:
一、核心致命问题 1:pwmInit()(PCA 模块)与PWM_kuo_zan_init()(独立 PWM 模块)资源冲突(未解决)
这是当前代码中最关键的冲突点,两者同时初始化会互相干扰,最终导致任一 PWM 模块都无法正常工作。
1. 冲突本质
pwmInit():初始化PCA 定时器模块实现 PWM 功能,占用 PCA 相关寄存器(CCON、CMOD、CCAPM0/1等)和对应 IO 口;
PWM_kuo_zan_init():初始化 STC15W4K56S4 的独立 PWM 模块(专用 PWM 外设),占用独立 PWM 寄存器(PWMCFG、PWMxT1/T2等)和对应 IO 口。
两者共享系统时钟资源,且部分 IO 口可能复用,同时使能会导致:① 时钟竞争冲突;② 寄存器配置被互相覆盖;③ 中断优先级混乱(若开启相关中断)。
2. 具体危害
你的需求是实现 PWM2/PWM6 输出(属于独立 PWM 模块),而pwmInit()的 PCA 模块 PWM 不仅无帮助,还会:
消耗系统资源,导致独立 PWM 模块时钟供给不足,波形输出异常;
若 PCA 模块与独立 PWM 模块复用同一 IO 口,会直接拉低 / 拉高该引脚,覆盖独立 PWM 的输出波形;
最终表现:PWM2/PWM6 无输出、波形杂波过多、频率飘忽不定。
3. 修正方案(必须执行)
直接删除pwmInit()函数的调用,同时删除pwmInit()函数本身(若无需 PCA 模块 PWM),聚焦于独立 PWM 模块的配置,消除资源冲突。
修正后初始化流程中移除该调用:
c
运行
void moshi1_init_TINK()  //初始化任务
{
    EAXFR = 0x01;
    EN_LSR = 0;
    IO_init();                         //IO口
    // 删除:pwmInit(); (消除PCA与独立PWM模块冲突)
    PWM_kuo_zan_init();               //扩展pwm初始化
    pwm6_i(0);
    // 后续初始化...
}
二、核心致命问题 2:PWM_kuo_zan_init()中的两个关键错误(未修正,直接导致 PWM 无输出)
你尚未修正该函数中的 IO 口模式回退和 PWMxT1/T2 逻辑倒置问题,这两个问题是 PWM2/PWM6 无有效输出的直接原因。
1. 错误 1:IO 口模式「回退」(推挽输出→淮双向口),丧失 PWM 驱动能力
该函数中以下代码仍在修改 PWM 输出引脚的 IO 口模式,将IO_init()中配置的「推挽输出」改为「淮双向口」,无法驱动 PWM 高频波形:
c
运行
void PWM_kuo_zan_init()
{
    // 以下3段代码是致命错误,必须全部删除!
    P0M0 &= ~0xc0;  // 影响P0.6/P0.7(PWM7)
    P0M1 &= ~0xc0;
    P0 &= ~0xc0;                  

    P2M0 &= ~0x0e;  // 影响P2.1/P2.2/P2.3(PWM3/PWM4/PWM5)
    P2M1 &= ~0x0e;
    P2 &= ~0x0e;                  

    P3M0 &= ~0x80;  // 影响P3.7(PWM2,核心!)
    P3M1 &= ~0x80;
    P3 &= ~0x80;                  

    // 后续PWM配置...
}
修正要求:删除所有PxM0 &= ~xxx;和PxM1 &= ~xxx;语句,仅保留Px &= ~xxx;(若需初始化引脚电平,不影响模式),保留推挽输出模式,确保 PWM 有足够驱动能力。
2. 错误 2:PWMxT1 > PWMxT2逻辑倒置,无有效方波输出
当前 PWM2(及其他通道)的配置仍为:
c
运行
PWM2T1= 1;                             
PWM2T2= 0;                           
STC15 独立 PWM 模块的工作逻辑:计数器从 0 开始计数,到达PWMxT1时切换引脚电平,到达PWMxT2时再次切换,一个周期结束后重置计数器。
要求:必须满足PWMxT1 < PWMxT2(且两者都小于PWMC设置的周期值0xff),否则会出现 “电平切换逻辑混乱”,表现为引脚始终为高 / 低电平,无方波输出。
修正示例(PWM2 占空比 50%,适配PWMC=0xff的周期):
c
运行
// PWM2修正:T1 < T2,实现50%占空比
PWM2T1= 0x00;  // 计数到0时,切换为低电平
PWM2T2= 0x80;  // 计数到128时,切换为高电平(周期255,占空比50%)
PWM2CR= 0x00;  // 使能PWM2输出到P3.7
同理,若要启用 PWM6,需解开注释并修正:
c
运行
// PWM6修正:解开注释,T1 < T2
PWM6T1= 0x00;
PWM6T2= 0x80;
PWM6CR= 0x00;  // 使能PWM6输出到P1.6
三、PWM_kuo_zan_init()的其他优化 / 修正问题
1. 扩展寄存器访问未收尾(P_SW2未关闭)
函数中仅开启了扩展寄存器访问(P_SW2 |= 0x80;),但未在末尾关闭,可能导致后续代码误操作扩展寄存器,引发不可预期的故障:
c
运行
void PWM_kuo_zan_init()
{
    // 保留电平初始化,删除IO口模式修改
    P0 &= ~0xc0;
    P2 &= ~0x0e;
    P3 &= ~0x80;
   
    P_SW2 |= 0x80;   // 开启扩展寄存器访问
    // 中间PWM配置...
   
    PWMCR = 0xbf;    // 合并使能:0x3f|0x80=0xbf
    P_SW2 &= ~0x80;  // 新增:关闭扩展寄存器访问,防止误操作
}
2. 冗余配置语句(影响可读性,可能导致配置混乱)
函数中存在冗余的PWMCKS和PWMCFG赋值,建议删除冗余项:
c
运行
void PWM_kuo_zan_init()
{
    // 省略其他代码...
    P_SW2 |= 0x80;
   
    PWMCFG = 0x00;                  // 仅保留1次赋值
    // 删除冗余:PWMCKS = 0x00;
    PWMCKS = 0x08;                  // PWM时钟为系统时钟/2(明确注释)
    PWMC = 0xff;                    // 设置PWM周期为255个PWM时钟
   
    // 后续PWM通道配置...
}
四、潜在问题 3:EAXFR宏定义可能缺失(导致编译报错)
你直接使用EAXFR = 0x01;,但未在代码中看到对应的宏定义,编译器无法识别EAXFR对应的寄存器地址(ISP_CONTR,地址0xE2),会报 “undefined identifier 'EAXFR'” 编译错误。
修正方案
在文件头部(所有函数之前)添加EAXFR的宏定义,关联到正确的寄存器地址:
c
运行
// 全局宏定义:映射EAXFR到ISP_CONTR寄存器(地址0xE2)
#define EAXFR (*(unsigned char volatile *)0xE2)

// 后续初始化函数...
void moshi1_init_TINK()  //初始化任务
{
    EAXFR = 0x01;
    // 其他代码...
}
五、潜在问题 4:中断与初始化顺序的小隐患(影响稳定性)
定时器初始化在总中断开启前(合理,但需确认定时器中断使能时机):
你先初始化Timer0/1/3/4,再开启EA=1(总中断),这个顺序是合理的(避免初始化过程中触发定时器中断),但需确保定时器初始化函数中未提前开启对应定时器中断(如ET0=1),否则会导致中断提前触发。
EAXFR修改无中断保护(可选优化):
修改ISP_CONTR寄存器(EAXFR所在)时,若此时有外部中断触发,可能导致寄存器修改不完整,建议添加简单的中断保护:
c
运行
void moshi1_init_TINK()  //初始化任务
{
    EA = 0; // 暂时关闭全局中断,保护寄存器修改
    EAXFR = 0x01; // 开启扩展寄存器访问
    EA = 1; // 恢复全局中断(后续初始化完成后再开启也可)
   
    EN_LSR = 0;
    IO_init();
    PWM_kuo_zan_init();
    // 后续代码...
}
六、潜在问题 5:pwm6_i(0)函数的未知风险
你调用了pwm6_i(0)设置 PWM6,但该函数的实现未提供,存在潜在风险:
若该函数内部修改了 PWM6 的T1/T2值,可能覆盖PWM_kuo_zan_init()中的配置,导致逻辑混乱;
若该函数操作了 P1.6 的 IO 口模式,可能再次将推挽输出改为淮双向口;
建议:查看pwm6_i()函数实现,确保其仅修改 PWM6 的占空比(PWM6T1/T2),不修改 IO 口模式和其他核心配置。
七、总结:当前代码的核心故障点(修正优先级从高到低)
删除pwmInit()调用,消除 PCA 模块与独立 PWM 模块的资源冲突;
删除PWM_kuo_zan_init()中所有PxM0 &= ~xxx;和PxM1 &= ~xxx;语句,保留 PWM 引脚推挽输出模式;
修正PWMxT1/PWMxT2赋值逻辑,确保PWMxT1 < PWMxT2;
补充EAXFR宏定义,避免编译报错;
关闭P_SW2扩展寄存器访问,优化冗余配置;
检查pwm6_i()函数,消除未知风险。
按照上述顺序修正后,PWM2/PWM6 应能输出有效波形,若仍无输出,可进一步排查硬件接线(如引脚是否虚焊、是否被外部电路拉低)和系统时钟配置(是否与PWMCKS分频匹配)。






回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:724
  • 最近打卡:2026-03-18 07:56:47
已绑定手机

97

主题

7244

回帖

1万

积分

超级版主

积分
13791
发表于 2026-1-10 13:37:47 | 显示全部楼层
今晚*** 发表于 2026-1-10 09:56
这个文章的意思是注释掉最后关闭pwm的那段代码?
       PWM7T1= 1;                             
        PWM7 ...

像这样:
void main(void)
{
    P_SW2|=0x80;
    ……
    while(1)
    {
        ……
    }
}
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:359
  • 最近打卡:2026-03-20 21:53:40

844

主题

1万

回帖

2万

积分

管理员

积分
22719
发表于 2026-1-11 13:44:00 | 显示全部楼层
用 AiCube-ISP 图型化配置,自动生成程序框架


截图202601111344214964.jpg
深圳国芯人工智能有限公司-工具软件
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:6
  • 最近打卡:2026-01-23 11:30:49
已绑定手机

1

主题

13

回帖

101

积分

注册会员

积分
101
发表于 2026-1-12 10:22:43 | 显示全部楼层
神*** 发表于 2026-1-11 13:44
用 AiCube-ISP 图型化配置,自动生成程序框架

请问按照这个配置为什么会是这样的?为什么会有这样的报错?
ScreenShot_2026-01-12_101943_690.png
ScreenShot_2026-01-12_102024_386.png
ScreenShot_2026-01-12_102055_140.png
ScreenShot_2026-01-12_102117_369.png
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:6
  • 最近打卡:2026-01-23 11:30:49
已绑定手机

1

主题

13

回帖

101

积分

注册会员

积分
101
发表于 2026-1-12 11:09:34 | 显示全部楼层
神*** 发表于 2026-1-11 13:44
用 AiCube-ISP 图型化配置,自动生成程序框架

生成的都是这种库函数吗?有没有生成类似于软件中自带的案例的那种选项?我需要排查还有哪些地方的设置要注意一下

ScreenShot_2026-01-12_110747_117.png
ScreenShot_2026-01-12_110814_480.png
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:228
  • 最近打卡:2026-03-21 08:48:34

16

主题

234

回帖

462

积分

中级会员

积分
462
发表于 2026-1-12 14:02:14 | 显示全部楼层
我使用ISP软件还从来没出问题过,我都是复制过来代码后,在对着手册再看一遍用到的各个寄存器置位那些位代表啥意思
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:6
  • 最近打卡:2026-01-23 11:30:49
已绑定手机

1

主题

13

回帖

101

积分

注册会员

积分
101
发表于 2026-1-12 17:12:10 | 显示全部楼层
猫*** 发表于 2026-1-12 14:02
我使用ISP软件还从来没出问题过,我都是复制过来代码后,在对着手册再看一遍用到的各个寄存器置位那些位代 ...

之前那个aicube应该是没有在图形界面上配置的缘故,在stc15上我更习惯看寄存器直接操作的版本
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:6
  • 最近打卡:2026-01-23 11:30:49
已绑定手机

1

主题

13

回帖

101

积分

注册会员

积分
101
发表于 2026-1-21 14:43:58 | 显示全部楼层
猫*** 发表于 2026-1-12 14:02
我使用ISP软件还从来没出问题过,我都是复制过来代码后,在对着手册再看一遍用到的各个寄存器置位那些位代 ...

应该是还有部分引脚没有正确配置,之前没有看到这一块还有图形化配置界面,只看到部分gpio的手动配置图表
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:6
  • 最近打卡:2026-01-23 11:30:49
已绑定手机

1

主题

13

回帖

101

积分

注册会员

积分
101
发表于 2026-1-23 11:30:49 | 显示全部楼层
Debu*** 发表于 2026-1-10 13:37
像这样:
void main(void)
{

现在pwm6能正常点亮了,为什么它的输出每次输出的极性都不一样?只要断电后pwm6的极性大概率会翻转一次?就是输出的参数越大后再越亮和越暗之间交替,请问这个是个什么原因?还是我配置有问题?
void PWM_kuo_zan_init() //特殊功能PWM直接操作输出
{       
        P0M0 &= ~0xc0;
        P0M1 &= ~0xc0;
        P0 &= ~0xc0;                    //设置P1.6/.P1.7电平
        P2M0 &= ~0x0e;
        P2M1 &= ~0x0e;
        P2 &= ~0x0e;                    //设置P2.1/P2.2/P2.3电平
        P3M0 &= ~0x80;
        P3M1 &= ~0x80;
        P3 &= ~0x80;                    //设置P3.7电平
       
        P_SW2 |= 0x80;
       
        PWMCFG = 0x00;                  //配置PWM的输出初始电平为低电平
  PWMCKS = 0x00;                  //选择PWM的时钟为Fosc/(0+1)
        PWMCKS = 0x08;                            // PWM时钟为系统时钟
        PWMC = 0xff;                            //设置PWM周期为ffH个PWM时钟

        /*PWM0T1= 0x0100;                       //在计数值为100H地方输出低电平
        PWM0T2= 0x0500;                           //在计数值为500H地方输出高电平
        PWM0CR= 0x00;                             //使能PWM0输出

        PWM1T1= 0x0100;                             
        PWM1T2= 0x0171;                           
        PWM1CR= 0x00;     */      

        PWM2T1= 1;                             
        PWM2T2= 0;                           
        PWM2CR= 0x00;          //PWM2输出到P3.7   

        PWM3T1= 1;                             
        PWM3T2= 0;                           
        PWM3CR= 0x00;          //PWM3输出到P2.1

        PWM4T1= 1;                             
        PWM4T2= 0;                           
        PWM4CR = 0x00;        //PWM4输出到P2.2  

        PWM5T1= 1;                             
        PWM5T2= 0;                           
        PWM5CR = 0x00;        //PWM5输出到P2.3  
       
//        PWM6T1= 1;                             
//        PWM6T2= 0;                           
//        PWM6CR = 0x00;        //PWM6输出到P1.6   

        PWM7T1= 1;                             
        PWM7T2= 0;                           
        PWM7CR = 0x00;        //PWM7输出到P0.7

  PWMCFG = 0x00;                  //配置PWM的输出初始电平
        PWMCR = 0x3f;                   //使能PWM信号输出
  PWMCR |= 0x80;                  //使能PWM模块
  //P_SW2  &= ~0x80;
}

void pwm6(unsigned short Wide)
{
    if (Wide == 0)
    {
        PWMCR &= ~0x10;
        PWM6 = 0;
    }
    else if (Wide == CYCLE)
    {
        PWMCR &= ~0x10;
        PWM6 = 1;
    }
    else
    {
        P_SW2 |= 0x80;
        PWM6T1 = Wide;
        P_SW2 &= ~0x80;
        PWMCR |= 0x10;
    }
}

#define CCP_S0 0x10                         //P_SW1.4
#define CCP_S1 0x20                         //P_SW1.5
void pwmInit()        //PCA模块操作输出
{         

        P1_0 = 0;
        P1_1 = 0;
        ACC = P_SW1;
        ACC &= ~(CCP_S0 | CCP_S1);              //CCP_S0=0 CCP_S1=0
        P_SW1 = ACC;      
       
        CCON = 0x00;                                                                //控制寄存器设置
        //CMOD = 0x02;                //PCA时钟为系统时钟        2分频
        CMOD = 0x0E;                //PCA时钟为系统时钟        8分频
        CL = 0x00;                                                                        //计数器清零
        CH = 0x00;

        CCAPM0 = 0x00;                              //PCA模块0为PWM工作模式
        PCA_PWM0 =0x00;                      //  0x80;     //PCA模块0输出6位PWM
        CCAP0L = 0x00;                              //PWM占空比为50%[(40H-20H)/40H]
        CCAP0H = 0x00;

        CCAPM1 = 0x42;                              //PCA模块1为PWM工作模式
        PCA_PWM1 =0x00;                      //  0x40;     //PCA模块1输出7位PWM
        CCAP1L = 0x00;                              //PWM占空比为75%[(80H-20H)/80H]
        CCAP1H = 0x00;  
       
        CR = 1;                         //PCA定时器开始工作
}

void moshi1_init_TINK()  //初始化任务
{
        //LED_MODE=0;
        //EN_1 =0;
  P_SW2|=0x80;
        EN_LSR = 0;
        IO_init();                         //IO口
        pwmInit();
        PWM_kuo_zan_init();               //扩展pwm初始化
        //pwm6_i(0);
        pwm6(0);
        ADCinit();
        UartInit();         //串口1初始化
        Timer0Init();            //定时器
        Timer1Init();                  
        Timer3Init();                   
        Timer4Init();
  
        IP=0x10; //串口优先级设为最高
       
        EA=1;//开启总中断
       
        PWM_time_CCP1(0);//风鸣器
}
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-3-23 23:08 , Processed in 0.130486 second(s), 90 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表