找回密码
 立即注册
查看: 36|回复: 7

STC PWMA通道2占空比无法改变?

[复制链接]
  • 打卡等级:偶尔看看III
  • 打卡总天数:56
  • 最近打卡:2025-11-01 12:17:15
已绑定手机

7

主题

590

回帖

1050

积分

金牌会员

积分
1050
发表于 昨天 12:17 | 显示全部楼层 |阅读模式
这几天又跟着冲哥和布丁橘长学习了PWM

发现一个怪现象:STC32G12K128的通道2,好像占空比不能改变?



看看下面这个呼吸灯:


#include <STC32G.H>
#include "config.h"

#define PWM_PSC                         (120-1)        //120分频
#define PWM_PERIOD                 1000                //周期10毫秒

void PWMA_Config(void);                                //PWMA初始化设置函数
void Update_duty();                                                //更新占空比函数

u16 duty;                                                                                        //占空比变量
bit updateduty;                                                                //占空比更新标志
bit blinkflag;                                                                //呼吸灯状态标志

void main(void)
{
        EAXFR = 1;                                                                         // 使能访问 XFR
        CKCON = 0x00;                                                         // 设置外部数据总线速度为最快
        WTST = 0x00;                                                                // 设置程序代码等待参数,等待时间为0个时钟,CPU执行程序速度最快

        P0M1 = 0x00;P0M0 = 0x00;                //设置P0口为准双向口模式 //00:准双向口 01:推挽输出 10:高阻输入 11:开漏输出
        P1M1 = 0x00;P1M0 = 0x00;                //设置P1口为准双向口模式 //00:准双向口 01:推挽输出 10:高阻输入 11:开漏输出
        P2M1 = 0x00;P2M0 = 0x00;                //设置P2口为准双向口模式 //00:准双向口 01:推挽输出 10:高阻输入 11:开漏输出
        P3M1 = 0x00;P3M0 = 0x00;                //设置P3口为准双向口模式 //00:准双向口 01:推挽输出 10:高阻输入 11:开漏输出
        P4M1 = 0x00;P4M0 = 0x00;                //设置P4口为准双向口模式 //00:准双向口 01:推挽输出 10:高阻输入 11:开漏输出
        P5M1 = 0x00;P5M0 = 0x00;                //设置P5口为准双向口模式 //00:准双向口 01:推挽输出 10:高阻输入 11:开漏输出
        P6M1 = 0x00;P6M0 = 0x00;                //设置P6口为准双向口模式 //00:准双向口 01:推挽输出 10:高阻输入 11:开漏输出
        P7M1 = 0x00;P7M0 = 0x00;                //设置P7口为准双向口模式 //00:准双向口 01:推挽输出 10:高阻输入 11:开漏输出
       
        PWMA_Config();                                                        //PWMA初始化设置
        Update_duty();                                                        //更新占空比
        EA = 1;                                                                                        //使能EA总中断
        duty = PWM_PERIOD;                                        //初始占空比100%,LED熄灭
        while (1)
        {
                Update_duty();                                                //循环执行占空比更新函数
        }
}
void PWM_ISR() interrupt 26
{
        if(PWMA_SR1 & 0x01)                                                                                        //PWM中断后,查询中断标志位,更新中断标志是否置1
        {
                PWMA_SR1 &= ~0x01;                                                                                //清零更新中断标志位
                if(blinkflag == 0) duty -= 10;                                //由暗到亮过程:duty-10
                else if(blinkflag == 1) duty += 10;                //有亮到暗过程:duty+10
                if(duty >= 1000) blinkflag = 0;                                //防溢出周期1000
                else if(duty <= 0) blinkflag = 1;                        //防溢出
                updateduty = 1;                                                                                                //占空比更新标志置1
        }
}
void PWMA_Config(void)
{
        //PWMA_PS = 0x01;                                                //PWM1P引脚切换到P2.0       
        PWMA_PS = 0x00;                                                        //通道1PWM1P引脚切换到P1.0,1N脚P1.1,通道2输出脚
                                                                                        //默认PWM2P脚P1.2,PWM2N脚P1.3
       
        PWMA_PSCRH = (u16)(PWM_PSC >> 8);
        PWMA_PSCRL = (u16)(PWM_PSC);                                 //119+1=120预分频
       
        PWMA_CCER1 = 0x00;                                                         //写 CCMRx 前必须先清零 CCERx 关闭通道cc1
        PWMA_CCER2 = 0x00;                          //写 CCMRx 前必须先清零 CCERx 关闭通道cc3
       
        PWMA_CCMR1 = 0x60;                                                         // 设置 CC1 为 PWMA 输出模式,PWM模式1
        PWMA_CCMR2 = 0x60;                                                         // 设置 CC2 为 PWMA 输出模式,PWM模式1
       
        //PWMA_CCER1 |= 0x01;                                                 // 使能 CC1 通道,01就只有单路输出P1.0
        PWMA_CCER1 |= 0x05;                                                 // 使能 OC1 通道,开启输出比较通道,双路互补输出
        PWMA_CCER2 |= 0x05;                                                 // 使能 OC2 通道,开启输出比较通道,双路互补输出

                       
        //PWMA_CCER1 |= 0x08;                        //加这句是启输出比较通道,把双路互补输出改双路同向输出
        PWMA_CCER2 |= 0x08;                            //加这句是启输出比较通道,把双路互补输出改双路同向输出       
                                                                        //方便看到LED亮
        PWMA_CCR1H = (u16)(PWM_PERIOD >> 8);                 // 设置初始占空比100%,LED熄灭
        PWMA_CCR1L = (u16)(PWM_PERIOD);
       
        PWMA_CCR2H = (u16)(PWM_PERIOD >> 8);                 // 设置初始占空比100%,LED熄灭
        PWMA_CCR2L = (u16)(PWM_PERIOD);
       
       
        PWMA_ARRH = (u16)(PWM_PERIOD >> 8);                        // 设置PWM周期
        PWMA_ARRL = (u16)(PWM_PERIOD);
       
        PWMA_ENO |= 0X01;           //使能PWM1p通道输出(P1.0)
        PWMA_ENO |= 0X02;           //使能PWM1n通道输出(P1.1)

        PWMA_ENO |= 0X10;           //使能PWM2p通道输出(P1.2)
        PWMA_ENO |= 0X20;           //使能PWM2n通道输出(P1.3)
       

       
        PWMA_BKR = 0x80;                                // 使能主输出

        PWMA_IER = 0x01;                                // 使能更新中断
        PWMA_CR1 = 0x01;                                 // 启动PWM定时器,向上计数模式

}
void Update_duty()                                                                                                //更新占空比函数
{
               
        PWMA_CCR1H = (u8)(duty >> 8);
        PWMA_CCR1L = duty;                                                                                         //更新CC1通道占空比
       
        PWMA_CCR2H = (u8)(duty >> 8);
        PWMA_CCR2L = duty;
                                                                                        //更新CC2通道占空比
        updateduty = 0;                                                                                                        //占空比更新标志清零
}

