xie2101 发表于 2026-7-4 17:55:09

问一个 Ai8051U 实验箱 时钟频率 相关的问题。

    1. 在官方的例程<< Ai8051U-32Bit\27-通过定时器周期性调度任务综合例程,简单实用的任务调度系统,推荐>>

config.h 中 有时钟相关代码如下:

//#define MAIN_Fosc      22118400L    //¶¨ÒåÖ÷ʱÖÓ
//#define MAIN_Fosc      12000000L    //¶¨ÒåÖ÷ʱÖÓ
//#define MAIN_Fosc      11059200L    //¶¨ÒåÖ÷ʱÖÓ
//#define MAIN_Fosc      5529600L   //¶¨ÒåÖ÷ʱÖÓ
#define MAIN_Fosc      24000000L    //¶¨ÒåÖ÷ʱÖÓ

//========================================================================
//                               ¶¨Ê±Æ÷¶¨Òå
//========================================================================

#define Timer0_Reload   (MAIN_Fosc / 1000)      //Timer 0 ÖÐ¶ÏÆµÂÊ, 1000´Î/Ãë

//========================================================================
//                               ´®¿Ú¶¨Òå
//========================================================================

#define PrintUart       2      //1:printf ʹÓà UART1; 2:printf ʹÓà UART2
#define Baudrate      115200L
#define TM               (65536 - (((MAIN_Fosc) / (Baudrate) + 2) / 4))    // 原来的代码没有 +2 ,这里我改了一下, 没什么影响。


   


----------------------------------
新增代码

void usb_init()
{
    P3M0 &= ~0x03;
    P3M1 |= 0x03;

    IRC48MCR = 0x80;
    while (!(IRC48MCR & 0x01));

    USBCLK = 0x00;
    USBCON = 0x90;

    usb_write_reg(FADDR, 0x00);
    usb_write_reg(POWER, 0x81);
    usb_write_reg(INTRIN1E, 0x3f);
    usb_write_reg(INTROUT1E, 0x3f);
    usb_write_reg(INTRUSBE, 0x07);
    usb_write_reg(POWER, 0x01);

    DeviceState = DEVSTATE_DEFAULT;
    Ep0State.bState = EPSTATE_IDLE;
    InEpState = 0x00;
    OutEpState = 0x00;

    Ep4InBusy = 0;
    Ep5InBusy = 0;
    Ep4OutBusy = 0;
    Ep5OutBusy = 0;

    EUSB = 1;
}

---------------------------------------------------------------------------------------------

在 UartInit(); 前调用一下    usb_init();   就时钟就只能设置成24mhz,设置成 22118400hz 会乱码。
---------------------------------------------------------------------------------------------
为什么调用一下usb_init就只能设置24mhz了呢?






xie2101 发表于 2026-7-4 18:35:43

2.在 << Ai8051U-32Bit\51-USB-CDC转双串口-根据串口波特率选择出厂时校准的几种常用时钟频率做主频>> 例程中


有 代码如下:
          switch (baud)
    {
    case 14400:
    case 19200:
    case 28800:
    case 38400:
    case 57600:
    case 115200:
    case 230400:
    case 460800:
    case 921600:    //可被 22.1184M 整除
      SetMCLK(0); //主时钟 22.1184MHz
      break;
    case 1500000:   //可被 30M 整除
      SetMCLK(2); //主时钟 30MHz
      break;
    default:
      SetMCLK(1); //主时钟 24MHz
      break;
    }

--------------------------

void SetMCLK(BYTE clk) //设置主频
{
    switch(clk)
    {
    case 1:
      if(MAIN_Fosc == 24000000L) break;
      //选择24MHz
      CLKDIV = 0x04;
      IRTRIM = T24M_ADDR;
      VRTRIM = VRT27M_ADDR;
      IRCBAND = (IRCBAND & ~0x03) | IRCBAND_27M;
      CLKDIV = 1;
      MAIN_Fosc =      24000000L;      //定义主时钟
      break;

    case 2:
      if(MAIN_Fosc == 30000000L) break;
      //选择30MHz
      CLKDIV = 0x04;
      IRTRIM = T30M_ADDR;
      VRTRIM = VRT27M_ADDR;
      IRCBAND = (IRCBAND & ~0x03) | IRCBAND_27M;
      CLKDIV = 1;
      MAIN_Fosc =      30000000L;      //定义主时钟
      break;

    case 3:
      if(MAIN_Fosc == 40000000L) break;
      //选择40MHz
      CLKDIV = 0x04;
      IRTRIM = T40M_ADDR;
      VRTRIM = VRT44M_ADDR;
      IRCBAND = (IRCBAND & ~0x03) | IRCBAND_44M;
      CLKDIV = 1;
      MAIN_Fosc =      40000000L;      //定义主时钟
      break;

    default:
      if(MAIN_Fosc == 22118400L) break;
      //选择22.1184MHz
      CLKDIV = 0x04;
      IRTRIM = T22M_ADDR;
      VRTRIM = VRT27M_ADDR;
      IRCBAND = (IRCBAND & ~0x03) | IRCBAND_27M;
      CLKDIV = 1;
      MAIN_Fosc =      22118400L;      //定义主时钟
      break;
    }
}

这个例程中 usb和uart就可以设置22118400? 好奇怪。
不过我在实验箱上测了一下这个例子,发现uart2 发什么收到什么。目前也没弄懂为啥会这样。
这个例程按道理来说,uart发送 后在虚拟串口才能看到发送的内容,但是实际测试效果却不是这样的。困惑死了。


xie2101 发表于 2026-7-4 19:06:43

我主要使用uart2, 所以我紧接着 查看 << Ai8051U-32Bit\27-通过定时器周期性调度任务综合例程,简单实用的任务调度系统,推荐 >> 是这么初始化uart2 的。

    S2_S = 1;       //UART2 switch to: 0: P1.2 P1.3,1: P4.2 P4.3
    S2CFG |= 0x01;//使用串口2时,W1位必需设置为1,否则可能会产生不可预期的错误
    S2CON = (SCON & 0x3f) | 0x40;
    T2L= TM;
    T2H= TM>>8;                                                    //#define TM               (65536 - (((MAIN_Fosc) / (Baudrate) + 2) / 4))    // 原来的代码没有 +2 ,这里我改了一下
    AUXR |= 0x14; //定时器2时钟1T模式,开始计时
    PS2 = 1;

查看 << Ai8051U-32Bit\51-USB-CDC转双串口-根据串口波特率选择出厂时校准的几种常用时钟频率做主频>> 是这么初始化uart2 的。

sys_init() 中
    S2_S = 1;       //UART2(RxD2_2/P4.2, TxD2_2/P4.3)
uart_init() 中

    S2CON = 0x50;
    T2L = BR(MAIN_Fosc,115200);
    T2H = BR(MAIN_Fosc,115200) >> 8;            //#define BR(clk,n)                   (65536 - ((clk) / (n) + 2)/ 4)
    T2x12 = 1;
    T2R = 1;
    PS2 = 1;    //提高串口2中断优先级,防止数据丢失
    ES2 = 1;

乘风飞扬 发表于 2026-7-6 11:18:48

config.h 中 有时钟相关代码如下:

#define MAIN_Fosc      22118400L
//#define MAIN_Fosc      12000000L
//#define MAIN_Fosc      11059200L
//#define MAIN_Fosc      5529600L
//#define MAIN_Fosc      24000000L

修改主时钟时,MAIN_Fosc 定义需要同步修改

页: [1]
查看完整版本: 问一个 Ai8051U 实验箱 时钟频率 相关的问题。