51的DSP来了, 100MHz, STC32G144K246

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

LIB需要根据工程的代码空间大小模式选择合适的LIB库

可以通过查看Target选项卡中的Code Rom Size类型来选择,通常来讲,

如果需要使用全部的246K代码空间,选择HUGE模式的LIB库即可

以下例程也以HUGE模式下LIB库进行使用举例

因为STC32所使用的C251核心,本身带有1T指令的加法/减法/乘法指令集,(C251除法指令集16位消耗6个时钟,32位消耗10个时钟)

所以LIB中仅将加速了有符号整形除法,无符号长整形除法,有符号长整型除法这三类

其余使用C251默认指令集进行计算,因为其默认指令集的除法为无符号除法,所以大部分都需要进行加速

可以通过删除/禁用掉LIB库来测试运算是否正确

以下为测试程序的输出,下载时钟选择24MHz,串口波特率选择为115200bps即可:

可以看到计算结果是和预期一样,正确的

速度测试中,使用1000次循环测试不同数据类型的除法运算,在P60上输出的高电平宽度即为运算时间

测试中,使用了DSP32的程序(使用LIB库)的,耗时2.83ms@120Mhz

未使用DSP32的程序,耗时4.86ms@120Mhz
速度测试部分程序下载:

DSP32速度测试-P60高电平宽度输出.zip (88.7 KB, 下载次数: 22)

计算测试程序下载:

DSP32测试.zip (89.08 KB, 下载次数: 24)

测试程序代码:

复制代码
  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. uc2 = 2; uc3 = 3;
  51. uc1 = uc2 % uc3; // 2%3=2
  52. uart_send(sprintf(uart_buff, "2%%3=2,=%u\n",(unsigned int)uc1));
  53. i2 = -2, i3 = 3;
  54. i1 = i2 % i3; // -2%3=-2
  55. uart_send(sprintf(uart_buff, "-2%%3=-2,=%d\n",i1));
  56. l2 = -2, l3 = 3;
  57. l1 = l2 / l3; // -2/3=0 (整数除法)
  58. uart_send(sprintf(uart_buff, "-2/3=0,=%ld\n",l1));
  59. l2 = -2, l3 = 3;
  60. l1 = l2 % l3; // -2%3=-2
  61. uart_send(sprintf(uart_buff, "-2%%3=-2,=%ld\n",l1));
  62. ul2 = 2, ul3 = 3;
  63. ul1 = ul2 / ul3; // 2/3=0 (整数除法)
  64. uart_send(sprintf(uart_buff, "2/3=0,=%lu\n",ul1));
  65. ul2 = 2, ul3 = 3;
  66. ul1 = ul2 % ul3; // 2%3=2
  67. uart_send(sprintf(uart_buff, "2%%3=2,=%lu\n",ul1));
  68. Delay100ms();
  69. }
  70. }
  71. bit uart_flag = 0;
  72. void send_dat(char c)
  73. {
  74. uart_flag = 1;
  75. SBUF = c;
  76. while(uart_flag);
  77. }
  78. int data dat_len = 0;
  79. void uart_send(int num)
  80. {
  81. for(dat_len = 0; dat_len<num; dat_len++)
  82. {
  83. send_dat(uart_buff[dat_len]);
  84. }
  85. }
  86. void Uart1_Isr(void) interrupt 4
  87. {
  88. if (TI) //检测串口1发送中断
  89. {
  90. TI = 0; //清除串口1发送中断请求位
  91. uart_flag = 0;
  92. }
  93. if (RI) //检测串口1接收中断
  94. {
  95. RI = 0; //清除串口1接收中断请求位
  96. }
  97. }
  98. void Uart1_Init(void) //115200bps@120MHz
  99. {
  100. SCON = 0x50; //8位数据,可变波特率
  101. AUXR |= 0x40; //定时器时钟1T模式
  102. AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
  103. TMOD &= 0x0F; //设置定时器模式
  104. TL1 = 0xFC; //设置定时初始值
  105. TH1 = 0xFE; //设置定时初始值
  106. ET1 = 0; //禁止定时器中断
  107. TR1 = 1; //定时器1开始计时
  108. ES = 1; //使能串口1中断
  109. }
  110. char data off_t0_cnt = 0;
  111. void Timer0_Isr(void) interrupt 1
  112. {
  113. if(P32_OUT == 1&&P32 == 0&&off_t0_cnt<100)off_t0_cnt++; //判断外部P32按键按下一定时间时,关闭定时器0
  114. if(off_t0_cnt>5){TR0 = 0;}//注:仅在P32输出为1的时候,外部的按键按下才能被读到
  115. P32_OUT = ~P32_OUT;//每隔10ms亮/灭切换一次
  116. P32 = P32_OUT; //将输出电平给P32管脚
  117. }
  118. void Timer0_Init(void) //50毫秒@120MHz
  119. {
  120. TM0PS = 0x5B; //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
  121. AUXR |= 0x80; //定时器时钟1T模式
  122. TMOD &= 0xF0; //设置定时器模式
  123. TL0 = 0x3F; //设置定时初始值
  124. TH0 = 0x01; //设置定时初始值
  125. TF0 = 0; //清除TF0标志
  126. TR0 = 1; //定时器0开始计时
  127. ET0 = 1; //使能定时器0中断
  128. T0CLKO = 1; //使能P35输出定时器溢出时钟
  129. }
  130. void Io_Init(void)
  131. {
  132. P3M0 = 0x26; P3M1 = 0xdd;
  133. P3PU = 0x0d;
  134. P3SR = 0xdc;
  135. P3DR = 0xdc;
  136. P6M0 = 0xff; P6M1 = 0x00; //推挽输出,P6,PWM
  137. P6SR = 0x00; //转换速度和驱动电流最大,P6
  138. P6DR = 0x00;
  139. }
  140. void Delay10ms(void) //@120MHz
  141. {
  142. unsigned long edata i;
  143. _nop_();
  144. _nop_();
  145. i = 299998UL;
  146. while (i) i--;
  147. }
  148. void CLK_Init(void)
  149. {
  150. #if Main_Fosc == Fosc_120Mhz
  151. WTST = 4;CLKDIV = 2; //设置系统时钟=480MHz/2/2=120MHz,(因为CLKSEL选择时,已经将HPLL/2了)
  152. #elif Main_Fosc == Fosc_80Mhz
  153. WTST = 3;CLKDIV = 3; //设置系统时钟=480MHz/2/3=80MHz
  154. #elif Main_Fosc == Fosc_60Mhz
  155. WTST = 2;CLKDIV = 4; //设置系统时钟=480MHz/2/4=60MHz
  156. #endif
  157. //以下为超过60MHz时,系统时钟使用HPLL方式提供
  158. VRTRIM = CHIPID22; //载入27MHz频段的VRTRIM值
  159. IRTRIM = CHIPID12; //指定当前HIRC为24MHz,此时会覆盖掉ISP设置的时钟频率
  160. IRCBAND &= ~0x03; //清空频段选择
  161. IRCBAND |= 0x01; //选择27Mhz频段
  162. HPLLCR &= ~0x10; //选择HPLL输入时钟源为HIRC
  163. HPLLPDIV = 4; //24MHz/4=6MHz,需要保证输入HPLL的时钟在6MHz附近
  164. HPLLCR |= 0x0e; //HPLL=6MHz*80=480MHz
  165. HPLLCR |= 0x80; //使能HPLL
  166. Delay10ms();
  167. CLKSEL &= ~0x03; //BASE_CLK选择为HIRC,用以提供给HPLL
  168. CLKSEL &= ~0x0c; //清空主时钟源选择
  169. CLKSEL |= 1<<2; //设置主时钟源为内部 HPLL1 输出/2
  170. }
相关推荐
2301_800399722 小时前
stm32 printf重定向到USART
java·stm32·算法
小龙报2 小时前
《嵌入式成长系列之51单片机 --- Keil5创建工程》
c语言·开发语言·c++·单片机·嵌入式硬件·51单片机·学习方法
点灯小铭2 小时前
基于单片机的自行车速度与里程检测报警系统设计
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
今夜有雨.4 小时前
51单片机--DHT11温湿度传感器实验代码
单片机·嵌入式硬件·51单片机
CoderBob6 小时前
【EmbeddedGUI】简易Page开发模式
c语言·图像处理·单片机
法号:行颠6 小时前
Chaos-nano:Arduino Pro Mini 轻量级操作系统解析与实战应用
单片机·mcu·系统架构
知南x8 小时前
【STM32MP157 异核通信框架学习篇】(10)Linux下Remoteproc相关API (下)
linux·stm32·学习
Aldrich_3214 小时前
蓝桥杯嵌入式赛道—-软件篇(GPIO输出模式配置)
c语言·vscode·stm32·单片机·嵌入式硬件·蓝桥杯
Kisorge14 小时前
【电机控制】基于STM32F103C8T6的二轮平衡车设计——LQR线性二次线控制器(算法篇)
stm32·嵌入式硬件·算法