电子DIY小家 发表于 2023-6-17 19:45:10

追风剑-STC32F12K54测试:1,自带硬件USB仿真;2, 60MHz CPU主频;3,250MHz PWM ?


拿到了STC家的32位8051——追风剑-STC32F12K54-64MHz ! RMB2.3据说MCU内置3大亮点 “三角函数运算器,浮点运算器,250MHz-PWM”。当然上面的都是官方的“片面之词”,本着求真务实的本性,我得一个个测试下是不是骗我的哈哈。测试一:自带硬件USB在线仿真看到这个芯片支持三种仿真
这里写着支持串口仿真,USB仿真和SWD仿真,串口仿真需要串口线,SWD仿真需要LINK1D仿真器(也是下载器),这里选择最方便的USB仿真,只需要一个USB-typec的线就搞定了,硬件连线如下:

在看到官网的程序包里,第一个就是最直观的跑马灯功能,这里果断选择这个程序作为我们的测试程序。



但是打开这个工程之后需要注意的是这个工程是带HID功能的,他会占用P30,P31引脚,但是我们USB仿真也需要用到这个引脚,需要修改下代码才能作为仿真试用!!


如上这个工程目录里,一眼就看到了这个stc_usb_hid_32f.lib,所以这个工程需要手动的修改一下,删掉所有HID的部分,最终的代码如下所示:

#include "../comm/STC32F.h"//包含此头文件后,不需要再包含"reg51.h"头文件

#define MAIN_Fosc 22118400UL

void delay_ms(int ms);
void HardwareMarquee(void);

/******************** 主函数 **************************/
void main(void)
{
    EAXFR = 1; //扩展寄存器(XFR)访问使能

    RSTFLAG |= 0x04;   //设置硬件复位后需要检测P3.2的状态选择运行区域,否则硬件复位后进入USB下载模式

    P0M1 = 0x00;   P0M0 = 0x00;   //设置为准双向口
    P1M1 = 0x00;   P1M0 = 0x00;   //设置为准双向口
    P2M1 = 0x00;   P2M0 = 0x00;   //设置为准双向口
    P3M1 = 0x00;   P3M0 = 0x00;   //设置为准双向口
    P4M1 = 0x00;   P4M0 = 0x00;   //设置为准双向口
    P5M1 = 0x00;   P5M0 = 0x00;   //设置为准双向口
    P6M1 = 0x00;   P6M0 = 0x00;   //设置为准双向口
    P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口

    EA = 1;   //打开总中断
   
    while(1)
    {
      HardwareMarquee();
    }
}


void HardwareMarquee(void)
{
    P20 = 0;                //LED On
    delay_ms(250);
    P20 = 1;                //LED Off
    P21 = 0;                //LED On
    delay_ms(250);
    P21 = 1;                //LED Off
    P22 = 0;                //LED On
    delay_ms(250);
    P22 = 1;                //LED Off
    P23 = 0;                //LED On
    delay_ms(250);
    P23 = 1;                //LED Off
    P24 = 0;                //LED On
    delay_ms(250);
    P24 = 1;                //LED Off
    P25 = 0;                //LED On
    delay_ms(250);
    P25 = 1;                //LED Off
    P26 = 0;                //LED On
    delay_ms(250);
    P26 = 1;                //LED Off
    P27 = 0;                //LED On
    delay_ms(250);
    P27 = 1;                //LED Off
    P26 = 0;                //LED On
    delay_ms(250);
    P26 = 1;                //LED Off
    P25 = 0;                //LED On
    delay_ms(250);
    P25 = 1;                //LED Off
    P24 = 0;                //LED On
    delay_ms(250);
    P24 = 1;                //LED Off
    P23 = 0;                //LED On
    delay_ms(250);
    P23 = 1;                //LED Off
    P22 = 0;                //LED On
    delay_ms(250);
    P22 = 1;                //LED Off
    P21 = 0;                //LED On
    delay_ms(250);
    P21 = 1;                //LED Off
}

