jrh200310 发表于 2025-4-12 13:59:09

AI8051U 32模式卡定时器中断 | 已解决

代码如下:

void main(void)
{
    WTST = 0;//设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1; //扩展寄存器(XFR)访问使能
    CKCON = 0; //提高访问XRAM速度

   delayms(3000);
      

    P0M1 = 0x00;   P0M0 = 0x00;   //设置为准双向口
    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;   //设置为准双向口
    Uart1_Init();      //115200bps@40MHz
      Timer0_Init();                //10毫秒@40.000MHz

      EA = 1 ;      
    P5M0 |= 0x01; P5M1 &= ~0x01;

      printf("\n开机");

    while(1)
    {
            printf("\n1");
                delayms(100);
                P50 = !P50;

    }
}

//----------------------------------------------

void Timer0_Isr(void) interrupt 1
{
      ET0 = 0;                              //使能定时器0中断
      TF0 = 0;                              //清除TF0标志
      sys_tick ++ ;
      //printf("\nsys_tick = %bu",sys_tick);
      ET0 = 1;                              //使能定时器0中断      
}
//----------------------------------------------------
void Uart1_Isr(void) interrupt 4
{
      if (TI)                              //检测串口1发送中断
      {
                TI = 0;                        //清除串口1发送中断请求位
      }
      if (RI)                              //检测串口1接收中断
      {
                RI = 0;                        //清除串口1接收中断请求位
      }
}

使用AI8051U 32位模式,设置了定时器T0 10mS中断一次。初始化后开启定时器中断和全局中断,出现主程序不能正常工作,while(1)里的printf("\n1");不能输出,P50不能翻转,
但是在 Timer0_Isr(void) interrupt 1里的printf("\nsys_tick = %bu",sys_tick)可以正常打印;
关闭全局中断后while(1)里才能正常工作。




国芯人工智能 发表于 2025-4-12 14:03:00

以下是对该代码的专业分析及优化建议:

代码分析

该代码主要实现了对单片机AI8051U的初始化配置,包括指令延时、扩展寄存器访问、端口模式设置、串口初始化、定时器初始化以及中断使能等功能。整体逻辑清晰,但在一些细节上存在优化空间。

1. 指令延时与访问速度优化
   代码通过WTST = 0将指令延时设置为最快,同时通过CKCON = 0提高了XRAM的访问速度。这种配置适用于对实时性要求较高的场景,但需注意在低功耗模式下可能需要调整。

2. 端口模式设置
   代码将所有端口(P0-P7)设置为准双向口(PxM1 = 0x00; PxM0 = 0x00)。这种配置适合大多数通用I/O应用,但如果某些端口仅用于输入或输出,可以考虑单独配置以提高效率。

3. 串口初始化
   Uart1Init()函数用于初始化串口,波特率为115200bps@40MHz。需确保该函数内部已正确配置相关寄存器(如SCON、PCON等)以及波特率生成器。

4. 定时器初始化
   Timer0Init()函数用于初始化定时器0,定时周期为10毫秒@40.000MHz。需确保该函数已正确配置TMOD、TH0、TL0等寄存器,并启用了定时器中断。

5. 中断使能
   通过EA = 1开启了全局中断。确保在定时器中断服务函数中已正确处理中断标志位,以避免重复触发。

6. 调试信息输出
   代码通过printf输出调试信息(如“开机”和“1”)。需确保串口已正确初始化,并且printf函数已重定向到串口输出。

优化建议

1. 端口模式配置优化
   如果某些端口仅用于输入或输出,可以单独配置其模式。例如,若P5.0仅用于输出,可以优化如下:
   c
   P5M0 |= 0x01;// 设置为推挽输出
   P5M1 &= ~0x01; // 清除输入模式

2. 定时器初始化函数检查
   确保Timer0Init()函数已正确配置定时器0,并启用了中断。例如:
   c
   void Timer0Init(void)
   {
       TMOD &= 0xF0; // 清除定时器0模式位
       TMOD |= 0x01; // 设置为模式1(16位定时器)
       TH0 = 0xFC;   // 定时器初值高位
       TL0 = 0x18;   // 定时器初值低位
       TR0 = 1;      // 启动定时器0
       ET0 = 1;      // 使能定时器0中断
   }

3. 中断服务函数实现
   确保已实现定时器0的中断服务函数,并在其中清除中断标志位。例如:
   c
   void Timer0ISR(void) interrupt 1
   {
       TH0 = 0xFC; // 重装定时器初值
       TL0 = 0x18;
       // 添加定时器中断处理逻辑
   }

4. 调试信息优化
   如果调试信息较多,可以考虑使用条件编译或日志级别控制,以减少对程序性能的影响。例如:
   c
   #define DEBUG 1
   #if DEBUG
       printf("\n开机");
   #endif

总结

该代码整体结构合理,适合AI8051U单片机的基本应用场景。通过对端口模式、定时器初始化和中断服务函数的优化,可以进一步提升代码的效率和可靠性。建议在实际应用中根据具体需求进一步调整和测试。

[本文内容由国芯人工智能辅助生成,仅供参考]

jrh200310 发表于 2025-4-12 14:39:10

在8位模式下无此问题,在32位模式下才有此问题

ercircle 发表于 2025-4-12 14:58:08

中断和UartPutc同时在操作TI噢,检查下

可以参考实验箱串口例程或者使用AiCube生成新工程

jrh200310 发表于 2025-4-12 16:17:16

ercircle 发表于 2025-4-12 14:58
中断和UartPutc同时在操作TI噢,检查下

可以参考实验箱串口例程或者使用AiCube生成新工程


确实如你所说,去掉串口中断关于TX标志的代码,解决
页: [1]
查看完整版本: AI8051U 32模式卡定时器中断 | 已解决