maomaotou 发表于 2023-7-12 19:02:07

STC32F12追风剑PWM与IO口极限频率测试

本帖最后由 maomaotou 于 2023-7-12 19:16 编辑

感谢STC,感谢石小姐。在看到STC32F12系列PWM高达144MHz的宣传后,迫不及待地申请到了两块追风剑的开发板。先发一张开发板外观图。
PWM输入频率高,意味着同等频率下,我们的波形可以更加精细,分辨率更高。假设输入PWM外设的频率为50MHz,我们要输出5MHz的PWM波形,只能让PSC*ARR=10,且其分辨率最多不超过10个单位,即0.02us。如果我们能够令PWM外设的输入频率变成100MHz,那么输出5MHz的波形时,分辨率就可以达到20个单位,即0.01us。按照STC手册,我们如下配置时钟树

由于PCKI推荐输出信号为6MHz,故我们利用HPLL在合理范围内最高能将其倍频到246MHz。我们需要使能HPLLCR.ENHPLL和CLKSEL.HSIOCK,这样HSPWMA就有了高速的时钟信号输入。HSCLKDIV我们配置为0,不再分频。时钟配置代码如下:HIRCCR=0x80;
while(!(HIRCCR&0x01));
CLKSEL=0x00;
HPLLCR=0x0f;
HPLLCR|=0x80;
Delay_ms(1);
CLKSEL|=0x40;
HSCLKDIV=0;
时钟配置完毕,接下来让我们配置HSPWMA。本次测试中我最大的心得体会便是,做STC的开发,一定要先照手册的例程抄,再看寄存器有关的代码配置。光看HSPWMA的地址/数据寄存器和异步写入那一块,我晕头转向也搞不懂这一节再说啥,为啥配置个PWM还要异步写入呢?直到我看到后面的例程我才真正理解这一节文档开头所说的:“STC32F 系列单片机为高级 PWMA 和高级 PWMB 提供了高速模式 (HSPWMA 和HSPWMB)。高速高级 PWM是以高级 PWMA 和高级 PWMB 为基础,增加了高速模式”这一句话。配置HSPWMA的代码如下:#include <stc32g.h>
#include <intrins.h>
//56MHz
sbit LED=P2^7;

void Delay_ms(unsigned int n)                //@56MHz
{
        unsigned long edata i;
        unsigned int j;

        for(j=0;j<n;j++){
                _nop_();
                _nop_();
                _nop_();
                i = 13998UL;
                while (i) i--;
        }
}

#define _10kHZ_Mode
#ifndef _10kHZ_Mode
#define CLOCK_HZ 10
#define PRESCALER 46322
#define RELOAD 10000/CLOCK_HZ
#else
#define CLOCK_10kHZ 150
#define PRESCALER 23161/CLOCK_10kHZ
#define RELOAD 2
#endif

void WritePWMA(char addr,char dat){
        while(HSPWMA_ADR&0x80);
        HSPWMA_DAT=dat;
        HSPWMA_ADR=addr&0x7f;
}

void HSPWM_configure(){
        HPLLCR=0x0f;
        HPLLCR|=0x80;
        Delay_ms(1);
        CLKSEL|=0x40;
        HSCLKDIV=0;
       
        //156MHz
       
        //PWM OUTPUT @ P2^7 1Hz 15600 10000 PWM4N
        HSPWMA_CFG=0x03;
        PWMA_PS=0x40;
        WritePWMA((char)&PWMA_ENO,0x80);
        WritePWMA((char)&PWMA_PSCRH,PRESCALER>>8);
        WritePWMA((char)&PWMA_PSCRL,(PRESCALER&0xff)-1);
        WritePWMA((char)&PWMA_ARRH,RELOAD>>8);
        WritePWMA((char)&PWMA_ARRL,(RELOAD&0xff)-1);
        WritePWMA((char)&PWMA_CCER2,0x00);
        WritePWMA((char)&PWMA_CCMR4,0x60);
        WritePWMA((char)&PWMA_CCER2,0x40);
        #ifndef _10kHZ_Mode
                WritePWMA((char)&PWMA_CCR4H,(RELOAD/2)>>8);
                WritePWMA((char)&PWMA_CCR4L,((RELOAD/2)&0xff));
        #else
                WritePWMA((char)&PWMA_CCR4H,(1)>>8);
                WritePWMA((char)&PWMA_CCR4L,((1)&0xff));
        #endif
        WritePWMA((char)&PWMA_BKR,0x80);
        WritePWMA((char)&PWMA_CR1,0x01);
}