//========================================================================
// 函数: void delay_ms(u8 ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟.
// 返回: none.
// 版本: VER1.0
// 日期: 2022-6-3
// 备注:
//========================================================================
void delay_ms(int ms)
{
    int i;
    do{
      i = MAIN_Fosc / 14000;//软件延时与程序指令延时参数(WTST)值有关
      while(--i);
    }while(--ms);
}


代码只保留了端口初始化,延时和LED来回闪烁的功能, 然后对工程进行下设置:





然后工程如上设置,那代码部分就设置完了,开始硬件部分配置:
1.将板子上的芯片制作为仿真芯片,先按下板子上的P32按钮,在按下电源键并松开,最后松开P32按钮,就可以再串口那栏看见HID的那一行了,没有的话手动安装下驱动~




2.设置仿真芯片


这里需要注意时钟1指向的时钟选择自己的代码工程里定义好的主时钟,我的代码是22.1184Mhz的时钟,一定要和代码匹配!!

3.等待制作完成


出现上述提示即为成功,可以关闭这个软件了。这里切记一定要给板子断一下电在进行后续操作!!

4.编译代码


代码0错误,0警告,没有问题

5.进入仿真模式:





可以看到上面已经进入了经典的仿真界面!!!!非常的华丽,可以像我一样在哪一行打个断点,在点击全速运行!


然后就可以看到板子上的灯会来回的流动一圈了,再点一次运行就会再动一次,然后就可以开始后面的开发之旅啦!!~祝各位小伙伴用的愉快

电子DIY小家 发表于 2023-6-17 20:58:13

测试二:32位8051系统时钟真能跑到 64MHz 吗?

可以看到这个STC家的宣传的大字图上64MHz几个大字特别的醒目,要知道以前的STC最高速度不过48Mhz,这速度一下上涨了33%,有那么点不真实,为了验证他是不是在吹牛,这里咱必须得动手实测下看看!

可以看到STC32F的手册商还有这个非常经典的主时钟控制寄存器,因为使用的内部的IRC时钟,这多少M没有办法测量外部的晶振来得到,那么这里就可以用这个主时钟分频到引脚上直接输出,当然为了照顾下我们的示波器,这里直接用系统时钟四分频输出,可以直接看手册的这一张代码:(不确定系统时钟的时候就可以用这个办法测试!!!)


这里附上测试代码,方便大家复制下载:
void main()
{
      EAXFR = 1; //使能访问 XFR
      //CKCON 上电初始值为 0,无需设置
      //WTST 在 ISP 下载时已自动设置,也无需设置
      P0M0 = 0x00;
      P0M1 = 0x00;
      P1M0 = 0x00;
      P1M1 = 0x00;
      P2M0 = 0x00;
      P2M1 = 0x00;
      P3M0 = 0x00;
      P3M1 = 0x00;
      P4M0 = 0x00;
      P4M1 = 0x00;
      P5M0 = 0x00;
      P5M1 = 0x00;
      
      // MCLKOCR = 0x01; //主时钟输出到 P5.4 口
      // MCLKOCR = 0x02; //主时钟 2 分频输出到 P5.4 口
      MCLKOCR = 0x04; //主时钟 4 分频输出到 P5.4 口
      // MCLKOCR = 0x84; //主时钟 4 分频输出到 P1.6 口
      
      while (1);
}

可以看到代码选择了系统时钟4分频输出,输出引脚选择了P54端口,这里下载的时候选择64m的时钟开始测试:


下载完成后,示波器接到板子上:


再来看示波器的结果:


可以看到示波器上输出波形的频率是大约为16Mhz,这是四分频输出,那就是说系统时钟是16*4Mhz,确确实实是64MHZ!!!诚不欺我!


当然手册还写着后续能到500MHZ,这里浅浅的期待一下哈哈!






电子DIY小家 发表于 2023-6-18 10:57:43

