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

STC8H2K12U 高速PWM问题

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:1
  • 最近打卡:2025-11-07 15:58:02
已绑定手机

1

主题

2

回帖

15

积分

新手上路

积分
15
发表于 2025-11-7 15:58:02 | 显示全部楼层 |阅读模式
版主好,我两个问题需要帮助:

1、STC8H2K12U,QFN封装,烧录界面主频选择的是40MHZ,其他的一切正常,包括常规40Mhz主频下的PWM。现在想换到高速PWM,通过144MHZ  PLL输出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[1:0] = 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函数,这就奇怪了,求解惑





捕获.JPG
回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:725
  • 最近打卡:2026-03-30 12:09:34
已绑定手机

97

主题

7246

回帖

1万

积分

超级版主

积分
13798
发表于 2025-11-7 16:25:16 | 显示全部楼层
PLL输入准确的12M,才能输出96M或144M,40M无法分频为12M,PLL输入范围是8~16M
截图202511071625147529.jpg
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:1
  • 最近打卡:2025-11-07 15:58:02
已绑定手机

1

主题

2

回帖

15

积分

新手上路

积分
15
发表于 2025-11-7 16:34:35 | 显示全部楼层
Debu*** 发表于 2025-11-7 16:25
PLL输入准确的12M,才能输出96M或144M,40M无法分频为12M,PLL输入范围是8~16M

1、如何知道40MHZ主频下分频给PLL的是多少?这颗IC,为了正确分频到12MHZ,只能选择12MHZ或24MHZ主频了是吗,可是这样主频太低了呀。

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

点评

PLL输入时钟不是非得是12M,8~16M范围内均可 40M不在8~16M范围内,必须正确设置USBCLK.PCKI,可以设置为3分频或4分频 3分频40M/3=13.333M,4分频40M/4=10M PLL输入时钟必须在8~16M范围内,否则不安全  详情 回复 发表于 2025-11-7 16:52
回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:725
  • 最近打卡:2026-03-30 12:09:34
已绑定手机

97

主题

7246

回帖

1万

积分

超级版主

积分
13798
发表于 2025-11-7 16:52:39 | 显示全部楼层
XK*** 发表于 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频率
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:1
  • 最近打卡:2025-11-07 15:58:02
已绑定手机

1

主题

2

回帖

15

积分

新手上路

积分
15
发表于 2025-11-7 18:10:55 | 显示全部楼层
Debu*** 发表于 2025-11-7 16:52
PLL输入时钟不是非得为12M,8~16M范围内均可,主时钟频率可以用40M
40M不在8~16M范围内,必须正确设置USBC ...

分频我理解了,倍频8和12,哪里来的依据?手册也没说明啊!不过测试了下,好像CLKSEL 的第7位CKMS就是倍频吗?0=8倍 1=12倍吗

点评

是的  详情 回复 发表于 2025-11-7 23:57
回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:725
  • 最近打卡:2026-03-30 12:09:34
已绑定手机

97

主题

7246

回帖

1万

积分

超级版主

积分
13798
发表于 2025-11-7 23:57:16 | 显示全部楼层
XK*** 发表于 2025-11-7 18:10
分频我理解了,倍频8和12,哪里来的依据?手册也没说明啊!不过测试了下,好像CLKSEL 的第7位CKMS就是倍频 ...

是的
回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2026-4-3 05:05 , Processed in 0.114133 second(s), 75 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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