找回密码
 立即注册
查看: 271|回复: 31

STC8G系列的PCA/CCP/PWM, 10位PWM

[复制链接]
  • TA的每日心情
    奋斗
    昨天 08:38
  • 签到天数: 20 天

    [LV.4]偶尔看看III

    1

    主题

    17

    回帖

    131

    积分

    注册会员

    积分
    131
    发表于 2024-4-5 16:59:09 | 显示全部楼层 |阅读模式
    用下述程序使用PCA/CCP/PWM模块发送10位PWM,程序逻辑都是对的,
    这个我经过反复验证,当我用电位器进行调节时,输出的波形频率是对的,

    占空比只能打到24%,并不能跟着采样值一直打到100%,
    想问一下我这个程序有什么问题,还是其他?
    截图202404051658503670.jpg


    回复 送花

    使用道具 举报

    该用户从未签到

    46

    主题

    2928

    回帖

    6587

    积分

    超级版主

    积分
    6587
    发表于 2024-4-7 23:02:02 | 显示全部楼层
    leitang 发表于 2024-4-7 19:21
    梁工,我按你的说法,加了一个延时,确实是可以了,但还是pwm还有很明显的抖动,这个如何处理

    10位PWM例程写好了,测试无任何问题,
    P1.2接电位器输入ADC2,10位ADC结果送PCA2-P3.7输出10位PWM,
    下载选择11.0592MHz主频的话,PWM频率就是11059200/1024=10800Hz。


    用户请先别修改程序, 直接下载"ADC.hex"测试.

    下载时选择主频11.0592MHZ(其它频率也可以)。
    本程序演示ADC2(P1.2)接电位器并将ADC值送给

    10位PWM2输出(P3.7-PCA2).

    10-1路ADC读电位器-控制PCA-PWM.rar (61.25 KB, 下载次数: 15)


    请看视频:





    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    昨天 08:38
  • 签到天数: 20 天

    [LV.4]偶尔看看III

    1

    主题

    17

    回帖

    131

    积分

    注册会员

    积分
    131
     楼主| 发表于 2024-4-5 19:47:39 | 显示全部楼层
    void PCA_Init()
    {
            CCON=0x00;  //关闭PCA计数器,清除相关标志位
            CMOD=0x0a;  //PCA时钟源为系统时钟4分频  
            CL  =0x00;  //计数器清零
            CH  =0x00;      
    /*------------------------PWM2部分-----------------------------*/
            CCAPM2 = 0x40;  //使能PCA模块2_PWM输出
            CCAP2L=0X00;    //捕获比较寄存器低8位,比较值
            CCAP2H=0X00;    //捕获比较寄存器高8位,重装值
            PCA_PWM2=0xC0;  //10位PWM输出
    //        CCAPM2=0x42;    //使能PCA模块2_PWM输出     
    }
    void PWM2_Set_Duty(u16 Duty)
    {
            //注意:在更新 10 位 PWM 的重载值时,必须先写高两位 XCCAPnH[1:0],再写低 8 位 CCAPnH[7:0]。
           
    //        CCAPM2   &= 0x40;           //使能PCA模块2_PWM输出
                  PCA_PWM2&= ~(3<<4);        //清零重装值高2位
            PCA_PWM2|=(Duty>>4)&0x30; //设置新的重装值高2位
            CCAP2H   = Duty;           //重装值低8位
            CCAPM2   = 0x42;           //使能PCA模块2_PWM输出
                  CR = 1;   //启动计数器
    }
    //***************主函数**********************
    void main()
    {
                  u16 a;
            P3M0 &= ~0x0c; P3M1 |= 0x0c;    //IO口初始化
            P5M0 |= 0x30; P5M1 &= ~0x30;
            p1 = 0;                         //单片机工作指示灯
            p2 = 0;                                //清除mos管的干扰(只在测试程序时使用)
            PCA_Init();                     //PCA初始化,打开PWM模块

                  while (1)
         {
                  Get_ADC(0x02);                   //启动AD采样,打开采样通道2
                  a = ~(ADC_RES << 8| ADC_RESL);    //将AD采样的值付给a,并取反,使其占空比随着采样电压的增大而变大
            PWM2_Set_Duty(a);                //跟随AD采样值打占空比
         }        
    }

    点评

    你初始化ADC的程序再哪呢?没看到  详情 回复 发表于 2024-4-7 17:43
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    昨天 08:38
  • 签到天数: 20 天

    [LV.4]偶尔看看III

    1

    主题

    17

    回帖

    131

    积分

    注册会员

    积分
    131
     楼主| 发表于 2024-4-5 19:58:14 | 显示全部楼层
    可能是我描述不详细,大概就是低位CCAP2H里的值正常跟随采样值走,但高位每一次赋值的时候都感觉把高位清零了,而且此时正好也是低位数据全为零的状态,所以占空比就会突然从24%下降到0%,然后继续增大采样值就会从零在慢慢打到24%,我想请问一下,如何解决这个问题
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    551

    主题

    9238

    回帖

    1万

    积分

    管理员

    积分
    13957
    发表于 2024-4-5 20:03:15 | 显示全部楼层
    截图202404052003121009.jpg
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    昨天 08:38
  • 签到天数: 20 天

    [LV.4]偶尔看看III

    1

    主题

    17

    回帖

    131

    积分

    注册会员

    积分
    131
     楼主| 发表于 2024-4-5 20:18:43 | 显示全部楼层

    大佬,这个10位pwm的范例程序我用过,但是10位打满占空比和前面的不一样,他需要另一个寄存器来放入高两位,也就是PCA_PWM2这个寄存器中的xccapnh,我是按照数据手册给的要求编写的
    截图202404052016359667.jpg
    截图202404052016548141.jpg

    截图202404052018039861.jpg
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    551

    主题

    9238

    回帖

    1万

    积分

    管理员

    积分
    13957
    发表于 2024-4-5 20:25:42 | 显示全部楼层
    截图202404052025076132.jpg

    截图202404052025385047.jpg

    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    551

    主题

    9238

    回帖

    1万

    积分

    管理员

    积分
    13957
    发表于 2024-4-5 20:26:30 | 显示全部楼层
    #include "reg51.h"
    #include "intrins.h"

    sfr     CCON    =   0xd8;
    sbit    CF      =   CCON^7;
    sbit    CR      =   CCON^6;
    sbit    CCF2    =   CCON^2;
    sbit    CCF1    =   CCON^1;
    sbit    CCF0    =   CCON^0;
    sfr     CMOD    =   0xd9;
    sfr     CL      =   0xe9;
    sfr     CH      =   0xf9;
    sfr     CCAPM0  =   0xda;
    sfr     CCAP0L  =   0xea;
    sfr     CCAP0H  =   0xfa;
    sfr     PCA_PWM0 =  0xf2;
    sfr     CCAPM1  =   0xdb;
    sfr     CCAP1L  =   0xeb;
    sfr     CCAP1H  =   0xfb;
    sfr     PCA_PWM1 =  0xf3;
    sfr     CCAPM2  =   0xdc;
    sfr     CCAP2L  =   0xec;
    sfr     CCAP2H  =   0xfc;
    sfr     PCA_PWM2 =  0xf4;

    sfr     P0M1    =   0x93;
    sfr     P0M0    =   0x94;
    sfr     P1M1    =   0x91;
    sfr     P1M0    =   0x92;
    sfr     P2M1    =   0x95;
    sfr     P2M0    =   0x96;
    sfr     P3M1    =   0xb1;
    sfr     P3M0    =   0xb2;
    sfr     P4M1    =   0xb3;
    sfr     P4M0    =   0xb4;
    sfr     P5M1    =   0xc9;
    sfr     P5M0    =   0xca;

    void main()
    {
        P0M0 = 0x00;
        P0M1 = 0x00;
        P1M0 = 0x00;
        P1M1 = 0x00;
        P2M0 = 0x00;
        P2M1 = 0x00;
        P3M0 = 0x00;
        P3M1 = 0x00;
        P4M0 = 0x00;
        P4M1 = 0x00;
        P5M0 = 0x00;
        P5M1 = 0x00;

        CCON = 0x00;
        CMOD = 0x08;                                //PCA时钟为系统时钟
        CL = 0x00;
        CH = 0x00;
    //--6位PWM--
        CCAPM0 = 0x42;                              //PCA模块0为PWM工作模式
        PCA_PWM0 = 0x80;                            //PCA模块0输出6位PWM
        CCAP0L = 0x20;                              //PWM占空比为50%[(40H-20H)/40H]
        CCAP0H = 0x20;
    //--7位PWM--
        CCAPM1 = 0x42;                              //PCA模块1为PWM工作模式
        PCA_PWM1 = 0x40;                            //PCA模块1输出7位PWM
        CCAP1L = 0x20;                              //PWM占空比为75%[(80H-20H)/80H]
        CCAP1H = 0x20;
    //--8位PWM--
    //  CCAPM2 = 0x42;                              //PCA模块2为PWM工作模式
    //  PCA_PWM2 = 0x00;                            //PCA模块2输出8位PWM
    //  CCAP2L = 0x20;                              //PWM占空比为87.5%[(100H-20H)/100H]
    //  CCAP2H = 0x20;
    //--10位PWM--
        CCAPM2 = 0x42;                              //PCA模块2为PWM工作模式
        PCA_PWM2 = 0xc0;                            //PCA模块2输出10位PWM
        CCAP2L = 0x20;                              //PWM占空比为96.875%[(400H-20H)/400H]
        CCAP2H = 0x20;
        CR = 1;                                     //启动PCA计时器

        while (1);
    }


    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    551

    主题

    9238

    回帖

    1万

    积分

    管理员

    积分
    13957
    发表于 2024-4-5 20:28:08 | 显示全部楼层
    截图202404052028059278.jpg
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    昨天 08:38
  • 签到天数: 20 天

    [LV.4]偶尔看看III

    1

    主题

    17

    回帖

    131

    积分

    注册会员

    积分
    131
     楼主| 发表于 2024-4-5 20:39:13 | 显示全部楼层
    回复 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    昨天 08:38
  • 签到天数: 20 天

    [LV.4]偶尔看看III

    1

    主题

    17

    回帖

    131

    积分

    注册会员

    积分
    131
     楼主| 发表于 2024-4-5 20:47:25 | 显示全部楼层

    大佬,我这个不是单纯的只要发10位pwm波,这个我已经验证过了,是完全可行的,我前面还有一个AD采样,我想的是让采样值控制10位pwm的占空比,现在就是我的高两位的值好像赋不上取又好像是被清零了,我就想问问大佬我这个程序的问题
    回复 支持 反对 送花

    使用道具 举报

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

    本版积分规则

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

    GMT+8, 2024-4-30 13:03 , Processed in 0.083414 second(s), 75 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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