找回密码
 立即注册
查看: 274|回复: 4

DSP,51的DSP来了, 100MHz, STC32G144K246

[复制链接]
  • 打卡等级:以坛为家III
  • 打卡总天数:607
  • 最近打卡:2025-11-02 00:15:24
已绑定手机
已实名认证

122

主题

2949

回帖

7670

积分

版主

积分
7670
发表于 前天 18:35 | 显示全部楼层 |阅读模式
https://www.stcaimcu.com/data/do ... t/STC32G144K246.pdf    STC32G144K246 用户手册

截图202510311945084078.jpg

截图202510311944486134.jpg

DSP,51DSP来了, 100MHz, STC32G144K246
DSP 与 CPU系统时钟 同频, STC32G144K246,51DSP 来了
===建议 跑 100MHz
下面演示 DSP 指令集 的程序使用 120MHz 系统时钟
120MHz系统时钟,由内部 IRC时钟-24MHz,HPLL倍频产生。

LIB需要根据工程的代码空间大小模式选择合适的LIB库
可以通过查看Target选项卡中的Code Rom Size类型来选择,通常来讲,
如果需要使用全部的246K代码空间,选择HUGE模式的LIB库即可
以下例程也以HUGE模式下LIB库进行使用举例


截图202510311819046943.jpg


因为STC32所使用的C251核心,本身带有1T指令的加法/减法/乘法指令集,(C251除法指令集16位消耗6个时钟,32位消耗10个时钟)
所以LIB中仅将加速了有符号整形除法,无符号长整形除法,有符号长整型除法这三类
其余使用C251默认指令集进行计算,因为其默认指令集的除法为无符号除法,所以大部分都需要进行加速
截图202510311832038300.jpg

可以通过删除/禁用掉LIB库来测试运算是否正确
以下为测试程序的输出,下载时钟选择24MHz,串口波特率选择为115200bps即可:
截图202510311834164372.jpg
可以看到计算结果是和预期一样,正确的


速度测试中,使用1000次循环测试不同数据类型的除法运算,在P60上输出的高电平宽度即为运算时间
测试中,使用了DSP32的程序(使用LIB库)的,耗时2.83ms@120Mhz
未使用DSP32的程序,耗时4.86ms@120Mhz
速度测试部分程序下载: DSP32速度测试-P60高电平宽度输出.zip (88.7 KB, 下载次数: 1)


