找回密码
 立即注册
查看: 55|回复: 8

AiCube生成代码使用printf_usb输出信息有阻塞现象,如何解决?

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2025-10-12 14:11:23

1

主题

4

回帖

31

积分

新手上路

积分
31
发表于 5 天前 | 显示全部楼层 |阅读模式
1.测试设备:STC8H8K64U实验箱V9.6。
2.代码生成:AiCube生成STC8H8K64U芯片代码。时钟24MHz
3.实现功能:使用printf_usb上传信息到串口助手,控制LED4进行状态翻转。
4.测试仪器:手持示波器FNIRSI-2C53T
5.测试代码如下:
  1. void main(void)
  2. {
  3.     //<<AICUBE_USER_MAIN_INITIAL_BEGIN>>
  4.     // 在此添加用户主函数初始化代码  
  5.     //<<AICUBE_USER_MAIN_INITIAL_END>>
  6.     SYS_Init();
  7.     //<<AICUBE_USER_MAIN_CODE_BEGIN>>
  8.     // 在此添加主函数中运行一次的用户代码  
  9.                 P40 = 0;
  10.     //<<AICUBE_USER_MAIN_CODE_END>>
  11.     while (1)
  12.     {
  13.         //<<AICUBE_USER_MAIN_LOOP_BEGIN>>
  14.         // 在此添加主函数中用户主循环代码
  15.                 printf_usb("LED4 is Toggle!\r\n");
  16.                 P60 = ~P60;
  17.         //<<AICUBE_USER_MAIN_LOOP_END>>
  18.     }
  19. }
复制代码
6.测试步骤如下:
6.1 使用上面测试代码,编译并下载到STC8H8K64U实验箱,连接串口调试助手,但不打开串口,P60端口测试波形如下:
2.bmp

可以看到P60端口的翻转时间约73ms。(即printf_usb阻塞时间73ms)

6.2 使用上面测试代码,编译并下载到STC8H8K64U实验箱,连接串口调试助手,但打开串口,P60端口测试波形如下:
3.bmp

可以看到P60端口的翻转时间约204us。(即printf_usb运行时间204us)


6.3 使用上面测试代码,注释printf_usb(“LED4 is Toggle!\r\n”)代码,编译并下载到STC8H8K64U实验箱,P60端口测试波形如下:
1.bmp

可以看到P60端口的翻转时间约171ns。(正常)

使用printf_usb引起阻塞是什么原因?如何解决阻塞问题。请各位大神指导!
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:328
  • 最近打卡:2025-10-15 08:50:20
已绑定手机

85

主题

3256

回帖

7196

积分

荣誉版主

无情的代码机器

积分
7196
发表于 4 天前 | 显示全部楼层

看下这个帖子,可以加个判断是否打开函数。
https://www.stcaimcu.com/forum.p ... 7406&pid=179406
三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2025-10-12 14:11:23

1

主题

4

回帖

31

积分

新手上路

积分
31
发表于 4 天前 | 显示全部楼层
erci*** 发表于 2025-10-12 00:19
看下这个帖子,可以加个判断是否打开函数。
https://www.stcaimcu.com/forum.php?mod=redirect&goto=findp ...

谢谢!参考帖子修改后测试如下:
1.增加函数声明及isCDCopen()函数。
函数声明如下:
  1. //<<AICUBE_USER_GLOBAL_DEFINE_BEGIN>>
  2. // 在此添加用户全局变量定义、用户宏定义以及函数声明
  3. extern void usb_write_reg(BYTE addr, BYTE dat);
  4. extern BYTE usb_read_reg(BYTE addr);
  5. u8 isCDCOpen();
  6. //<<AICUBE_USER_GLOBAL_DEFINE_END>>
复制代码

isCDCopen()函数如下:
  1. //<<AICUBE_USER_FUNCTION_IMPLEMENT_BEGIN>>
  2. // 在此添加用户函数实现代码  
  3. u8 isCDCOpen()
  4. {
  5.         u8 result = 0;   
  6.         if (DeviceState != DEVSTATE_CONFIGURED){
  7.                         return 0;
  8.         }
  9.         IE2 &= ~0x80;
  10.         usb_write_reg(INDEX, 1);
  11.         if (!(usb_read_reg(INCSR1) & INIPRDY)){
  12.                 result = 1;
  13.         }        
  14.         IE2 |= 0x80;
  15.         return result ;
  16. }
  17. //<<AICUBE_USER_FUNCTION_IMPLEMENT_END>>