上面黑体字的2句,好像完全不起作用,导致接在通道2的2个LED,不能象接着通道1上的2个LED一样可以呼吸

应该是原理上有没看到的地方?  哪位大侠,帮手看看?



回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:607
  • 最近打卡:2025-11-02 00:15:24
已绑定手机
已实名认证

122

主题

2949

回帖

7670

积分

版主

积分
7670
发表于 昨天 14:20 | 显示全部楼层
你的PWMA_CCER给错了,你用的ccer2是控制oc3和oc4的,需要使用 PWMA_CCER1 |= 0x50; //打开oc2通道使能
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:56
  • 最近打卡:2025-11-01 12:17:15
已绑定手机

7

主题

590

回帖

1050

积分

金牌会员

积分
1050
发表于 昨天 14:40 | 显示全部楼层
王*** 发表于 2025-11-1 14:20
你的PWMA_CCER给错了,你用的ccer2是控制oc3和oc4的,需要使用 PWMA_CCER1 |= 0x50; //打开oc2通道使能 ...

感谢您!
我改了这里:
PWMA_CCER1 |= 0x50; //打开oc2通道使能 ...



本来以为是第3和4个LED灯(P1.2P1.3)是呼吸灯的,结果不是,是多了一个第6个LED灯成了呼吸灯,但是也不对啊





        PWMA_CCER1 = 0x00;                                                         //写 CCMRx 前必须先清零 CCERx 关闭通道cc1
        PWMA_CCER2 = 0x00;                          //写 CCMRx 前必须先清零 CCERx 关闭通道cc3
       
        PWMA_CCMR1 = 0x60;                                                         // 设置 CC1 为 PWMA 输出模式,PWM模式1
        PWMA_CCMR2 = 0x60;                                                         // 设置 CC3 为 PWMA 输出模式,PWM模式1

