AiCube生成代码使用printf_usb输出信息有阻塞现象,如何解决?
1.测试设备:STC8H8K64U实验箱V9.6。2.代码生成:AiCube生成STC8H8K64U芯片代码。时钟24MHz
3.实现功能:使用printf_usb上传信息到串口助手,控制LED4进行状态翻转。
4.测试仪器:手持示波器FNIRSI-2C53T
5.测试代码如下:
void main(void)
{
//<<AICUBE_USER_MAIN_INITIAL_BEGIN>>
// 在此添加用户主函数初始化代码
//<<AICUBE_USER_MAIN_INITIAL_END>>
SYS_Init();
//<<AICUBE_USER_MAIN_CODE_BEGIN>>
// 在此添加主函数中运行一次的用户代码
P40 = 0;
//<<AICUBE_USER_MAIN_CODE_END>>
while (1)
{
//<<AICUBE_USER_MAIN_LOOP_BEGIN>>
// 在此添加主函数中用户主循环代码
printf_usb("LED4 is Toggle!\r\n");
P60 = ~P60;
//<<AICUBE_USER_MAIN_LOOP_END>>
}
}6.测试步骤如下:
6.1 使用上面测试代码,编译并下载到STC8H8K64U实验箱,连接串口调试助手,但不打开串口,P60端口测试波形如下:
可以看到P60端口的翻转时间约73ms。(即printf_usb阻塞时间73ms)
6.2 使用上面测试代码,编译并下载到STC8H8K64U实验箱,连接串口调试助手,但打开串口,P60端口测试波形如下:
可以看到P60端口的翻转时间约204us。(即printf_usb运行时间204us)
6.3 使用上面测试代码,注释printf_usb(“LED4 is Toggle!\r\n”)代码,编译并下载到STC8H8K64U实验箱,P60端口测试波形如下:
可以看到P60端口的翻转时间约171ns。(正常)
使用printf_usb引起阻塞是什么原因?如何解决阻塞问题。请各位大神指导!{:baoquan:}
看下这个帖子,可以加个判断是否打开函数。
https://www.stcaimcu.com/forum.php?mod=redirect&goto=findpost&ptid=17406&pid=179406
ercircle 发表于 2025-10-12 00:19
看下这个帖子,可以加个判断是否打开函数。
https://www.stcaimcu.com/forum.php?mod=redirect&goto=findp ...
谢谢!参考帖子修改后测试如下:
1.增加函数声明及isCDCopen()函数。
函数声明如下:
//<<AICUBE_USER_GLOBAL_DEFINE_BEGIN>>
// 在此添加用户全局变量定义、用户宏定义以及函数声明
extern void usb_write_reg(BYTE addr, BYTE dat);
extern BYTE usb_read_reg(BYTE addr);
u8 isCDCOpen();
//<<AICUBE_USER_GLOBAL_DEFINE_END>>
isCDCopen()函数如下:
//<<AICUBE_USER_FUNCTION_IMPLEMENT_BEGIN>>
// 在此添加用户函数实现代码
u8 isCDCOpen()
{
u8 result = 0;
if (DeviceState != DEVSTATE_CONFIGURED){
return 0;
}
IE2 &= ~0x80;
usb_write_reg(INDEX, 1);
if (!(usb_read_reg(INCSR1) & INIPRDY)){
result = 1;
}
IE2 |= 0x80;
return result ;
}
//<<AICUBE_USER_FUNCTION_IMPLEMENT_END>>
2.修改main()函数,增加条件判断后printf_usb输出信息。
void main(void)
{
//<<AICUBE_USER_MAIN_INITIAL_BEGIN>>
// 在此添加用户主函数初始化代码
//<<AICUBE_USER_MAIN_INITIAL_END>>
SYS_Init();
//<<AICUBE_USER_MAIN_CODE_BEGIN>>
// 在此添加主函数中运行一次的用户代码
P40 = 0;
//<<AICUBE_USER_MAIN_CODE_END>>
while (1)
{
//<<AICUBE_USER_MAIN_LOOP_BEGIN>>
// 在此添加主函数中用户主循环代码
if(isCDCOpen())
printf_usb("LED4 is Toggle!\r\n");
P60 = ~P60;
//<<AICUBE_USER_MAIN_LOOP_END>>
}
}
3.测试结果:
3.1 使用上面测试代码,编译并下载到STC8H8K64U实验箱,连接串口调试助手,但不打开串口,P60端口测试波形如下:
可以看到P60端口的翻转时间约3us。(即isCDCopen()函数判断运行时间约3us)
3.2 使用上面测试代码,编译并下载到STC8H8K64U实验箱,连接串口调试助手,打开串口,P60端口测试波形如下:
可以看到P60端口的波形不再是标准方波,输出信号有些紊乱,具体原因还不清楚。
elec_bird 发表于 2025-10-12 14:11
谢谢!参考帖子修改后测试如下:
1.增加函数声明及isCDCopen()函数。
函数声明如下:
这是因为“isCDCOpen”其实判断的是“发送忙”,所以上面帖子里提到这个函数伴随发送行为才有效。
当printf发送最后一个字节是,printf函数已跳出,但是usb还在最后一个字节“发送忙”,所以后续几次主循环会跳过“isCDCOpen”快速翻转P60操作方波忽长忽短,
可以观察:
if(isCDCOpen())
printf("LED4 is Toggle!\r\n");
while(!isCDCOpen()); //等待发送彻底结束,仅观察方波用,要是串口没打开就卡在这里了
P60 = !P60;
ercircle 发表于 2025-10-12 14:38
这是因为“isCDCOpen”其实判断的是“发送忙”,所以上面帖子里提到这个函数伴随发送行为才有效。
当prin ...
按照上面代码测试,的确是解决了在打开串口助手后输出波形为方波。
尝试测试:将while(!isCDCOpen())语句放到if条件判断中:
if(isCDCOpen())
{
printf_usb("LED4 is Toggle!\r\n");
while(!isCDCOpen());
}
P60 = ~P60;
测试结果:
1. 串口助手不打开时,代码应该不会进入if语句,能正常输出方波,但实际却无输出(???)。
2.串口助手打开时,输出方波正常。
elec_bird 发表于 2025-10-12 15:20
按照上面代码测试,的确是解决了在打开串口助手后输出波形为方波。
尝试测试:将while(!isCDCOpen())语句 ...
哈哈细品:
上电默认空闲状态,第一次会进入if条件(没有发送行为就没有“发送忙”状态),没打开串口时printf有尝试发送行为,一直没发出去所以阻塞在while循环。
页:
[1]