XKMA 发表于 2025-11-7 15:58:02

STC8H2K12U 高速PWM问题

版主好,我两个问题需要帮助:

1、STC8H2K12U,QFN封装,烧录界面主频选择的是40MHZ,其他的一切正常,包括常规40Mhz主频下的PWM。现在想换到高速PWM,通过144MHZPLL输出10位PWM,期望得到140KHZ左右的PWM,但是实测PWM输出有191KHZ左右,和预期的不一致。按191HZHZ*1024=这样往回推算PLL得有195MHZ了,可是看手册上CLKSEL描述写着PLL只有两档:96MHZ或144MHZ.这是怎么回事呢?

void WritePWMA(char addr, char dat)
{
    while(HSPWMA_ADR & 0x80);                                                //等待前一个异步读写完成

    HSPWMA_DAT = dat;                                                                //准备需要写入的数据
    _nop_();
    _nop_();
    HSPWMA_ADR = addr & 0x7f;                                                //设置间接访问地址,只需要设置原XFR地址的低7位
    //HSPWMA_ADR寄存器的最高位写0,表示写数据
    _nop_();
    _nop_();
}

void configure_pwma_10bit_140k(void)
{    // 1. 配置物理引脚17为P1.1,推挽输出
    P1M1 &= ~0x01;// 清除P1.1的M1位
    P1M0 |= 0x01;   // 设置P1.1的M0位 - 推挽输出

    // P3.4 (PWM4P_2) 设置为推挽输出 - 第12脚
    P3M1 &= ~0x10;// 清除P3.4的M1位
    P3M0 |= 0x10;   // 设置P3.4的M0位 - 推挽输出

    P_SW2 |= 0x80;
    // 启动PLL
    PLLCR |= 0x80;
    Delayms(2);      //@40.000MHz
    CLKSEL |= 0xC0;
    Delayms(2);      //@40.000MHz   
    HSPWMA_CFG = 0x03;
    Delayms(2);      //@40.000MHz
    HSCLKDIV= 0;

    //通过异步方式设置PWMA的相关寄存器
    WritePWMA((char)&PWMA_CCER1, 0x00);
    WritePWMA((char)&PWMA_CCER2, 0x00);
    WritePWMA((char)&PWMA_PSCRH, 0x00);    //设置输出PWM的周期
    WritePWMA((char)&PWMA_PSCRL, 0x00);
    WritePWMA((char)&PWMA_ARRH, 0x03);//设置输出PWM的周期
    WritePWMA((char)&PWMA_ARRL, 0xFF);
    WritePWMA((char)&PWMA_CCMR1, 0x68); //OC1REF输出PWM1(CNT<CCR时输出有效电平1)
    WritePWMA((char)&PWMA_CCMR4, 0x68); //OC1REF输出PWM1(CNT<CCR时输出有效电平1)
    WritePWMA((char)&PWMA_CCR1H, 0x01); //设置输出PWM的占空比
    WritePWMA((char)&PWMA_CCR1L, 0xFF);
    WritePWMA((char)&PWMA_CCR4H, 0x01); //设置输出PWM的占空比
    WritePWMA((char)&PWMA_CCR4L, 0xFF);
    WritePWMA((char)&PWMA_OISR, 0x00);// 7. 配置空闲状态

    //PWMA_PS配置 - 选择P3.4作为PWM4P输出
    PWMA_PS = 0xC0;// C4PS = 11 (选择P3.4)

    WritePWMA((char)&PWMA_ENO, 0x41);
    //输出使能寄存器
    //使能PWM1P(P1.1)和PWM4P(P3.4)输出
    //PWMA_ENO = 0x41;// 二进制: 10000010
    //                   // 位7=1 (ENO4P), 位1=1 (ENO1P)
    WritePWMA((char)&PWMA_BKR, 0x80);                               //使能主输出
    WritePWMA((char)&PWMA_CCER1, 0x01);                        //使能CC1/CC1N上的输出功能
    WritePWMA((char)&PWMA_CCER2, 0x10);                        //使能CC1/CC1N上的输出功能
    WritePWMA((char)&PWMA_CR1, 0x01);                              //开始PWM计数

    //关闭XFR访问
    P_SW2 &= ~0x80;
}