冲哥戏说:高达 500MHz 的 PWM时钟,32位8051 PWM时钟源
=====这难到是为未来的超高速STC32H准备的【500MHz CPU工作时钟】?
测试三:32位8051的PWM时钟源真能达到 250MHz 吗?
可以看到这个STC家的宣传的大字图上 250MHz-PWM 几个大字特别的醒目,最大64M的主频却能提供250M的时钟源!得试试!
在查阅了手册和论坛的多方数据之后发现,官方有大佬发了实测能到307.5M的PWM,远超宣传的250M时钟源。所以我也得按照这个基础来试试是不是真的能达到。
可以看到官方大佬提供的PWM的历程的时钟如上所示,最终实测能测到一个3.075M的PWM输出!

当然,那么问题来了,既然官方说HPLL的输入时钟可以为6~12Mhz,可他才配置了7.5M,是不是还能再高!所以这里我设置输入IRC为48,PCKI设置为4分频~那不就刚好12M的时钟给HPLL了吗{:lol:}在来个极限的HPLL的82倍频(倍频为52-82倍,具体数据如下)测试下,理论来说可以达到492M的PWM时钟源!!说干就干,代码如下:
int main()
{
      ICacheOn(); //使能 ICACHE 功能
      
      EAXFR = 1;
      
      P0M0 = 0; P0M1 = 0;
      P1M0 = 0; P1M1 = 0;
      P2M0 = 0; P2M1 = 0;
      P3M0 = 0; P3M1 = 0;
      P4M0 = 0; P4M1 = 0;
      P5M0 = 0; P5M1 = 0;
      
      //选择 HPLL 输入时钟分频
      USBCLK &= ~PCKI_MSK;
      USBCLK |= PCKI_D4; //PLL 输入时钟 4 分频
      
      //设置 HPLL 的除频系数
      HPLLCR = HPLLDIV_82; //F_HPLL=48M/4*82/2=480M
      
      //启动 HPLL
      HPLLCR |= ENHPLL; //使能 HPLL
      delay(); //等待 HPLL 时钟稳定
      
      
      //选择 HSPWM/HSSPI 时钟
      #if (HSCK_SEL == HSCK_MCLK)
                CLKSEL &= ~HSIOCK; //HSPWM/HSSPI 选择主时钟为时钟源
      #elif (HSCK_SEL == HSCK_PLL)
                CLKSEL |= HSIOCK; //HSPWM/HSSPI 选择 PLL 输出时钟为时钟源
      #else
                CLKSEL &= ~HSIOCK; //默认 HSPWM/HSSPI 选择主时钟为时钟源
      #endif
      
      HSCLKDIV = 0; //HSPWM/HSSPI 时钟源不分频
      HSPWMA_CFG = 0x03; //使能 PWMA 相关寄存器异步访问功能
      PWMA_PS = 0x00; //PWMA_CC1/CC1N 高速 PWM 输出到 CC1/CC1N 口
      
      //注意:PWMA_PS 不能使用异步方式进行读写
      //通过异步方式设置 PWMA 的相关寄存器
      WritePWMA((char)&PWMA_CCER1, 0x00);
      WritePWMA((char)&PWMA_CCMR1, 0x00); //CC1 为输出模式
      WritePWMA((char)&PWMA_CCMR1, 0x60); //OC1REF 输出 PWM1(CNT<CCR 时输出有效电平 1)
      WritePWMA((char)&PWMA_CCER1, 0x05); //使能 CC1/CC1N 上的输出功能
      WritePWMA((char)&PWMA_ENO, 0x03); //使能 PWM 信号输出到端口 P1.0/P1.1
      WritePWMA((char)&PWMA_BKR, 0x80); //使能主输出
      WritePWMA((char)&PWMA_CCR1H, 50>>8); //设置 PWM 占空比为 50 个 PWM 时钟
      WritePWMA((char)&PWMA_CCR1L, 50);
      WritePWMA((char)&PWMA_ARRH, 99>>8); //设置输出 PWM 的周期为 100 个 PWM 时钟
      WritePWMA((char)&PWMA_ARRL, 99);
      WritePWMA((char)&PWMA_DTR, 10); //设置互补对称输出 PWM 的死区
      WritePWMA((char)&PWMA_CR1, 0x01); //开始 PWM 计数

      while (1);
}话不多说,直接上测试结果:
可以看到输出频率还是非常准确的。虽然波形稍微有一点点失真,但是输出频率高了多多少少会有些问题,这里可以设置PWM的计数周期,将PWM速度降下来,这里我把PWMA_ARR寄存器设为999,也就是输出频率保持在491K左右再来看看

