spc_cll 发表于 2026-4-12 19:27:05

AI8051U的printf_usb函数异常导致main主循环阻塞

在多个地方调用printf_usb函数,可能会导致程序阻塞问题。
在测试例程中,同时在main主循环和定时器中调用printf_usb,使用usb口连接到电脑。
当STC-ISP打开对应的COM口时,可以观察到main主循环和定时中断函数中调用的printf_usb正常输出,同时相应的p2.0和p2.1指示灯正常闪烁。
当STC-ISP关闭对应的COM口后,定时器对应的P2.1指示灯正常闪烁,而主循环对应的P2.0指示灯闪烁几次后,就不再闪烁了。
===================================================================
测试例程是使用AiClue助手生成的32位程序项目,主要配置如下:

生成的程序中仅做如下修改:
1.修改定时器初始化程序:(带**的行)

void TIMER0_Init(void)
{
    。。。
    TIMER0_SetIntPriority(0);         //设置中断为最低优先级   
    //TIMER0_EnableInt();               //使能定时器0中断//*****在这里使能,定时器不工作
    TIMER0_SetPrescale(T0_PSCR);      //设置定时器0的8位预分频
    TIMER0_SetReload16(T0_RELOAD);      //设置定时器0的16位重载值
    TIMER0_Run();                     //定时器0开始运行
    TIMER0_EnableInt();               //使能定时器0中断//****将这句移到这里,定时器才能正常工作   
}


2.main函数主循环:

u8 main_loop_cnt=0;   //主循环次数
u8 timer_call_cnt=0;    //定时器次数
void main(void)


{    。。。
    while (1)
    {
      main_loop_cnt++;
      P20=~P20;               //用于观察主循环运行状态
      P0=~main_loop_cnt;
      printf_usb("main_loop_cnt=%d,timer_call_cnt=%d\n",main_loop_cnt,timer_call_cnt);
      delay_ms(500);                        
    }
。。。
}


3.定时器中断函数:

void TIMER0_ISR(void) interrupt TMR0_VECTOR
{
    //<<AICUBE_USER_TIMER0_ISR_CODE1_BEGIN>>
    // 在此添加中断函数用户代码
                        timer_call_cnt++;
                        P21=~P21;   //用于观察定时器运行状态
                        printf_usb("main_loop_cnt=%d,timer_call_cnt=%d\n",main_loop_cnt,timer_call_cnt);      
    //<<AICUBE_USER_TIMER0_ISR_CODE1_END>>      
}



ercircle 发表于 2026-4-12 21:45:26

不要在中断里打印,设置flag集中在main里打印

lcwswust 发表于 2026-4-13 09:40:17

printf_usb底层实现代码似乎是在库里面对吧,所以我也不好说。
但是,假如你是使用串口发送数据,如果主循环与中断都同时调用串口发送函数,且依靠TI标志来判断发送完成,那么就有可能一方清除了TI标志导致另一方等不到这个标志而陷入死循环。
建议按楼上的方法来。

spc_cll 发表于 2026-4-13 13:31:37

上面这个是测试程序,无意中发现在多个地方调用pringf_usb这个函数可能会导致程序阻塞。
封装库里可能没有将USB接口当做独占设备处理,也可能缺少超时处理,使调用pringf_usb函数时有可能进入死循环。
页: [1]
查看完整版本: AI8051U的printf_usb函数异常导致main主循环阻塞