找回密码
 立即注册
查看: 48|回复: 3

8H8K64U Printf_USB 打卡

[复制链接]
  • 打卡等级:以坛为家I
  • 打卡总天数:248
  • 最近打卡:2025-04-27 09:57:01
已绑定手机

24

主题

756

回帖

3315

积分

超级版主

积分
3315
QQ
发表于 4 天前 | 显示全部楼层 |阅读模式
实验一:printf_usb("Hello World !\r\n"), 第一个完整的C语言
1:在官网上下载最新的库文件,https://stcai.com/,选择软件工具一栏,点击库函数
截图202504271613366787.jpg
截图202504271614261864.jpg
2:打开KEIL编译器并创建项目
截图202504271615288983.jpg
截图202504271617051872.jpg
截图202504271623262559.jpg
截图202504271630205964.jpg
3:打开最新版本的AIapp-ISP-V6.95M软件,选择单片机型号为:STC8H8K64U,打开程序文件,点击下载
截图202504271632241209.jpg
代码如下:

#include "stc8h.h"                          //头文件不分大小写,但关键字分大小写
#include "ai_usb.h"                         //USB 库和 USB 虚拟设备的头文件,需要在项目文件中添加对应的 USB 库

void main(void)
{
//        EAXFR=1;允许访问扩展的特殊寄存器,XFR
        
//        WTST = 0;设置取程序代码等待时间,赋值为 0 表示不等待,程序以最快速度运行
//        CKCON = 0;设置访问片内的 xdata 速度,赋值为 0 表示用最快速度访问,不增加额外的等待时间
        P_SW2|=0X80;                        ////使能可以访问扩展的特殊功能寄存器XFR,没有冲突不用关闭
        usb_init();                                //初始化 USB 模块,并且会将【P3.0, P3.1】初始化为高阻输入,不影响 USB【D-, D+】通讯
        EA=1;                                                        //使能总中断
        
        while(1)
        {
        printf_usb("Hello World !\r\n");//直接打印输出 “Hello World !” 到主机相应软件的 USB【CDC/HID-串口助手】
                           // \r 是回车,跳到行首,\n 是换行,就是换到下一行;\r\n 不要交换次序
        }
}


回复

使用道具 举报 送花

3

主题

1160

回帖

1031

积分

等待验证会员

积分
1031
发表于 4 天前 | 显示全部楼层
在嵌入式系统开发中,调试信息的输出是一个非常重要的环节。通过调试信息,开发者可以实时监控程序的运行状态,快速定位问题。在传统的嵌入式开发中,通常使用串口(UART)来输出调试信息。然而,随着USB接口的普及,使用USB进行调试信息输出逐渐成为一种更为便捷的选择。本文将介绍如何在嵌入式系统中使用USB接口实现类似printf的功能,并通过一个简单的“Hello World”示例来演示其实现过程。

1. 背景介绍

在嵌入式系统中,printf函数是C语言标准库中用于格式化输出的函数。然而,标准的printf函数通常依赖于操作系统的支持,而在裸机(bare-metal)或实时操作系统(RTOS)环境下,标准库的实现可能并不适用。因此,开发者需要根据具体的硬件平台和需求,自行实现printf函数。

USB(Universal Serial Bus)是一种广泛使用的通信接口,具有高速、即插即用等优点。通过USB接口输出调试信息,不仅可以提高数据传输速度,还可以减少硬件资源的占用。本文将介绍如何在嵌入式系统中通过USB接口实现printf功能。

2. 硬件平台

本文以一款常见的嵌入式微控制器为例,假设该微控制器集成了USB接口,并且支持USB CDC(Communication Device Class)协议。CDC协议是一种用于模拟串口通信的USB协议,通过CDC协议,USB设备可以模拟成一个虚拟串口,从而方便地与主机进行通信。

3. 软件实现

3.1 USB CDC驱动

首先,需要实现USB CDC驱动。USB CDC驱动的实现通常包括以下几个部分:

1. USB设备描述符:描述USB设备的类型、接口、端点等信息。
2. USB端点配置:配置USB端点的类型、大小、方向等。
3. USB中断处理:处理USB中断事件,如数据传输完成、设备连接等。
4. USB数据传输:实现数据的发送和接收。

由于USB CDC驱动的实现较为复杂,通常可以使用芯片厂商提供的库函数或参考开源项目进行开发。

3.2 printf函数实现

在USB CDC驱动的基础上,可以实现一个类似于printf的函数,用于通过USB接口输出调试信息。以下是一个简单的实现示例:
  1. c
  2. include
  3. include
  4. include
  5. // USB发送函数,假设已经实现
  6. void USBSendData(const char data, int length);
  7. void printfusb(const char format, ...) {
  8.     char buffer[128];
  9.     valist args;
  10.     vastart(args, format);
  11.     int length = vsnprintf(buffer, sizeof(buffer), format, args);
  12.     vaend(args);
  13.    
  14.     if (length > 0) {
  15.         USBSendData(buffer, length);
  16.     }
  17. }
复制代码

在上述代码中,printfusb函数首先使用vsnprintf函数将格式化字符串写入缓冲区,然后通过USBSendData函数将缓冲区中的数据发送到USB接口。