看这个图波形是不是就瞬间很完美了!!所以官方说的250M其实应该是内部多方测试最稳定的一个版本,但是实际上极限的输出的频率远高于此,当然这里其实也可以看出一个事情,这里的HPLL输出频率已经达到了48/4*82 = 984MHZ ,离1Ghz其实已经非常接近了啊!!!
当然上述部分均属于测试,远超官方推荐的频率,我们一般把这种称之为超频(和电脑的CPU一样都能超频,当然超频有风险,使用需谨慎),可以看到下图所示,其实手册建议的HPLL输出在312-496MHZ之间最好(这里切记HPLL的输入时钟最好为6-12Mhz之间),我们这里提供一个最稳定最好用的一个PWM的配置。。

1.首先确定主频
可以看到ISP软件里最大时钟是64Mhz,按照我的风格最大的不用,选倒数第二个最保守,所以这里这里我选择用60mhz的主频。
STC建议选择不调节,用出厂前就校准好的 60MHz
2.确定HPLL的参数首先主频是60M,按照手册说的HPLL输出最大最好不超496,那这里直接60/8*64 = 480M,这个参数就挺好,公因数很多可以分出很多频率的PWM出去{:lol:}(还留了16M缓冲的空间,所谓做人留一线日后好相见,这里留16M日后好升级哈哈),最后输入到PWM的时钟2分频一下就是240mhz。
3.代码编写一般的话,pwm如果对频率没有太大要求,我们都会往精度上提一提,一般分成2^8个档位以上,这里为了参数好看点实用性强一点直接配置为1000档,也就是PWMA_ARR为999。最终代码如下:<blockquote>
话不多说,直接上图,可以看到这个PWM的参数其实很完美!输出频率也是我们的理论值240M/1000= 240k

所以说这个PWM其实就完全没问题,非常nice!最终代码附件下载~

神农鼎 发表于 2023-6-18 11:39:45

这 500MHz/2 后占空比是50% 的250MHz PWM时钟

=====搞 音频PWM发声, 冲哥是第一人 !

16位PWM 当16位用,当10位用,当8位用,当2~16位用
16位PWM 当8位用

16位PWM 当10位用



16位PWM 当16位用


HPLL输出频率超过800M/2,也就是PWM输入时钟超过400M,测试4个样品,两个样品PWM无输出
HPLL输出频率超过700M/2,也就是PWM输入时钟超过350M,测试4个样品均输出正常
HPLL的输入频率确实比我们原始定的规格【6~12M】的范围要宽,【2~16M】都可以




马永锋 发表于 2023-6-18 16:10:47

冲哥 威武。从流逝那购买的板子应该快到了,紧跟冲哥学。

神农鼎 发表于 2023-6-18 16:50:01

追风剑-STC32F12K54-64MHz-LQFP48转DIP48核心功能实验板, CPU-60MHz:
有【硬件三角函数,硬件浮点】
sin/cos,270时钟/60   <=   4.5uS
sin/cos,32个时钟/60,大致 0.5uS
比运算能力 STC32F12K54-64I-LQFP48, 超过 STM32F103C8T6了
=====请冲哥测试下【硬件三角函数,硬件浮点】











神农鼎 发表于 2023-6-18 17:01:43





追风剑-STC32F12K54-64MHz-LQFP48转DIP48核心功能实验板的演示程序中也有对应的演示程序







