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左右。
手册上的规格:
5V供电
3.3V供电
感谢分享!{:4_269:}
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%之间,就可以正常输出。 梁工 发表于 2023-7-13 15:45
IO的速度,5V时,上升沿、下降沿均在15ns左右,IO输出最高频率大约25~35MHz。
STC32F的PWM高速时钟可以到3 ...
是的,这个pwm在同价位的mcu里确实厉害。请问梁工用PWM输出音频信号,滤波电路应该怎么设计?STC有例程嘛 maomaotou 发表于 2023-7-13 15:51
是的,这个pwm在同价位的mcu里确实厉害。请问梁工用PWM输出音频信号,滤波电路应该怎么设计?STC有例程嘛 ...
正在写例程。
输出接RC滤波电路,最好是一阶无源RC+2阶有源RC,效果最好。
页:
[1]