// 批量更新两个通道
void UpdateBothPWM_RealTime(unsigned int duty1, unsigned int duty4)
{
    P_SW2 |= 0x80;
    WritePWMA((char)&PWMA_CCR1H, duty1 >> 8);                  //设置输出PWM的占空比
    WritePWMA((char)&PWMA_CCR1L, duty1);
    WritePWMA((char)&PWMA_CCR4H, duty4 >> 8);                  //设置输出PWM的占空比
    WritePWMA((char)&PWMA_CCR4L, duty4);
    P_SW2 &= ~0x80;
}
   这个问题总结简单点讲,就是需要使用144MHZ的PLL,使能高速PWM,输出10位分辨率,140K左右PWM波,该怎么做呢?


2、WritePWMA((char)&PWMA_ENO,0x41); 这条指令的意思是用来写PWMA_ENO=0X41,但是有个问题,手册中明确写了HSPWMA_CFG的EXTN=0时,只是写XFR区域为FEC0H-FEDFH之间的寄存器,然而我看了PWMA_ENO的地址,它明明是在FEB1呀,按手册的说法,实际应该直接写,例如:PWMA_ENO = 0x41;但是这样无法使能PWM1P(P1.1)和PWM4P(P3.4)输出,只能用WritePWMA((char)&PWMA_ENO,0x41);这条指令才行,相反的另一个参数PWMA_PS,地址在FEB2,只能直接写入,不能用WritePWMA函数,这就奇怪了,求解惑





DebugLab 发表于 2025-11-7 16:25:16

PLL输入准确的12M,才能输出96M或144M,40M无法分频为12M,PLL输入范围是8~16M

XKMA 发表于 2025-11-7 16:34:35

DebugLab 发表于 2025-11-7 16:25
PLL输入准确的12M,才能输出96M或144M,40M无法分频为12M,PLL输入范围是8~16M
1、如何知道40MHZ主频下分频给PLL的是多少?这颗IC,为了正确分频到12MHZ,只能选择12MHZ或24MHZ主频了是吗,可是这样主频太低了呀。

2、如果不改程序,这样输出安全吗?我看手册上写真支持144MHZ-192MHZ

DebugLab 发表于 2025-11-7 16:52:39

XKMA 发表于 2025-11-7 16:34
1、如何知道40MHZ主频下分频给PLL的是多少?这颗IC,为了正确分频到12MHZ,只能选择12MHZ或24MHZ主频了是 ...
PLL输入时钟不是非得为12M,8~16M范围内均可,主时钟频率可以用40M
40M不在8~16M范围内,必须正确设置USBCLK.PCKI,可以设置为3分频或4分频
3分频,40M/3=13.333M
4分频,40M/4=10M
PLL输入时钟必须在8~16M范围内,否则不安全
3分频8倍频,40M/3*8=106.667M
3分频12倍频,40M/3*12=160M
4分频8倍频,40M/4*8=80M
4分频12倍频,40M/4*12=120M
16位高级PWM,最大计数值也不是非得为2的n次方,计数最大值由ARR设置,可以修改ARR配合PWM输入时钟输出特定的PWM频率

XKMA 发表于 2025-11-7 18:10:55

DebugLab 发表于 2025-11-7 16:52
PLL输入时钟不是非得为12M,8~16M范围内均可,主时钟频率可以用40M
40M不在8~16M范围内,必须正确设置USBC ...
分频我理解了,倍频8和12,哪里来的依据?手册也没说明啊!不过测试了下,好像CLKSEL 的第7位CKMS就是倍频吗?0=8倍 1=12倍吗

DebugLab 发表于 2025-11-7 23:57:16

XKMA 发表于 2025-11-7 18:10
分频我理解了,倍频8和12,哪里来的依据?手册也没说明啊!不过测试了下,好像CLKSEL 的第7位CKMS就是倍频 ...

是的
页: [1]
查看完整版本: STC8H2K12U 高速PWM问题