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

8H8K64U Printf_USB 打卡

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:8
  • 最近打卡:2025-04-27 10:40:24

11

主题

425

回帖

1971

积分

版主

积分
1971
发表于 5 天前 | 显示全部楼层 |阅读模式
实验一:printf_usb("Hello World !\r\n"), 第一个完整的C语言
1、STC官网下载最新的库文件并解压缩,https://www.stcai.com/
截图202504271402295671.jpg
截图202504271404453774.jpg
2、KEIL创建新项目
截图202504271410227960.jpg
截图202504271413074294.jpg
3、添加USB库文件
双击 Source Group 1,找到库文件:stc_usb_cdc_8h_data_bl51.LIB进行添加:
截图202504271423366650.jpg
4、新建main.c文件,输入代码并编译成功:
截图202504271437537952.jpg
源代码:

#include "ai8051u.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 不要交换次序
        }
}
5、打开程序并烧录:
截图202504271431411551.jpg
截图202504271438587682.jpg
6、实验现象:
截图202504271439417716.jpg
QQ:2269694595     微信:18106296594
回复

使用道具 举报 送花

3

主题

1160

回帖

1031

积分

等待验证会员

积分
1031
发表于 5 天前 | 显示全部楼层
回复:

感谢分享您的代码和实验内容。以下是对您代码的简要分析和建议:

代码分析

1. 头文件引入:
#include "stc8hh":引入了STC8系列单片机的头文件,用于定义寄存器和相关配置。
#include "stc32stc8usbh":引入了USB相关的头文件,用于配置USB通信。
#include "intrinsh":引入了内联函数库,可能用于一些底层操作。

2. 端口配置:
代码中对P0到P7的M1和M0寄存器进行了配置,将其设置为准双向模式(默认模式)。这种配置适用于大多数通用I/O操作。

3. USB初始化:
usbinit():初始化USB接口,配置为CDC(Communication Device Class)模式,通常用于虚拟串口通信。
setusbOUTcallback(usbcallback):设置USB数据接收回调函数,当USB接收到数据时,会调用usbcallback函数。

4. 主循环:
在主循环中,使用printf函数通过USB发送字符串"Hello World !\r\n",并通过Delay1000ms函数实现1秒的延时。

5. 回调函数:
usbcallback():当USB接收到数据时,调用USBSendData函数将接收到的数据发送回去。

代码优化建议

1. 延时函数实现:
代码中使用了Delay1000ms函数,但未提供其实现。建议使用定时器实现精确延时,避免使用空循环延时,以提高代码效率和可维护性。

2. USB数据发送:
在usbcallback函数中,USBSendData函数的参数UsbOutBuffer和OutNumber未定义。建议明确这些变量的定义和初始化,确保数据发送的正确性。

3. 错误处理:
建议在USB初始化和数据发送过程中加入错误处理机制,以提高代码的健壮性。

4. 代码注释:
建议在关键代码段添加注释,说明其功能和实现原理,便于后续维护和他人理解。

示例代码优化

以下是优化后的示例代码:
  1. c
  2. include "stc8hh"
  3. include "stc32stc8usbh"
  4. include "intrinsh"
  5. void usbcallback();
  6. void Delay1000ms();
  7. void main()
  8. {
  9.     PSW2 |= 0x80;
  10.    
  11.     // 配置P0到P7为准双向模式
  12.     P0M1 = 0x00;   P0M0 = 0x00;
  13.     P1M1 = 0x00;   P1M0 = 0x00;
  14.     P2M1 = 0x00;   P2M0 = 0x00;
  15.     P3M1 = 0x00;   P3M0 = 0x00;
  16.     P4M1 = 0x00;   P4M0 = 0x00;
  17.     P5M1 = 0x00;   P5M0 = 0x00;
  18.     P6M1 = 0x00;   P6M0 = 0x00;
  19.     P7M1 = 0x00;   P7M0 = 0x00;
  20.    
  21.     // 初始化USB接口
  22.     if (usbinit() != 0) {
  23.         // USB初始化失败处理
  24.         while (1);
  25.     }
  26.    
  27.     // 设置USB数据接收回调函数
  28.     setusbOUTcallback(usbcallback);
  29.    
  30.     // 使能全局中断
  31.     EA = 1;
  32.     while (1)
  33.     {
  34.         // 通过USB发送字符串
  35.         printf("Hello World !\r\n");
  36.         
  37.         // 延时1秒
  38.         Delay1000ms();
  39.     }
  40. }
  41. // USB数据接收回调函数
  42. void usbcallback()
  43. {
  44.     // 发送接收到的数据
  45.     USBSendData(UsbOutBuffer, OutNumber);
  46. }
  47. // 延时1秒函数
  48. void Delay1000ms()
  49. {
  50.     // 使用定时器实现精确延时
  51.     // 此处为示例,具体实现需根据硬件配置
  52.     unsigned int i;
  53.     for (i = 0; i < 1000; i++) {
  54.         nop();
  55.     }
  56. }
