找回密码
 立即注册
查看: 58|回复: 5

8G1K08 10位PWM疑问

[复制链接]
  • 打卡等级:以坛为家II
  • 打卡总天数:468
  • 最近打卡:2025-05-01 10:58:55

44

主题

230

回帖

2841

积分

金牌会员

积分
2841
发表于 2025-4-18 11:02:10 | 显示全部楼层 |阅读模式

使用8G1K08 20pin的单片机,使用PCA0 模块的 PWM模式产生PWM方波;

PWM 初始化及占空比设置代码如下。其中 adc_value 为10位adc采样值,范围为0 ~1023;

`#include "pwm.h"

void PWM_Init(void)
{
P3M0 &= ~0x20;
P3M1 &= ~0x20;

P_SW1 &= ~(0X20);
P_SW1 |= (0X10);		// 切换PCA0 的引脚为P35
CCON = 0X00;
CMOD = 0X0A;
CCAPM0 = 0X42;
PCA_PWM0 |= 0xc0;

CL = 0;
CH = 0;

// 下边的三个值共同绝顶初始占空比
PWM_Duty(1024/2);

CCON |= 0X40;

}

void PWM_Duty(unsigned int adc_value)
{
// 首先将 PCA_PWM0 的 EPC0H 初始化为0,然后或上adc_value的最高位;
PCA_PWM0 &= ~(0X02);
PCA_PWM0 |= ((adc_value >> 9) & 0x02);
// 然后设置 PCA_PWM0 的 XCCAP0H (5:4)
PCA_PWM0 &= ~(0X30);
PCA_PWM0 |= ((adc_value >> 5) & 0x30);

CCAP0H = (adc_value & 0xff);

}

`

现象:

频率符合预期;

占空比看上去不太对。 求大神帮忙看下占空比设置是否正确。

另外有个小疑问, 这个PCA的计数器是16位的, 如果将CH,CL 设置为0, 等计数器溢出后是从多少开始计数, 需不需要软件设置 CH = 1111 1100 CL = 0000 0000

不争是争
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:423
  • 最近打卡:2025-05-01 07:10:25
已绑定手机

76

主题

4833

回帖

8343

积分

超级版主

DebugLab

积分
8343
发表于 2025-4-18 11:17:05 | 显示全部楼层
传入参数0000H~03FFH设置占空比

  1. void PWM_Out(unsigned int pwm_0,pwm_1,pwm_2)
  2. {
  3.         unsigned char temp_l,temp_h,temp;
  4.        
  5.         temp_l=pwm_0&0x00ff;                //读pwm_0低8位赋值给temp_l
  6.         temp_h=(pwm_0&0x0300)>>4;        //读pwm_0高2位,移动到XCCAP0H(PCA_PWM0[5:4])位置,赋值给temp_h
  7.         temp=PCA_PWM0&0xcd;                        //读PCA_PWM0,XCCAP2H(PCA_PWM0[5:4])、EPC0H(PCA_PWM0[1])清零后赋值给temp
  8.         temp_h|=temp;                                //写其他位到temph
  9.         if(pwm_0==0x03ff)                        //如果pwm_0最大
  10.                 temp_h|=0x02;                        //设置EPC0H(PCA_PWM0[1])为1
  11.         PCA_PWM0=temp_h;                        //写PCA_PWM0(先写高2位)
  12.         CCAP0H=temp_l;                                //写CCAP0H(再写低8位)
  13.        
  14.         temp_l=pwm_1&0x00ff;                //读pwm_1低8位赋值给temp_l
  15.         temp_h=(pwm_1&0x0300)>>4;        //读pwm_1高2位,移动到XCCAP1H(PCA_PWM1[5:4])位置,赋值给temp_h
  16.         temp=PCA_PWM1&0xcd;                        //读PCA_PWM1,XCCAP1H(PCA_PWM2[5:4])、EPC1H(PCA_PWM1[1])清零后赋值给temp
  17.         temp_h|=temp;                                //写其他位到temph
  18.         if(pwm_1==0x03ff)                        //如果pwm_1最大
  19.                 temp_h|=0x02;                        //设置EPC1H(PCA_PWM1[1])为1
  20.         PCA_PWM1=temp_h;                        //写PCA_PWM1(先写高2位)
  21.         CCAP1H=temp_l;                                //写CCAP1H(再写低8位)
  22.        
  23.         temp_l=pwm_2&0x00ff;                //读pwm_2低8位赋值给temp_l
  24.         temp_h=(pwm_2&0x0300)>>4;        //读pwm_2高2位,移动到XCCAP2H(PCA_PWM2[5:4])位置,赋值给temp_h
  25.         temp=PCA_PWM2&0xcd;                        //读PCA_PWM2,XCCAP2H(PCA_PWM2[5:4])、EPC2H(PCA_PWM2[1])清零后赋值给temp
  26.         temp_h|=temp;                                //写其他位到temph
  27.         if(pwm_2==0x03ff)                        //如果pwm_2最大
  28.                 temp_h|=0x02;                        //设置EPC2H(PCA_PWM2[1])为1
  29.         PCA_PWM2=temp_h;                        //写PCA_PWM2(先写高2位)
  30.         CCAP2H=temp_l;                                //写CCAP2H(再写低8位)
  31. }
