jrh200310 发表于 2026-1-12 09:04:23

AI8051U使用STC配置小工具使用PLL设置的问题

想测试TFPU的加速效果。在代码只默认下载用的40M时钟时,添加TFPU和不添加TFPU有明显的加速提升。用使用STC配置小工具钩上PLL时钟后。反而不能运行。求助      /*---------------------------------------------------------------------*/
/* --- Web: www.STCAI.com ---------------------------------------------*/
/*---------------------------------------------------------------------*/

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

本例程基于AI8051U为主控芯片的实验箱进行编写测试.

使用Keil C251编译器,Memory Model推荐设置XSmall模式,默认定义变量在edata,单时钟存取访问速度快。

edata建议保留1K给堆栈使用,空间不够时可将大数组、不常用变量加xdata关键字定义到xdata空间。

程序使用P0口来演示跑马灯,输出低驱动。

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

******************************************/


#include "stdio.h"
#include "intrins.h"
#include <AI8051U.H>
#include "math.h"



typedef         unsigned char        u8;
typedef         unsigned int        u16;
typedef         unsigned long        u32;

volatile float xdata sint1 = 155.1432;
volatile float xdata sint2 = 1.0546;
volatile float xdata xsint;

void UartPutc(unsigned char dat)
{
    SBUF = dat;
    while(TI == 0);
    TI = 0;
}

char putchar(char c)
{
    UartPutc(c);
    return c;
}

//==========================================================================
void Uart1Init(void)        //115200bps@40.000MHz
{
    P3M0&=~ 0X01;
        P3M1&=~ 0X02;
        SCON = 0x50;                //8位数据,可变波特率
        AUXR |= 0x01;                //串口1选择定时器2为波特率发生器
        AUXR |= 0x04;                //定时器时钟1T模式
        T2L = 0xA9;                        //设置定时初始值
        T2H = 0xFF;                        //设置定时初始值
        AUXR |= 0x10;                //定时器2开始计时
        //ES = 1;               //串口中断允许
}
//=============================================================================
void Uart1Send(u8 dat)
{
       SBUF = dat ; //
       while(TI==0)
           {;}
   TI = 0;
}

void uart1_send_bytes_to_str(unsigned char *p,unsigned int length) //          // 串口 4 发CR数组里的数据,可以设置长度
{
       unsigned char code zi = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};       
   unsigned int i = 0;
       unsigned char tempH;
       unsigned char tempL;
       while(i<length)
          {
                      
               tempH = zi[(*(p+i))>>4];
               tempL = zi[(*(p+i)&0x0f)];
                       
             Uart1Send(tempH);
               Uart1Send(tempL);       
               Uart1Send(' ');       
             i++;                       
       }
}

//======================================================================================

voiddelay_ms(u8 ms);
/****************外部函数声明和外部变量声明 *****************/

void Timer1_Init(void)                //625微秒@40.000MHz
{
        AUXR |= 0x40;                        //定时器时钟1T模式
        TMOD &= 0x0F;                        //设置定时器模式
        TL1 = 0x58;                                //设置定时初始值
        TH1 = 0x9E;                                //设置定时初始值
        TF1 = 0;                                //清除TF1标志
        TR1 = 1;                                //定时器1开始计时
        ET1 = 1;                                //使能定时器1中断
}


//void Clock_Init(void)
//{
//        HSCLKDIV = 0x01;
//        CLKSEL &= ~(3<<2);
//        CLKSEL |= (1<<2);
//        CLKSEL |= (1<<6);                //PLL->高速IO
//        IRC48MCR = 0x80;                //启动内部48M USB时钟
//        while(!(IRC48MCR&1));
//        IRCBAND &= ~(3<<6);
//        IRCBAND |= (2<<6);
//}

void Clock_Init(void)
{
        HSCLKDIV = 0x01;
        USBCLK |= (1<<7);                //打开PLL功能
        USBCLK &= ~(3<<5);
        USBCLK |= (2<<5);
        CLKSEL |= (1<<7);
        CLKSEL &= ~(3<<2);
        CLKSEL |= (1<<2);
        CLKSEL |= (1<<6);                //PLL->高速IO
        IRC48MCR = 0x80;                //启动内部48M USB时钟
        while(!(IRC48MCR&1));
        IRCBAND &= ~(3<<6);
        IRCBAND |= (2<<6);
}