这里PWMA_CCMR2 = 0x60;肯定也是理解错误的产物,但是把他们删除了,第6个LED灯灭了,第3和4个LED灯(P1.2P1.3)也没有反应.....手册也没看明白!



回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:56
  • 最近打卡:2025-11-01 12:17:15
已绑定手机

7

主题

590

回帖

1050

积分

金牌会员

积分
1050
发表于 昨天 16:51 | 显示全部楼层





void PWMA_Config(void)
{
        //PWMA_PS = 0x01;                                                //PWM1P引脚切换到P2.0       
        PWMA_PS = 0x00;                                                        //通道1PWM1P引脚切换到P1.0,1N脚P1.1,通道2输出脚
                                                                                        //默认PWM2P脚P1.2,PWM2N脚P1.3
       
        PWMA_PSCRH = (u16)(PWM_PSC >> 8);
        PWMA_PSCRL = (u16)(PWM_PSC);                                 //119+1=120预分频
       
       
       
        PWMA_CCR1H = (u16)(PWM_PERIOD >> 8);                 // 设置初始占空比100%,LED熄灭
        PWMA_CCR1L = (u16)(PWM_PERIOD);
       
        PWMA_ARRH = (u16)(PWM_PERIOD >> 8);                        // 设置PWM周期
        PWMA_ARRL = (u16)(PWM_PERIOD);
       
       
        PWMA_CCER1 = 0x00;                                                         //写 CCMRx 前必须先清零 CCERx 关闭通道cc1
        PWMA_CCER2 = 0x00;                          //写 CCMRx 前必须先清零 CCERx 关闭通道cc3
       
        PWMA_CCMR1 = 0x60;                                                         // 设置 CC1 为 PWMA 输出模式,PWM模式1
        PWMA_CCMR2 = 0x60;                                                         // 设置 CC3 为 PWMA 输出模式,PWM模式1
       
        //PWMA_CCER1 |= 0x01;                                                 // 使能 CC1 通道,01就只有单路输出P1.0
        PWMA_CCER1 |= 0x05;                                                 // 使能 OC1 通道,开启输出比较通道,双路互补输出
        PWMA_CCER1 |= 0x50;                                                 // //打开oc2通道使能,开启输出比较通道,双路互补输出

                       
        //PWMA_CCER1 |= 0x08;                        //加这句是启输出比较通道,把双路互补输出改双路同向输出
        //PWMA_CCER2 |= 0x08;                            //加这句是启输出比较通道,把双路互补输出改双路同向输出       
                                                                        //方便看到LED亮
       
       

        PWMA_ENO |= 0X0F;           //使能PWM2n通道输出(P1.0---P1.3)

       
        PWMA_BKR = 0x80;                                // 使能主输出

        PWMA_IER = 0x01;                                // 使能更新中断
        PWMA_CR1 = 0x01;                                 // 启动PWM定时器,向上计数模式

}


2句黑色的肯定是错的,通道1是可以正常运行的,按道理我们加了:

PWMA_CCER1 |= 0x50;                                                 // //打开oc2通道使能,开启输出比较通道,双路互补输出

PWMA_ENO |= 0X0F;           //使能PWM2n通道输出(P1.0---P1.3)

再加上默认:

PWMA_PS = 0x00;                                                        //通道1PWM1P引脚切换到P1.0,1N脚P1.1,通道2输出脚
                                                                                        //默认PWM2P脚P1.2,PWM2N脚P1.3

应该P0---P3  这4个LED都是呼吸灯啊?我不知道哪里没有设置对。。。。。。。。。。。


回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:56
  • 最近打卡:2025-11-01 12:17:15
已绑定手机

7

主题

590

回帖

1050

积分

金牌会员

积分
1050
发表于 昨天 17:20 | 显示全部楼层
先改回去通道3:



void PWMA_Config(void)
{
        //PWMA_PS = 0x01;                                                //PWM1P引脚切换到P2.0        
        PWMA_PS = 0x00;                                                        //通道1PWM1P引脚切换到P1.0,1N脚P1.1,通道2输出脚
                                                                                        //默认PWM2P脚P1.2,PWM2N脚P1.3
        
        PWMA_PSCRH = (u16)(PWM_PSC >> 8);
        PWMA_PSCRL = (u16)(PWM_PSC);                                 //119+1=120预分频
        
        
        
        PWMA_CCR1H = (u16)(PWM_PERIOD >> 8);                 // 设置初始占空比100%,LED熄灭
        PWMA_CCR1L = (u16)(PWM_PERIOD);
        
        PWMA_ARRH = (u16)(PWM_PERIOD >> 8);                        // 设置PWM周期
        PWMA_ARRL = (u16)(PWM_PERIOD);
        
        
        PWMA_CCER1 = 0x00;                                                         //写 CCMRx 前必须先清零 CCERx 关闭通道cc1
        PWMA_CCER2 = 0x00;                          //写 CCMRx 前必须先清零 CCERx 关闭通道cc3
        
        PWMA_CCMR1 = 0x60;                                                         // 设置 CC1 为 PWMA 输出模式,PWM模式1
        PWMA_CCMR3 = 0x60;                                                         // 设置 CC3 为 PWMA 输出模式,PWM模式1
        
        //PWMA_CCER1 |= 0x01;                                                 // 使能 CC1 通道,01就只有单路输出P1.0
        PWMA_CCER1 |= 0x05;                                                 // 使能 OC1 通道,开启输出比较通道,双路互补输出
        PWMA_CCER2 |= 0x05;                                                 // //打开oc3通道使能,开启输出比较通道,双路互补输出

                        
        //PWMA_CCER1 |= 0x08;                        //加这句是启输出比较通道,把双路互补输出改双路同向输出
        PWMA_CCER2 |= 0x08;                            //加这句是启输出比较通道,把双路互补输出改双路同向输出        
                                                                        //方便看到LED亮
        
        

        PWMA_ENO |= 0X33;           //使能PWM2n通道输出(P1.0---P1.3)

        
        PWMA_BKR = 0x80;                                // 使能主输出

        PWMA_IER = 0x01;                                // 使能更新中断
        PWMA_CR1 = 0x01;                                 // 启动PWM定时器,向上计数模式

}


这样就是P10P11的LED正常呼吸灯,P12P13就长亮,不会呼吸.....但灯的位置是对的
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:56
  • 最近打卡:2025-11-01 12:17:15
已绑定手机

7

主题

590

回帖

1050

积分

金牌会员

