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>>
}
不要在中断里打印,设置flag集中在main里打印
printf_usb底层实现代码似乎是在库里面对吧,所以我也不好说。
但是,假如你是使用串口发送数据,如果主循环与中断都同时调用串口发送函数,且依靠TI标志来判断发送完成,那么就有可能一方清除了TI标志导致另一方等不到这个标志而陷入死循环。
建议按楼上的方法来。 上面这个是测试程序,无意中发现在多个地方调用pringf_usb这个函数可能会导致程序阻塞。
封装库里可能没有将USB接口当做独占设备处理,也可能缺少超时处理,使调用pringf_usb函数时有可能进入死循环。
页:
[1]