mangolu 发表于 2022-5-17 19:13:39

STC8G PCA的PCA_PWMnp寄存器中EPCnH位应该怎么理解?

如题,其中EPCnH在手册中这样描述:



8位PWM,不是只有8位吗?第9位是指什么?同理,6、7、10一样。

下面是8位PWM结构图,可以看到CH那里变成了9位比较器,不明白这个9位比较器是怎么来的,CH不是8位的吗?



下面是官方例程,更新PWM占空比的:

//========================================================================
// 函数: UpdatePwm(u8 PCA_id, u16 pwm_value)
// 描述: 更新PWM值.
// 参数: PCA_id: PCA序号. 取值 PCA0,PCA1,PCA2,PCA_Counter
//               pwm_value: pwm值, 这个值是输出低电平的时间.
// 返回: none.
// 版本: V1.0, 2012-11-22
//========================================================================
void        UpdatePwm(u8 PCA_id, u16 pwm_value)
{
        if(PCA_id == PCA0)
        {
                PCA_PWM0 = (PCA_PWM0 & ~0x32) | (u8)((pwm_value & 0x0300) >> 4) | (u8)((pwm_value & 0x0400) >> 9);
                CCAP0H = (u8)pwm_value;
        }
        else if(PCA_id == PCA1)
        {
                PCA_PWM1 = (PCA_PWM1 & ~0x32) | (u8)((pwm_value & 0x0300) >> 4) | (u8)((pwm_value & 0x0400) >> 9);
                CCAP1H = (u8)pwm_value;
        }
        else if(PCA_id == PCA2)
        {
                PCA_PWM2 = (PCA_PWM2 & ~0x32) | (u8)((pwm_value & 0x0300) >> 4) | (u8)((pwm_value & 0x0400) >> 9);
                CCAP2H = (u8)pwm_value;
        }
}

可以看到官方程序,(u8)((pwm_value & 0x0400) >> 9)这里应该是设置10bit模式下的第11位,设置到EPCnH?那其他的6、7、8模式的第7、8、9位不需要设置吗?

mangolu 发表于 2022-5-18 09:02:31

现在基本上搞清楚8Bit PWM这个第9位的意义:

初始化为8bit PWM,当设置:
PCA_PWM0 &= 0xFD;        // EPC0H = 0
CCAP0H = 0x00;

这时PWM输出一直是高电平,占空比能达到100%:


当设置:
PCA_PWM0 &= 0xFD;        // EPC0H = 0
CCAP0H = 0xFF;

PWM输出:


之所以会有高电平,应该是CL = 0xFF的时候,与CCAP0L的值同为0xFF输出的高电平,这时的占空比应该为1/256。而要达到占空比为0,CCAP0L的值应该为256,这样CL的值永远小于或不可能等于256,输出才能为低电平,而256=0x100,所以第9位的意义在这里。

mangolu 发表于 2022-5-18 09:04:40

所以官方的例程里,只设置工作于10bit下第11位的值,并不严谨:
//========================================================================
// 函数: UpdatePwm(u8 PCA_id, u16 pwm_value)
// 描述: 更新PWM值.
// 参数: PCA_id: PCA序号. 取值 PCA0,PCA1,PCA2,PCA_Counter
//               pwm_value: pwm值, 这个值是输出低电平的时间.
// 返回: none.
// 版本: V1.0, 2012-11-22
//========================================================================
void        UpdatePwm(u8 PCA_id, u16 pwm_value)
{
        if(PCA_id == PCA0)
        {
                PCA_PWM0 = (PCA_PWM0 & ~0x32) | (u8)((pwm_value & 0x0300) >> 4) | (u8)((pwm_value & 0x0400) >> 9);
                CCAP0H = (u8)pwm_value;
        }
        else if(PCA_id == PCA1)
        {
                PCA_PWM1 = (PCA_PWM1 & ~0x32) | (u8)((pwm_value & 0x0300) >> 4) | (u8)((pwm_value & 0x0400) >> 9);
                CCAP1H = (u8)pwm_value;
        }
        else if(PCA_id == PCA2)
        {
                PCA_PWM2 = (PCA_PWM2 & ~0x32) | (u8)((pwm_value & 0x0300) >> 4) | (u8)((pwm_value & 0x0400) >> 9);
                CCAP2H = (u8)pwm_value;
        }
}

小李非刀 发表于 2022-5-18 18:08:08

PCA工作于PWM模式时,是一种缓冲锁存结构。下面以PCA0工作于10位PWM说明。
设置的占空比值在XCCAP0H CCAP0H,一共10位,分高2位低8位,先装高2位,再装低8位。还有最高位EPC0H。
在每个PWM周期的开始,会自动拷贝这11位值到EPC0L XCCAP0L CCAP0L,在整个PWM周期,这11位数据不变,保证本次PWM周期不被打扰。硬件会将XCCAP0L CCAP0L与CH CL值比较,决定输出高低。
当要连续输出低电平时,EPC0H写1,正常输出则EPC0H写0.
页: [1]
查看完整版本: STC8G PCA的PCA_PWMnp寄存器中EPCnH位应该怎么理解?