3.3 示例程序

以下是一个简单的示例程序,通过printfusb函数输出“Hello World”信息:
  1. c
  2. int main(void) {
  3.     // 初始化USB
  4.     USBInit();
  5.    
  6.     // 输出调试信息
  7.     printfusb("Hello World !\r\n");
  8.    
  9.     while (1) {
  10.         // 主循环
  11.     }
  12. }
复制代码

在上述程序中,首先调用USBInit函数初始化USB接口,然后通过printfusb函数输出“Hello World”信息。

4. 调试与测试

在完成代码编写后,可以通过以下步骤进行调试与测试:

1. 编译与下载:将代码编译并下载到目标硬件平台。
2. 连接USB:将目标硬件平台通过USB接口连接到主机。
3. 查看输出:在主机上打开串口调试工具,选择对应的虚拟串口,查看是否能够接收到“Hello World”信息。

5. 总结

本文介绍了如何在嵌入式系统中通过USB接口实现类似printf的功能,并通过一个简单的“Hello World”示例演示了其实现过程。通过USB接口输出调试信息,不仅可以提高数据传输速度,还可以减少硬件资源的占用。在实际开发中,开发者可以根据具体的硬件平台和需求,进一步优化和扩展该功能。

6. 参考文献

1. USB CDC协议规范
2. 嵌入式系统开发手册
3. C语言标准库文档

通过本文的介绍,希望读者能够掌握在嵌入式系统中使用USB接口输出调试信息的基本方法,并能够在实际项目中灵活应用。

[本文内容由国芯人工智能辅助生成,仅供参考]
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:248
  • 最近打卡:2025-04-27 09:57:01
已绑定手机

24

主题

756

回帖

3315

积分

超级版主

积分
3315
QQ
发表于 4 天前 | 显示全部楼层
实验二: 查询方式,查询到电脑命令后,printf_usb("Hello World !\r\n")或其他
1:前期准备工作与实验一一致
2:编译
截图202504271635289889.jpg
3:打开最新版本的AIapp-ISP-V6.95M软件
截图202504271636284411.jpg

源代码:
实验二: 查询方式,查询到电脑命令后,printf_usb("Hello World !\r\n")或其他
源代码:#include "STC8H.h" //头文件不分大小写,但关键字分大小写
#include "ai_usb.h" //USB 库和 USB 虚拟设备的头文件,需要在项目文件中添加对应的 USB 库
//由于在 USB 库函数的代码中已经定义了,不停电 ISP 下载命令字”@STCISP#”,
//只需要在下载软件的“收到用户命令后复位到 ISP 监控程序区”选项卡中进行相应的设置,
//即可实现 USB 不停电 ISP 下载功能,或串口不停电 ISP 下载功能。
void main(void)
{
//EAXFR = 1; //允许访问扩展的特殊寄存器,XFR
//WTST = 0;  //设置取程序代码等待时间,赋值为 0 表示不等待,程序以最快速度运行
//CKCON = 0; //设置访问片内的 xdata 速度,赋值为 0 表示用最快速度访问,不增加额外的等待时间
P_SW2 |= 0x80; //使能可以访问扩展的特殊功能寄存器XFR,没有冲突不用关闭
usb_init(); //初始化 USB 模块
EA = 1; //使能全局中断
while(1)
{
if(bUsbOutReady)
{ //查询方式:USB-Device 单片机查询是否有接收完成的 USB 主机送来的数据包
//“bUsbOutReady”:主机发送给 HID/CDC 设备的数据状态标志。
//USB 库中有定义 bUsbOutReady 位变量,查询方式必须调用一次“usb_OUT_done();”
//状态位为 1 表示,主机发送给 HID/CDC 设备数据已完成,
//设备已成功接收一包数据,等待对数据继续处理。
if(UsbOutBuffer[0]==7)
printf_usb("HelloWorld!\r\n");
//接收到的数据包的第 0 个字节是 7,打印“HelloWorld!”
else if(UsbOutBuffer[0]==8)
printf_usb("China!\r\n");
//接收到的数据包的第 0 个字节是 8 后,打印“China!”
usb_OUT_done(); //USB 查询方式,Device 单片机通知【主机可以发下一个数据包】
//当使用査询方式 if(bUsbOutReady),查询调用 USB 库函数时,在数据处理完成后,
//必须调用一次“usb_OUT_done();”,这样才能接收下一包数据。
//如果是使用中断方式调用 USB 库函数,用户程序不需要调用“usb_OUT_done();”
//中断方式,USB 库函数内部会自动处理。
}
}
}
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:248
  • 最近打卡:2025-04-27 09:57:01
已绑定手机

24

主题

756

回帖

3315

积分

超级版主

积分
3315
QQ
发表于 4 天前 | 显示全部楼层
实验三: 中断方式,单片机USB中断接收服务函数收到命令后,printf_usb("Hello World !\r\n")或其他

1:编译
截图202504271638089115.jpg
2:打开最新版本的AIapp-ISP-V6.95M软件
截图202504271638421411.jpg
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-1 22:18 , Processed in 0.110602 second(s), 67 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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