/******************** 主函数 **************************/
void main(void)
{
        u16 i ;
       
    WTST = 0;//设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
   // EAXFR = 1; //扩展寄存器(XFR)访问使能
        EAXSFR(); //扩展寄存器(XFR)访问使能
    CKCON = 0; //提高访问XRAM速度
   
       
        Clock_Init();
       
       
    P0M1 = 0x00;   P0M0 = 0xff;   //设置为推挽输出
    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;   //设置为准双向口
       
        Uart1Init();

        P34 = 1;

        printf("test tpfu\n");
    while(1)
    {
               
                P33 = 0 ;
       
                for(i=0;i<640;i++)
                {
                  xsint = sint1 * sint2 ;//实测性能提升1倍多
                }
               
                P33 = 1;
                delay_ms(10);
    }
}

//========================================================================
// 函数: voiddelay_ms(unsigned char ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟.
// 返回: none.
// 版本: VER1.0
// 日期: 2013-4-1
// 备注:
//========================================================================

void Delay1ms(void)        //@40.000MHz
{
        unsigned long edata i;

        _nop_();
        _nop_();
        _nop_();
        i = 9998UL;
        while (i) i--;
}



voiddelay_ms(u8 ms)
{
   u16 i;
    for(i=0;i<ms;i++)
        {
       Delay1ms()        ;//@40.000MHz
        }
}

//============================================================

不使用时钟初始化能正常工作。小工具配置如下


jrh200310 发表于 2026-1-12 09:07:11

主程序加了时钟初始化后,反而不能运行
void Clock_Init(void)
{
        HSCLKDIV = 0x01;
        USBCLK |= (1<<7);                //打开PLL功能
        USBCLK &= ~(3<<5);
        USBCLK |= (2<<5);
        CLKSEL |= (1<<7);
        CLKSEL &= ~(3<<2);
        CLKSEL |= (1<<2);
        CLKSEL |= (1<<6);                //PLL->高速IO
        IRC48MCR = 0x80;                //启动内部48M USB时钟
        while(!(IRC48MCR&1));
        IRCBAND &= ~(3<<6);
        IRCBAND |= (2<<6);
}

jrh200310 发表于 2026-1-12 09:08:41

测试发现选择这个PLL时钟就不能运行,不选PLL时钟的时钟初始化可以运行

jrh200310 发表于 2026-1-12 09:10:35

使用AI8051U 32位模式

神农鼎 发表于 2026-1-12 19:58:01

uS级【硬件三角函数/浮点运算器,TFPU】@Ai8051U, @120MHz, 计算sin函数@1.2uS - TinyML,Ai8051U 人工智能 开山之作,AI手写计算器 国芯人工智能技术交流网站 - AI32位8051交流社区

jrh200310 发表于 2026-1-13 09:08:10

今天搞明白了这个界面的信息。 按个界面配置可以工作了。昨天的配置把CPU内核时钟设成了120M了。所以不能运行。但是有个问题,我按个设置TFPU的速度,跟设置成40M的速度是一样的。通过在示波器界面测量前浮点数计数完P34脚的电平变化,可以以观测到这个设置TFPU速度没有起到加快的作用。120M 和40M是一样的。是哪里设弄错了吗?

jrh200310 发表于 2026-1-13 09:12:17

#include "stdio.h"
#include "intrins.h"
#include <AI8051U.H>
#include "math.h"

typedef         unsigned char        u8;
typedef         unsigned int        u16;
typedef         unsigned long        u32;

volatile float xdata sint1 = 155.1432;
volatile float xdata sint2 = 1.0546;
volatile float xdata xsint;

void UartPutc(unsigned char dat)
{
    SBUF = dat;
    while(TI == 0);
    TI = 0;
}

char putchar(char c)
{
    UartPutc(c);
    return c;
}

