找回密码
 立即注册
查看: 234|回复: 1

Ai8051U的TFPU问题 | 已解决

[复制链接]
  • 打卡等级:以坛为家III
  • 打卡总天数:795
  • 最近打卡:2026-04-02 08:34:34

19

主题

16

回帖

369

积分

中级会员

积分
369
发表于 2026-1-15 14:56:19 | 显示全部楼层 |阅读模式
这几天使用擎天柱开发板学习MDU和TFPU,编程并用示波器测试。MDU的使用徐爱国,用示波器观察,尤其是除法上,很明显。但是使用TFPU时出了问题。

首先,在工程中加入了AI8051U_32_TFPU.LIB文件,没做其它特殊设置,
lib.png prj.png

没做什么设置,陈旭代码如下:
  1. <div>
  2. <div>#include "AI8051U.h"
  3. #include "intrins.h"
  4. #include "stdio.h"
  5. #include "math.h"
  6. #define MAIN_Fosc        24000000UL
  7. volatile  unsigned long int near uint1, uint2;
  8. volatile unsigned long int near xuint;
  9. volatile long int sint1, sint2;
  10. volatile long int xsint;
  11. unsigned long ultest;
  12. long ltest;
  13. /*****************************************************************************/
  14. sbit TPIN  =  P1^0;
  15. /*****************************************************************************/
  16. #define Baudrate      115200L
  17. #define TM            (65536 -(MAIN_Fosc/Baudrate/4))
  18. #define PrintUart     1        //1:printf 使用 UART1; 2:printf 使用 UART2
  19. /******************** 串口打印函数 ********************/
  20. void UartInit(void)
  21. {
  22. #if(PrintUart == 1)
  23.     S1_S1 = 0;      //UART1 switch to, 0x00: P3.0 P3.1, 0x40: P3.6 P3.7, 0x80: P1.6 P1.7, 0xC0: P4.3 P4.4
  24.     S1_S0 = 1;
  25.     SCON = (SCON & 0x3f) | 0x40;
  26.     T1x12 = 1;      //定时器时钟1T模式
  27.     S1BRT = 0;      //串口1选择定时器1为波特率发生器
  28.     TL1  = TM;
  29.     TH1  = TM>>8;
  30.     TR1 = 1;        //定时器1开始计时
  31. //    SCON = (SCON & 0x3f) | 0x40;
  32. //    T2L  = TM;
  33. //    T2H  = TM>>8;
  34. //    AUXR |= 0x15;   //串口1选择定时器2为波特率发生器
  35. #else
  36.     S2_S = 1;       //UART2 switch to: 0: P1.2 P1.3,  1: P4.2 P4.3
  37.     S2CFG |= 0x01;  //使用串口2时,W1位必需设置为1,否则可能会产生不可预期的错误
  38.     S2CON = (S2CON & 0x3f) | 0x40;
  39.     T2L  = TM;
  40.     T2H  = TM>>8;
  41.     AUXR |= 0x14;   //定时器2时钟1T模式,开始计时
  42. #endif
  43. }
  44. void UartPutc(unsigned char dat)
  45. {
  46. #if(PrintUart == 1)
  47.     SBUF = dat;
  48.     while(TI==0);
  49.     TI = 0;
  50. #else
  51.     S2BUF  = dat;
  52.     while(S2TI == 0);
  53.     S2TI = 0;    //Clear Tx flag
  54. #endif
  55. }
  56. char putchar(char c)
  57. {
  58.     UartPutc(c);
  59.     return c;
  60. }
  61. void delay(unsigned char ms)
  62. {
  63.      while(--ms);
  64. }
  65. void PLL_Init() {
  66. //  CLKSEL &= ~0x80;        //选择PLL的96M(*8)作为PLL的输出时钟
  67.     CLKSEL |= 0x80;         //选择PLL的144M(*12)作为PLL的输出时钟
  68.     USBCLK &= ~0x60;
  69. //  USBCLK |= 0x00;         //PLL输入时钟为12M则选择1分频
  70. //  USBCLK |= 0x20;         //PLL输入时钟为24M则选择2分频
  71.     USBCLK |= 0x40;         //PLL输入时钟为48M则选择4分频
  72. //  USBCLK |= 0x60;         //PLL输入时钟为96M则选择8分频
  73.     USBCLK |= 0x80;         //启动PLL
  74.     delay(1000);                //等待PLL锁频,建议50us以上
  75.     HSCLKDIV = 0;           //高速外设时钟源不分频
  76.     TFPU_CLKDIV = 0;        //TFPU时钟源不分频
  77. //  CLKSEL &= ~0x40;        //选择系统时钟作为高速外设时钟源
  78.     CLKSEL |= 0x40;         //选择PLL时钟作为高速外设时钟源
  79. }
  80. /*****************************************************************************/
  81. void main(void) {   
  82.     float f1=223.57;
  83.     float f2=764.84;
  84.     float f3=0;
  85.    
  86.    
  87.     WTST = 0;  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
  88.     EAXFR = 1; //扩展寄存器(XFR)访问使能
  89.     CKCON = 0; //提高访问XRAM速度
  90.     P0M1 = 0x00;   P0M0 = 0x00;   //设置为准双向口
  91.     P1M1 = 0x00;   P1M0 = 0x00;   //设置为准双向口
  92.     P2M1 = 0x00;   P2M0 = 0x00;   //设置为准双向口
  93.     P3M1 = 0x00;   P3M0 = 0x00;   //设置为准双向口
  94.     P4M1 = 0x00;   P4M0 = 0x00;   //设置为准双向口
  95.     P5M1 = 0x00;   P5M0 = 0x00;   //设置为准双向口
  96.     P6M1 = 0x00;   P6M0 = 0x00;   //设置为准双向口
  97.     P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口
  98.     UartInit();
  99.    
  100.         PLL_Init();
  101.    
  102. //  DMAIR = 0x3e;           //TFPU使用系统时钟作为时钟源
  103.     DMAIR = 0x3f;           //TFPU使用高速外设时钟作为时钟源
  104.                             //*** 必须设置此句,TFPU才能使用高速时钟作为时钟源 ***
  105.   
  106.    
  107.     while(1) {
  108.         //printf("start...\r\n");
  109.         TPIN=1;
  110.         f3 = f1 + f2;
  111. //        f3 = f1 - f2;
  112. //        f3 = f1 * f2;
  113. //        f3 = f1 / f2;
  114.         TPIN=0;
  115.    
  116.     }
  117. }
  118. /*****************************************************************************/</div>
  119. </div>
复制代码
运行后,示波器测试的状况:
加法有TFPU.png

47.264纳秒
然后去掉lib,注释掉与TFPU有关的代码:
PLL_Init();

DMAIR = 0x3f;


也就是没有TFPU的支持下,同样的浮点数加法运算,
加法无TFPU.png

46.853纳秒
主频设置为24MHz,
从结果来看,好像TPFU没起作用啊。
这是什么原因呢?

回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:795
  • 最近打卡:2026-04-02 08:34:34

19

主题

16

回帖

369

积分

中级会员

积分
369
发表于 2026-1-15 16:15:41 | 显示全部楼层
找到原因了。参与运算的变量,全都改成全局变量就可以了,局部变量场合,确实不起作用,但速度似乎更快。
回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2026-4-2 21:11 , Processed in 0.104090 second(s), 49 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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