本帖最后由 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左右。
|