//==========================================================================
void Uart1Init(void)        //115200bps@40.000MHz
{
    P3M0&=~ 0X01;
        P3M1&=~ 0X02;
        SCON = 0x50;                //8位数据,可变波特率
        AUXR |= 0x01;                //串口1选择定时器2为波特率发生器
        AUXR |= 0x04;                //定时器时钟1T模式
        T2L = 0xA9;                        //设置定时初始值
        T2H = 0xFF;                        //设置定时初始值
        AUXR |= 0x10;                //定时器2开始计时
        //ES = 1;               //串口中断允许
}
//=============================================================================
void Uart1Send(u8 dat)
{
       SBUF = dat ; //
       while(TI==0)
           {;}
   TI = 0;
}

voiddelay_ms(u8 ms);
/****************外部函数声明和外部变量声明 *****************/

void Timer1_Init(void)                //625微秒@40.000MHz
{
        AUXR |= 0x40;                        //定时器时钟1T模式
        TMOD &= 0x0F;                        //设置定时器模式
        TL1 = 0x58;                                //设置定时初始值
        TH1 = 0x9E;                                //设置定时初始值
        TF1 = 0;                                //清除TF1标志
        TR1 = 1;                                //定时器1开始计时
        ET1 = 1;                                //使能定时器1中断
}



//void Clock_Init(void)//120M TPFU
//{
//        HSCLKDIV = 0x01;
//        SPI_CLKDIV = 0x04;
//        I2S_CLKDIV = 0x02;
//        USBCLK |= (1<<7);                //打开PLL功能
//        USBCLK &= ~(3<<5);
//        USBCLK |= (2<<5);
//        CLKSEL |= (1<<7);
//        CLKSEL |= (1<<6);                //PLL->高速IO
//        IRC48MCR = 0x80;                //启动内部48M USB时钟
//        while(!(IRC48MCR&1));
//        IRCBAND &= ~(3<<6);
//        IRCBAND |= (2<<6);
//}

void Clock_Init(void) //TPFU 40M
{
        HSCLKDIV = 0x01;
        SPI_CLKDIV = 0x04;
        I2S_CLKDIV = 0x02;
        TFPU_CLKDIV = 0x03;
        USBCLK |= (1<<7);                //打开PLL功能
        USBCLK &= ~(3<<5);
        USBCLK |= (2<<5);
        CLKSEL |= (1<<7);
        CLKSEL |= (1<<6);                //PLL->高速IO
        IRC48MCR = 0x80;                //启动内部48M USB时钟
        while(!(IRC48MCR&1));
        IRCBAND &= ~(3<<6);
        IRCBAND |= (2<<6);
}



/******************** 主函数 **************************/
void main(void)
{
        u16 i ;
       
    WTST = 0;//设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
   // EAXFR = 1; //扩展寄存器(XFR)访问使能
        EAXSFR(); //扩展寄存器(XFR)访问使能
    CKCON = 0; //提高访问XRAM速度
   
       
        Clock_Init();
       
       
    P0M1 = 0x00;   P0M0 = 0xff;   //设置为推挽输出
    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;   //设置为准双向口
       
        Uart1Init();

        P34 = 1;

        printf("test tpfu\n");
    while(1)
    {
               
                P33 = 0 ;
       
                for(i=0;i<640;i++)
                {
                  xsint = sint1 * sint2 ;//实测性能提升1倍多
                }
               
                P33 = 1;
                delay_ms(10);
    }
}

//========================================================================
// 函数: voiddelay_ms(unsigned char ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟.
// 返回: none.
// 版本: VER1.0
// 日期: 2013-4-1
// 备注:
//========================================================================

void Delay1ms(void)        //@40.000MHz
{
        unsigned long edata i;

        _nop_();
        _nop_();
        _nop_();
        i = 9998UL;
        while (i) i--;
}



voiddelay_ms(u8 ms)
{
   u16 i;
    for(i=0;i<ms;i++)
        {
       Delay1ms()        ;//@40.000MHz
        }
}

//============================================================

jrh200310 发表于 2026-1-13 09:13:14

有添加TFPU库

jrh200310 发表于 2026-1-13 09:22:27

不管怎么设置,不设置,直接屏蔽时钟初始化的代码,都是是这个时间。如何始TPFU时钟生效,求助!

神农鼎 发表于 2026-1-13 15:56:46


用最新 ISP 软件中的 AiCube 图形化配置,自动生成程序框架





页: [1] 2
查看完整版本: AI8051U使用STC配置小工具使用PLL设置的问题