积分
1050
发表于 昨天 17:26 | 显示全部楼层
void PWMA_Config(void)
{
        //PWMA_PS = 0x01;                                                //PWM1P引脚切换到P2.0       
        PWMA_PS = 0x00;                                                        //通道1PWM1P引脚切换到P1.0,1N脚P1.1,通道2输出脚
                                                                                        //默认PWM2P脚P1.2,PWM2N脚P1.3
       
        PWMA_PSCRH = (u16)(PWM_PSC >> 8);
        PWMA_PSCRL = (u16)(PWM_PSC);                                 //119+1=120预分频
       
       
       
        PWMA_CCR1H = (u16)(PWM_PERIOD >> 8);                 // 设置初始占空比100%,LED熄灭
        PWMA_CCR1L = (u16)(PWM_PERIOD);
       
        PWMA_CCR3H = (u8)(duty >> 8);
        PWMA_CCR3L = duty;
       
       
        PWMA_ARRH = (u16)(PWM_PERIOD >> 8);                        // 设置PWM周期
        PWMA_ARRL = (u16)(PWM_PERIOD);
       
       
        PWMA_CCER1 = 0x00;                                                         //写 CCMRx 前必须先清零 CCERx 关闭通道cc1
        PWMA_CCER2 = 0x00;                          //写 CCMRx 前必须先清零 CCERx 关闭通道cc3
       
        PWMA_CCMR1 = 0x60;                                                         // 设置 CC1 为 PWMA 输出模式,PWM模式1
        PWMA_CCMR3 = 0x60;                                                         // 设置 CC3 为 PWMA 输出模式,PWM模式1
       
        //PWMA_CCER1 |= 0x01;                                                 // 使能 CC1 通道,01就只有单路输出P1.0
        PWMA_CCER1 |= 0x05;                                                 // 使能 OC1 通道,开启输出比较通道,双路互补输出
        PWMA_CCER2 |= 0x05;                                                 // //打开oc3通道使能,开启输出比较通道,双路互补输出

                       
        //PWMA_CCER1 |= 0x08;                        //加这句是启输出比较通道,把双路互补输出改双路同向输出
        //PWMA_CCER2 |= 0x08;                            //加这句是启输出比较通道,把双路互补输出改双路同向输出       
                                                                        //方便看到LED亮
       
       

        PWMA_ENO |= 0X33;           //使能PWM2n通道输出(P1.0---P1.3)

       
        PWMA_BKR = 0x80;                                // 使能主输出

        PWMA_IER = 0x01;                                // 使能更新中断
        PWMA_CR1 = 0x01;                                 // 启动PWM定时器,向上计数模式

}
void Update_duty()                                                                                                //更新占空比函数
{
               
        PWMA_CCR1H = (u8)(duty >> 8);
        PWMA_CCR1L = duty;                                                                                         //更新CC1通道占空比
       
        PWMA_CCR3H = (u8)(duty >> 8);
        PWMA_CCR3L = duty;
                                                                                        //更新CC2通道占空比
        updateduty = 0;                                                                                                        //占空比更新标志清零
}

好像这样就可以,但我只能用通道1和通道3

实际应该是用通道1+通道2更加方便的,但是我不会设置通道2 ...........,哪位大侠指导一下?万分感谢!

回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:56
  • 最近打卡:2025-11-01 12:17:15
已绑定手机

7

主题

590

回帖

1050

积分

金牌会员

积分
1050
发表于 昨天 17:41 | 显示全部楼层
但是实际是有问题的:

PWMA_PS = 0x00;

现在发现通道2和通道3的默认脚位错乱了:

我现在是用通道3,应该默认脚位是P1.4P1.5

但实际上LED是在P1.2P1.3上工作


//PWMA_PS = 0x01;                                                //PWM1P引脚切换到P2.0       
        PWMA_PS = 0x00;                                                        //通道1PWM1P引脚切换到P1.0,1N脚P1.1,通道2输出脚
                                                                                        //默认PWM2P脚P1.2,PWM2N脚P1.3


截图202511011737303040.jpg
截图202511011737522947.jpg
截图202511011741477246.jpg
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:56
  • 最近打卡:2025-11-01 12:17:15
已绑定手机

7

主题

590

回帖

1050

积分

金牌会员

积分
1050
发表于 昨天 17:47 | 显示全部楼层
其实我折腾了一天,都是想用通道2 ,但是怎么都不能让通道2正常工作,我读手册的水平太低,只能按照以前摸索过的通道1+通道3来搞

但是一认真,就发现通道3的默认脚位不是P1.2和P1.3,再加上一直没搞懂通道2的设置,真不知道是怎么回事?

哪位大侠,指点一下,万分感谢。。。。。。。。。。。。
回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-11-2 05:35 , Processed in 0.129379 second(s), 82 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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