复制代码

2.修改main()函数,增加条件判断后printf_usb输出信息。
  1. void main(void)
  2. {
  3.     //<<AICUBE_USER_MAIN_INITIAL_BEGIN>>
  4.     // 在此添加用户主函数初始化代码  
  5.     //<<AICUBE_USER_MAIN_INITIAL_END>>
  6.     SYS_Init();
  7.     //<<AICUBE_USER_MAIN_CODE_BEGIN>>
  8.     // 在此添加主函数中运行一次的用户代码  
  9.                 P40 = 0;
  10.     //<<AICUBE_USER_MAIN_CODE_END>>
  11.     while (1)
  12.     {
  13.         //<<AICUBE_USER_MAIN_LOOP_BEGIN>>
  14.         // 在此添加主函数中用户主循环代码
  15.                 if(isCDCOpen())
  16.                         printf_usb("LED4 is Toggle!\r\n");
  17.                 P60 = ~P60;
  18.         //<<AICUBE_USER_MAIN_LOOP_END>>
  19.     }
  20. }
复制代码

3.测试结果:

3.1 使用上面测试代码,编译并下载到STC8H8K64U实验箱,连接串口调试助手,但不打开串口,P60端口测试波形如下:
4.bmp

可以看到P60端口的翻转时间约3us。(即isCDCopen()函数判断运行时间约3us)
3.2 使用上面测试代码,编译并下载到STC8H8K64U实验箱,连接串口调试助手,打开串口,P60端口测试波形如下:
5.bmp

可以看到P60端口的波形不再是标准方波,输出信号有些紊乱,具体原因还不清楚。


点评

这是因为“isCDCOpen”其实判断的是“发送忙”,所以上面帖子里提到这个函数伴随发送行为才有效。 当printf发送最后一个字节是,printf函数已跳出,但是usb还在最后一个字节“发送忙”,所以会跳过“isCDCOpen”快  详情 回复 发表于 4 天前
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:328
  • 最近打卡:2025-10-15 08:50:20
已绑定手机

85

主题

3256

回帖

7196

积分

荣誉版主

无情的代码机器

积分
7196
发表于 4 天前 | 显示全部楼层
elec_*** 发表于 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;

三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2025-10-12 14:11:23

1

主题

4

回帖

31

积分

新手上路

积分
31
发表于 4 天前 | 显示全部楼层
erci*** 发表于 2025-10-12 14:38
这是因为“isCDCOpen”其实判断的是“发送忙”,所以上面帖子里提到这个函数伴随发送行为才有效。

当prin ...

按照上面代码测试,的确是解决了在打开串口助手后输出波形为方波。

尝试测试:将while(!isCDCOpen())语句放到if条件判断中:
  1. if(isCDCOpen())
  2.                 {
  3.                         printf_usb("LED4 is Toggle!\r\n");
  4.                         while(!isCDCOpen());
  5.                 }                                       
  6.                 P60 = ~P60;
复制代码

测试结果:

1. 串口助手不打开时,代码应该不会进入if语句,能正常输出方波,但实际却无输出(???)。

2.串口助手打开时,输出方波正常。

点评

哈哈细品: 上电默认空闲状态,第一次会进入if条件(没有发送行为就没有“发送忙”状态),但是没打开串口时阻塞在while循环。 [attachimg]117362[/attachimg]  详情 回复 发表于 4 天前
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:328
  • 最近打卡:2025-10-15 08:50:20
已绑定手机

85

主题

3256

回帖

7196

积分

荣誉版主

无情的代码机器

积分
7196
发表于 4 天前 | 显示全部楼层
elec_*** 发表于 2025-10-12 15:20
按照上面代码测试,的确是解决了在打开串口助手后输出波形为方波。

尝试测试:将while(!isCDCOpen())语句 ...

哈哈细品:

上电默认空闲状态,第一次会进入if条件(没有发送行为就没有“发送忙”状态),没打开串口时printf有尝试发送行为,一直没发出去所以阻塞在while循环。
截图202510121604354608.jpg

点评

好的,主要用于单片机教学中让学生理解程序运行过程。想实现无论是否打开串口助手,都能正常工作,我再仔细分析一下!谢谢!  发表于 4 天前
三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-10-16 07:44 , Processed in 0.140295 second(s), 79 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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