找回密码
 立即注册
查看: 28|回复: 2

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

[复制链接]
  • 打卡等级:常住居民III
  • 打卡总天数:112
  • 最近打卡:2026-07-04 17:55:09

38

主题

201

回帖

953

积分

高级会员

积分
953
发表于 昨天 17:55 | 显示全部楼层 |阅读模式
    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了呢?


回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:112
  • 最近打卡:2026-07-04 17:55:09

38

主题

201

回帖

953

积分

高级会员

积分
953
发表于 昨天 18:35 | 显示全部楼层
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发送 后在虚拟串口才能看到发送的内容,但是实际测试效果却不是这样的。困惑死了。


回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:112
  • 最近打卡:2026-07-04 17:55:09

38

主题

201

回帖

953

积分

高级会员

积分
953
发表于 昨天 19:06 | 显示全部楼层
我主要使用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;

回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2026-7-5 05:56 , Processed in 0.067540 second(s), 50 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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