/*---------------------------------------------------------------------*/
/* --- STC MCU Limited ------------------------------------------------*/
/* --- STC 1T Series MCU Demo Programme -------------------------------*/
/* --- Mobile: (86)13922805190 ----------------------------------------*/
/* --- Fax: 86-0513-55012956,55012947,55012969 ------------------------*/
/* --- Tel: 86-0513-55012928,55012929,55012966 ------------------------*/
/* --- Web: www.STCAI.com ---------------------------------------------*/
/* --- BBS: www.STCAIMCU.com-----------------------------------------*/
/* --- QQ:800003751 -------------------------------------------------*/
/* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序            */
/*---------------------------------------------------------------------*/

/*************功能说明    **************

本例程基于STC32F核心转接板(追风剑)进行编写测试。

短按(50ms~1s)P3.2按钮一次,计算一次浮点数运算结果。

通过USB生成的CDC串口发送,使用电脑串口助手就能查看计算结果。

项目加载“STC32_FPMU_LARGE_V1.0.lib”库函数,则使用硬件浮点数单元进行浮点数运算;
项目不加载“STC32_FPMU_LARGE_V1.0.lib”库函数,则使用keil软件浮点数库进行浮点数运算;
通过示波器测量P01低电平时间可对比使用硬件浮点数单元与使用keil软件浮点数库进行浮点数运算所需的时间。

此外程序演示两种复位进入USB下载模式的方法:
1. 通过每1毫秒执行一次“KeyResetScan”函数,实现长按P3.2口按键触发MCU复位,进入USB下载模式。
   (如果不希望复位进入USB下载模式的话,可在复位代码里将 IAP_CONTR 的bit6清0,选择复位进用户程序区)
2. 通过加载“stc_usb_cdc_32f.lib”库函数,实现使用STC-ISP软件发送指令触发MCU复位,进入USB下载模式并自动下载。
   (注意:使用CDC接口触发MCU复位并自动下载功能,需要勾选端口设置:下次使用STC-HID接口进行ISP下载)

下载时, 选择时钟 60MHZ (用户可自行修改频率)。

******************************************/
#define PRINTF_HID         //printf输出直接重定向到USB接口(包含usb.h前定义)

#include "../comm/STC32F.h"//包含此头文件后,不需要再包含"reg51.h"头文件
#include "../comm/usb.h"   //USB调试及复位所需头文件
#include <math.h>
#include "stdio.h"
#include "intrins.h"

/*************本地常量声明    **************/

#define MAIN_Fosc       60000000UL//定义主时钟

/*************IO口定义    **************/

/*************本地变量声明    **************/

char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";                      //设置自动复位到ISP区的用户接口命令

//P3.2口按键复位所需变量
bit Key_Flag;
bit Key_Short_Flag;
bit Key_Short_Function;
u16 Key_cnt;

float cfl1=3.9;
float cfl2=5.1;
float cfl3;
float cfl4;
float cfl5;
float cfl6;
float cfl7;
float cfl8;
float cfl9;
float cfl10;

/*************本地函数声明    **************/

void KeyScan(void);
void delay_ms(u8 ms);

/****************外部函数声明和外部变量声明 *****************/