计算测试程序下载:
DSP32测试.zip (89.08 KB, 下载次数: 1)
测试程序代码:
  1. #include "STC32G.H"
  2. #include "stdio.h"
  3. #include "stdarg.h"
  4. #include "string.h"
  5. #include "math.h"
  6. //本例程使用CHIPID内预置参数,设置HIRC为24MHz
  7. //使用HPLL1,提供60Mhz,80Mhz,120Mhz的设置例程
  8. #define Fosc_60Mhz 0 //系统时钟为60Mhz
  9. #define Fosc_80Mhz 1 //系统时钟为80Mhz
  10. #define Fosc_120Mhz 2//系统时钟为120Mhz
  11. #define Main_Fosc Fosc_120Mhz //设置系统时钟为120Mhz
  12. void CLK_Init(void);                                //设置系统时钟,由Main_Fosc定义设置
  13. void Timer0_Init(void);                        //定时器0初始化函数
  14. void Io_Init(void);                                        //I/O口初始化函数,设置P32为开漏+打开内部上拉电阻模式
  15. void Uart1_Init(void);                        //串口初始化函数,115200bps
  16. void uart_send(int num);
  17. bit P32_OUT = 1;                                                //用于确定输出电平
  18. char uart_buff[64] = {0};
  19. void Delay100ms(void)        //@120MHz
  20. {
  21.         unsigned long edata i;
  22.         _nop_();
  23.         _nop_();
  24.         i = 2999998UL;
  25.         while (i) i--;
  26. }
  27. volatile char c1 = 1, c2 = -2, c3 = 3;
  28. volatile unsigned char uc1 = 1, uc2 = 2, uc3 = 3;
  29. volatile int i1 = 1, i2 = -2, i3 = 3;
  30. volatile long l1 = 1, l2 = -2, l3 = 3;
  31. volatile unsigned long ul1 = 1, ul2 = 2, ul3 = 3;
  32. void main(void)
  33. {
  34.         EAXFR = 1;                                        //使能访问扩展RAM区特殊功能寄存器(XFR)
  35.         CKCON &= ~0x07;                        //清空[2:0],设置外部数据总线等待时钟为0(最快),默认为7
  36.         CLK_Init();                                        //设置HPLL时钟为指定频率
  37.         Timer0_Init();                        //初始化定时器0,50毫秒@120MHz
  38.         Uart1_Init();                                //串口初始化函数,115200bps
  39.         Io_Init();                                        //初始化I/O口,设置P32等效为原准双向口模式(开漏模式+打开内部上拉电阻)
  40.         EA = 1;                                                        //打开总中断
  41.         while(1)
  42.         {
  43.                 //用户程序
  44.                 c2 = -2; c3 = 3;
  45.                 c1 = c2 % c3;       // -2%3=-2
  46.                 uart_send(sprintf(uart_buff, "\n-2%%3=-2,=%d\n",(int)c1));
  47.                 c2 = -2; c3 = 3;
  48.                 c1 = c2 / c3;       // -2/3=0
  49.                 uart_send(sprintf(uart_buff, "-2/3=0,=%d\n",(int)c1));
  50.                
  51.                 uc2 = 2; uc3 = 3;
  52.                 uc1 = uc2 % uc3;    // 2%3=2
  53.                 uart_send(sprintf(uart_buff, "2%%3=2,=%u\n",(unsigned int)uc1));
  54.                
  55.                 i2 = -2, i3 = 3;
  56.                 i1 = i2 % i3;       // -2%3=-2
  57.                 uart_send(sprintf(uart_buff, "-2%%3=-2,=%d\n",i1));
  58.                
  59.                 l2 = -2, l3 = 3;
  60.                 l1 = l2 / l3;       // -2/3=0 (整数除法)
  61.                 uart_send(sprintf(uart_buff, "-2/3=0,=%ld\n",l1));
  62.                 l2 = -2, l3 = 3;
  63.                 l1 = l2 % l3;       // -2%3=-2
  64.                 uart_send(sprintf(uart_buff, "-2%%3=-2,=%ld\n",l1));
  65.                
  66.                 ul2 = 2, ul3 = 3;
  67.                 ul1 = ul2 / ul3;    // 2/3=0 (整数除法)
  68.                 uart_send(sprintf(uart_buff, "2/3=0,=%lu\n",ul1));
  69.                 ul2 = 2, ul3 = 3;
  70.                 ul1 = ul2 % ul3;    // 2%3=2
  71.                 uart_send(sprintf(uart_buff, "2%%3=2,=%lu\n",ul1));
  72.                 Delay100ms();
  73.         }
  74. }
  75. bit uart_flag = 0;
  76. void send_dat(char c)
  77. {
  78.         uart_flag = 1;
  79.         SBUF = c;
  80.         while(uart_flag);
  81. }
  82. int data dat_len = 0;
  83. void uart_send(int num)
  84. {
  85.         for(dat_len = 0; dat_len<num; dat_len++)
  86.         {
  87.                 send_dat(uart_buff[dat_len]);
  88.         }
  89. }
  90. void Uart1_Isr(void) interrupt 4
  91. {
  92.         if (TI)                                //检测串口1发送中断
  93.         {
  94.                 TI = 0;                        //清除串口1发送中断请求位
  95.                 uart_flag = 0;
  96.         }
  97.         if (RI)                                //检测串口1接收中断
  98.         {
  99.                 RI = 0;                        //清除串口1接收中断请求位
  100.         }
  101. }
  102. void Uart1_Init(void)        //115200bps@120MHz
  103. {
  104.         SCON = 0x50;                //8位数据,可变波特率
  105.         AUXR |= 0x40;                //定时器时钟1T模式
  106.         AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
  107.         TMOD &= 0x0F;                //设置定时器模式
  108.         TL1 = 0xFC;                        //设置定时初始值
  109.         TH1 = 0xFE;                        //设置定时初始值
  110.         ET1 = 0;                        //禁止定时器中断
  111.         TR1 = 1;                        //定时器1开始计时
  112.         ES = 1;                                //使能串口1中断
  113. }
  114. char data off_t0_cnt = 0;
  115. void Timer0_Isr(void) interrupt 1
  116. {
  117.         if(P32_OUT == 1&&P32 == 0&&off_t0_cnt<100)off_t0_cnt++;        //判断外部P32按键按下一定时间时,关闭定时器0
  118.         if(off_t0_cnt>5){TR0 = 0;}//注:仅在P32输出为1的时候,外部的按键按下才能被读到
  119.         P32_OUT = ~P32_OUT;//每隔10ms亮/灭切换一次
  120.         P32 = P32_OUT;                //将输出电平给P32管脚
  121. }
  122. void Timer0_Init(void)                //50毫秒@120MHz
  123. {
  124.         TM0PS = 0x5B;                        //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
  125.         AUXR |= 0x80;                        //定时器时钟1T模式
  126.         TMOD &= 0xF0;                        //设置定时器模式
  127.         TL0 = 0x3F;                                //设置定时初始值
  128.         TH0 = 0x01;                                //设置定时初始值
  129.         TF0 = 0;                                //清除TF0标志
  130.         TR0 = 1;                                //定时器0开始计时
  131.         ET0 = 1;                                //使能定时器0中断
  132.         T0CLKO = 1;                        //使能P35输出定时器溢出时钟
  133. }
  134. void Io_Init(void)
  135. {
  136.         P3M0 = 0x26; P3M1 = 0xdd;
  137.         P3PU = 0x0d;
  138.         P3SR = 0xdc;
  139.         P3DR = 0xdc;
  140.         P6M0 = 0xff; P6M1 = 0x00; //推挽输出,P6,PWM
  141.         P6SR = 0x00; //转换速度和驱动电流最大,P6
  142.         P6DR = 0x00;
  143. }
  144. void Delay10ms(void)        //@120MHz
  145. {
  146.         unsigned long edata i;
  147.         _nop_();
  148.         _nop_();
  149.         i = 299998UL;
  150.         while (i) i--;
  151. }
  152. void CLK_Init(void)
  153. {
  154.         #if Main_Fosc == Fosc_120Mhz
  155.         WTST = 4;CLKDIV = 2;                 //设置系统时钟=480MHz/2/2=120MHz,(因为CLKSEL选择时,已经将HPLL/2了)
  156.         #elif Main_Fosc == Fosc_80Mhz
  157.         WTST = 3;CLKDIV = 3;         //设置系统时钟=480MHz/2/3=80MHz
  158.         #elif Main_Fosc == Fosc_60Mhz
  159.         WTST = 2;CLKDIV = 4;         //设置系统时钟=480MHz/2/4=60MHz
  160.         #endif
  161.         //以下为超过60MHz时,系统时钟使用HPLL方式提供
  162.         VRTRIM = CHIPID22;                //载入27MHz频段的VRTRIM值
  163.         IRTRIM = CHIPID12;                //指定当前HIRC为24MHz,此时会覆盖掉ISP设置的时钟频率
  164.         IRCBAND &= ~0x03;                        //清空频段选择
  165.         IRCBAND |= 0x01;                        //选择27Mhz频段
  166.         HPLLCR &= ~0x10;            //选择HPLL输入时钟源为HIRC
  167.         HPLLPDIV = 4;                                        //24MHz/4=6MHz,需要保证输入HPLL的时钟在6MHz附近
  168.         HPLLCR |= 0x0e;             //HPLL=6MHz*80=480MHz
  169.         HPLLCR |= 0x80;             //使能HPLL
  170.         Delay10ms();
  171.         CLKSEL &= ~0x03;                        //BASE_CLK选择为HIRC,用以提供给HPLL
  172.         CLKSEL &= ~0x0c;                        //清空主时钟源选择
  173.         CLKSEL |= 1<<2;                                //设置主时钟源为内部 HPLL1 输出/2
  174. }
复制代码










1 喜欢他/她就送朵鲜花吧,赠人玫瑰,手有余香!
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:225
  • 最近打卡:2025-11-01 08:22:10

792

主题

1万

回帖

2万

积分

管理员

积分
20133
发表于 前天 19:33 | 显示全部楼层
截图202510311941268810.jpg

截图202510311944295838.jpg

截图202510311933025033.jpg


截图202510311936531306.jpg

截图202510311937235578.jpg

截图202510311938295777.jpg

截图202510311940135646.jpg



回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:225
  • 最近打卡:2025-11-01 08:22:10

792

主题

1万

回帖

2万

积分

管理员

积分
20133
发表于 前天 19:42 | 显示全部楼层
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:520
  • 最近打卡:2025-10-31 00:04:04
已绑定手机

8

主题

159

回帖

1660

积分

金牌会员

积分
1660
发表于 前天 22:48 | 显示全部楼层
坐等软解mp3
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2025-10-31 22:58:03
已绑定手机

0

主题

4

回帖

48

积分

新手上路

积分
48
发表于 前天 22:58 来自手机 | 显示全部楼层
6
回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-11-2 05:35 , Processed in 0.121632 second(s), 67 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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