复制代码


DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:50
  • 最近打卡:2025-04-30 22:59:03

73

主题

5882

回帖

1万

积分

超级版主

积分
12073
发表于 2025-4-18 11:35:54 | 显示全部楼层
PCA计数器溢出后是从0开始计数的。
装载占空比是分开装载的,最好在PCA中断中及时装载,避免同步的问题。
外部程序装载占空比,有可能更改了高2位数据,低8位还未更改时,
刚好出现新周期的开始,会将新的高2位和旧的低8位组合在一起,出现错误,
但错误只在一个周期,没有再次更新占空比之前,随后的PWM都会正确。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:468
  • 最近打卡:2025-05-01 10:58:55

44

主题

230

回帖

2841

积分

金牌会员

积分
2841
发表于 2025-4-18 13:41:15 | 显示全部楼层
梁*** 发表于 2025-4-18 11:35
PCA计数器溢出后是从0开始计数的。
装载占空比是分开装载的,最好在PCA中断中及时装载,避免同步的问题。
...

就是CH和CL计数溢出后会从0000 0000 开始? 那10位的PWM 在 CH = 0000 0011 后还会继续计数? 直到 1111 1111 ?

点评

手册里有详细的说明,你可以仔细看一下。 10位PWM模式是拿10位占空比数据跟CH、CL低10位做比较,高6位无意义,对于PWM来说,计数器是10位的,从0计到1023,再+1就是0,发出自动装载信号。 [attachimg]94417[/attach  详情 回复 发表于 2025-4-18 14:03
不争是争
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:50
  • 最近打卡:2025-04-30 22:59:03

73

主题

5882

回帖

1万

积分

超级版主

积分
12073
发表于 2025-4-18 14:03:49 | 显示全部楼层
大*** 发表于 2025-4-18 13:41
就是CH和CL计数溢出后会从0000 0000 开始? 那10位的PWM 在 CH = 0000 0011 后还会继续计数? 直到 1111  ...


手册里有详细的说明,你可以仔细看一下。
10位PWM模式是拿10位占空比数据跟CH、CL低10位做比较,高6位无意义,对于PWM来说,计数器是10位的,从0计到1023,再+1就是0,发出自动装载信号。
截图202504181402402759.jpg
8位PWM模式是拿8位占空比数据跟CL低10位做比较,高6位无意义,对于PWM来说,计数器是10位的,从0计到1023,再+1就是0,发出自动装载信号。7位、6位类似。
截图202504181403383114.jpg

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:468
  • 最近打卡:2025-05-01 10:58:55

44

主题

230

回帖

2841

积分

金牌会员

积分
2841
发表于 2025-4-18 16:01:54 | 显示全部楼层
梁*** 发表于 2025-4-18 14:03
手册里有详细的说明,你可以仔细看一下。
10位PWM模式是拿10位占空比数据跟CH、CL低10位做比较,高6位无 ...

哦哦, 那就是说不需要考虑CH的高6位。 修改占空比之需要修改EPCnH CCAPnH XCCPnH 就好了,需要注意的是占空比这几个寄存器的修改不是原子操作。可能在相邻的两个周期之间有误差。
我这个LED调光的程序还好。 对这个要求不高。 只要大致波形对就可以了。 以后可以进一步优化。
不争是争
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-2 02:47 , Processed in 0.259041 second(s), 89 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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