/******************** 主函数 **************************/
void main(void)
{
    EAXFR = 1; //扩展寄存器(XFR)访问使能

    P0M1 = 0x00;   P0M0 = 0x00;   //设置为准双向口
    P1M1 = 0x00;   P1M0 = 0x00;   //设置为准双向口
    P2M1 = 0x00;   P2M0 = 0x00;   //设置为准双向口
    P3M1 = 0x00;   P3M0 = 0x00;   //设置为准双向口
    P4M1 = 0x00;   P4M0 = 0x00;   //设置为准双向口
    P5M1 = 0x00;   P5M0 = 0x00;   //设置为准双向口
    P6M1 = 0x00;   P6M0 = 0x00;   //设置为准双向口
    P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口

    //====== USB 初始化 ======
    P3M0 &= ~0x03;
    P3M1 |= 0x03;
   
    IRC48MCR = 0x80;
    while (!(IRC48MCR & 0x01));
   
    USBCLK = 0x00;
    USBCON = 0x90;
    //========================
    usb_init();//USB CDC 接口配置
    EA = 1;

    while(1)
    {
      delay_ms(1);
      KeyScan();   //每毫秒检查一次按键状态
      
      if(DeviceState != DEVSTATE_CONFIGURED)//等待USB完成配置
            continue;

      if(Key_Short_Function)      //P3.2按键短按
      {
            Key_Short_Function = 0; //短按一次P3.2按键,计算一次浮点数运算
            
            P01 = 0;
            cfl3 = cfl1*cfl2;
            cfl4 = cfl1/cfl2-cfl3;
            cfl5 = cfl1*cfl2+cfl4;
            cfl6 = cfl1/cfl2*sin(cfl5);
            cfl7 = cfl1/cfl2*cos(cfl6);
            cfl8 = cfl1/cfl2*tan(cfl7);
            cfl9 = cfl1/cfl2*sqrt(cfl8);
            cfl10 = cfl1/cfl2*atan(cfl9);
            P01 = 1;
            
            printf("cfl3=%f\r\n",cfl3); //CDC串口打印计算结果
            printf("cfl4=%f\r\n",cfl4);
            printf("cfl5=%f\r\n",cfl5);
            printf("cfl6=%f\r\n",cfl6);
            printf("cfl7=%f\r\n",cfl7);
            printf("cfl8=%f\r\n",cfl8);
            printf("cfl9=%f\r\n",cfl9);
            printf("cfl10=%f\r\n",cfl10);
      }

      if (bUsbOutReady)
      {
            //USB_SendData(UsbOutBuffer,OutNumber);    //发送数据缓冲区,长度

            usb_OUT_done();    //接收应答(固定格式)
      }
    }
}

//========================================================================
// 函数: void delay_ms(u8 ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟.
// 返回: none.
// 版本: VER1.0
// 日期: 2021-3-9
// 备注:
//========================================================================
void delay_ms(u8 ms)
{
   u16 i;
   do{
      i = MAIN_Fosc / 14000;//软件延时与程序指令延时参数(WTST)值有关
      while(--i);
   }while(--ms);
}

//========================================================================
// 函数: void KeyScan(void)
// 描述: P3.2口按键长按1秒触发软件复位,进入USB下载模式。
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2022-6-11
// 备注:
//========================================================================
void KeyScan(void)
{
    if(!P32)
    {
      if(!Key_Flag)
      {
            Key_cnt++;
            if(Key_cnt >= 1000)                //连续1000ms有效按键检测
            {
                Key_Short_Flag = 0;
                Key_Flag = 1;                //设置按键状态,防止重复触发

                USBCON = 0x00;      //清除USB设置
                USBCLK = 0x00;
                IRC48MCR = 0x00;
               
                delay_ms(10);
                IAP_CONTR = 0x60;   //触发软件复位,从ISP开始执行
                while (1);
            }
            else if(Key_cnt >= 50)//50ms防抖
            {
                Key_Short_Flag = 1; //设置短按标志
            }
      }
    }
    else
    {
      if(Key_Short_Flag)      //判断是否短按
      {
            Key_Short_Flag = 0; //清除短按标志
            Key_Short_Function = 1;
      }
      Key_cnt = 0;
      Key_Flag = 0;
    }
}



神农鼎 发表于 2023-6-18 17:07:34













国学芯用 发表于 2023-6-19 14:47:46


跟着冲哥学习    追风剑USB仿真{:4_174:}

zxy 发表于 2023-7-5 10:04:06

冲哥的讲解非常详细,我开始自己摸索不太顺利,跟冲哥学习一下就操作成功!谢谢冲哥!
页: [1]
查看完整版本: 追风剑-STC32F12K54测试:1,自带硬件USB仿真;2, 60MHz CPU主频;3,250MHz PWM ?