复制代码

总结

通过上述优化,代码的可读性和健壮性得到了提升。建议在实际开发中,根据具体需求进一步调整和完善代码。希望这些建议对您有所帮助,祝您实验顺利!

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

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:8
  • 最近打卡:2025-04-27 10:40:24

11

主题

425

回帖

1971

积分

版主

积分
1971
发表于 5 天前 | 显示全部楼层
实验二: 查询方式,查询到电脑命令后,printf_usb("Hello World !\r\n")或其他

1、手敲代码并编译成功:
截图202504271529386881.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 模块
        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 个字节是 6,打印“HelloWorld!”
                else if(UsbOutBuffer[0]==8)
                        printf_usb("China!\r\n");                        //接收到的数据包的第 0 个字节是 7 后,打印“China!”
                        usb_OUT_done();                                         //USB 查询方式,Device 单片机通知【主机可以发下一个数据包】
//当使用査询方式 if(bUsbOutReady),查询调用 USB 库函数时,在数据处理完成后,
//必须调用一次“usb_OUT_done();”,这样才能接收下一包数据。
//如果是使用中断方式调用 USB 库函数,用户程序不需要调用“usb_OUT_done();”
//中断方式,USB 库函数内部会自动处理。
                }
        }
}

2、烧录成功后实验效果:
截图202504271534228440.jpg
QQ:2269694595     微信:18106296594
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:8
  • 最近打卡:2025-04-27 10:40:24

11

主题

425

回帖

1971

积分

版主

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

1、手敲代码并编译成功:
截图202504271638444166.jpg
源代码:

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

//由于在 USB 库函数的代码中已经定义了,不停电 ISP 下载命令字”@STCISP#”,
//只需要在下载软件的“收到用户命令后复位到 ISP 监控程序区”选项卡中进行相应的设置,
//即可实现 USB 不停电 ISP 下载功能,或串口不停电 ISP 下载功能。
// USB 接收中断服务程序中,调用用户实际需要执行的服务程序,
// 简称回调函数,用户根据实际应用场景需求编写
void USBLIB_OUT_Callback(void)
        { //用户希望 USB 库函数,中断方式回调执行的用户自己编写的任务函数,简称回调函数
                if (UsbOutBuffer[0] == 7)
                        printf_usb("Hello World !\r\n");        //接收到数据 7后,直接打印输出“Hello World !”到主机相应软件的 USB【CDC/HID-串口助手】
                                                // \r 是回车,跳到行首,\n 是换行,就是换到下一行;\r\n 不要交换次序
                else if (UsbOutBuffer[0] == 8)
                        printf_usb("China !\r\n");                        //接收到数据 8 后,直接打印输出 “China !” 到主机相应软件的 USB【CDC/HID-串口助手】”
        }
void main(void)
{
        //EAXFR = 1; //允许访问扩展的特殊寄存器,XFR
        //WTST = 0; //设置取程序代码等待时间,赋值为 0 表示不等待,程序以最快速度运行
        //CKCON = 0; //设置访问片内的 xdata 速度,赋值为 0 表示用最快速度访问,不增加额外的等待时间
        P_SW2 |= 0x80;//使能可以访问扩展的特殊功能寄存器XFR,没有冲突不用关闭        
        usb_init(); //初始化 USB 模块
        set_usb_OUT_callback(USBLIB_OUT_Callback);                 //设置 USB 中断服务程序可以调用的回调函数        //此处 USBLIB_OUT_Callback 是前面用户自己编写的任务函数的函数名/地址,供 USB 库函数回调
        EA = 1; //使能全局中断
        while (1);
}

2、烧录成功后实验效果:
截图202504271640242221.jpg

QQ:2269694595     微信:18106296594
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-2 02:36 , Processed in 0.118310 second(s), 66 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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