int main(){
        EAXFR=1;
        HIRCCR=0x80;
        while(!(HIRCCR&0x01));
        CLKSEL=0x00;
        P2M0=0x00;
        P2M1=0x00;
        HSPWM_configure();
        while(1){
               
        }
        return 0;
}
这里46322和23161里的两个数据是根据经验测得的分频系数。这里我们的PWM占空比默认为50%。使/失能_10kHZ_Mode,更改CLOCK_HZ或CLOCK_10kHZ的值可以改变PWM的输出频率。
这样理论上STC的IO口可以使用HSPWM输出特别高的频率。
接下来就是我们的测试环节。IRC配置为56MHz。我们改变上述宏定义的值,观察其IO口输出。实验一:15MHz输出。
我们发现在这个较高的频率下,IO口输出波形能够接受。实验二:20MHz输出。
此时IO口输出波形已经从方波基本退化成了正弦波。实验三:50MHz输出。


此时IO口输出波形已经完全没法使用,频率在,但是幅度太小。
实验结论:PWM很给力,输入频率可以调的很高,分辨率也可以很精细。IO口极限输出频率为25MHz左右。

kksk 发表于 2023-7-12 21:00:16


手册上的规格:
5V供电

3.3V供电


芯征程 发表于 2023-7-13 09:00:00

感谢分享!{:4_269:}

梁工 发表于 2023-7-13 15:45:09

IO的速度,5V时,上升沿、下降沿均在15ns左右,IO输出最高频率大约25~35MHz。

STC32F的PWM高速时钟可以到300KHz左右,这个对于输出高频率的PWM非常有好处,比如输出音频信号(比如PWM长度为12bit,PWM时钟300MHz,则可以输出75KHz的PWM,声音非常好,甚至可以直接驱动MOSFET做D类驱动扬声器,功放都免了)。

PWM时钟高,则输出高频的PWM时仍能有较精细的分辨率,但要注意,当输出的脉冲(高电平、低电平一样)小于IO上升、下降沿的15ns时,将不能响应,在300MHz时钟时对应的PWM宽度为5个时钟。距离来说,要输出一个频率1Mhz的PWM,则1%占空比是没法输出的,因为1%占空比对应10ns,小于IO上升、下降沿的15ns,同理输出99%占空比也是不行的。当占空比为2%~98%之间,就可以正常输出。

maomaotou 发表于 2023-7-13 15:51:13

梁工 发表于 2023-7-13 15:45
IO的速度,5V时,上升沿、下降沿均在15ns左右,IO输出最高频率大约25~35MHz。

STC32F的PWM高速时钟可以到3 ...

是的,这个pwm在同价位的mcu里确实厉害。请问梁工用PWM输出音频信号,滤波电路应该怎么设计?STC有例程嘛

梁工 发表于 2023-7-13 16:53:45

maomaotou 发表于 2023-7-13 15:51
是的,这个pwm在同价位的mcu里确实厉害。请问梁工用PWM输出音频信号,滤波电路应该怎么设计?STC有例程嘛 ...

正在写例程。
输出接RC滤波电路,最好是一阶无源RC+2阶有源RC,效果最好。



页: [1]
查看完整版本: STC32F12追风剑PWM与IO口极限频率测试