单片机与上位机通信时,一般选择串口通信,在一次STC单片机的开发中,我从数据手册里得知,STC8H8K64U单片机带有USB外设,这让我萌生了使用虚拟串口的想法。
虚拟串口相比于传统串口,省去了USB转TTL芯片,降低了开发成本;传统串口通信的速率受到单片机主频的影响,速度有限,而虚拟串口的通信速率是USB全速模式下的通信速率,即12Mb/s(串口助手波特率拉满doge);除此之外,虚拟串口还有这许多优点。
在查找相关资料后,顺利地用上了虚拟串口,同时额外带来了一个功能——不断电下载。熟悉STC单片机的同志应该有所了解,在单片机烧录程序时,需要冷启动才可以进入烧录状态,这个操作降低了开发的效率,而不断电下载则将这个问题解决了。
下面我将为读者展示具体实现步骤,请多指教!
目录
导入源码
新建完工程后,从官网下载源码(https://www.stcai.com/filedownload/656048),将解压后的stc32_stc8_usb.h和stc_usb_cdc_8h_xdata.lib文件复制到工程目录下,然后进行如下配置。
在工程中引用头文件stc32_stc8_usb.h并添加以下代码。
#include<stc8h.h>
#include<stc32_stc8_usb.h>
//#define PRINTF_SEGLED //printf输出重定向到ISP下载软件中的7段数码管
#define PRINTF_HID //printf输出直接重定向到USB HID接口
#if defined PRINTF_SEGLED
#define printf SEG7_ShowString
#elif defined PRINTF_HID
#define printf printf_hid
#endif
char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#"; //下载指令
void USB_CDC_Init()
{
P3M0 &= ~0x03; //将USB的D+/D-引脚设为高阻输入模式
P3M1 |= 0x03;
IRC48MCR = 0x80; //使能内部48M的USB专用IRC
while(!(IRC48MCR & 0x01))
{
}
USBCLK = 0x00; //设置USB时钟源为内部48M的USB专用IRC
USBCON = 0x90; //使能USB功能
usb_init(); //调用USB CDC初始化库函数
IE2 |= 0x80; //使能USB中断
EA = 1;
while(DeviceState != DEVSTATE_CONFIGURED) //等待USB完成配置
{
}
}
void usb_handle()
{
//当接收完成数据后,bUsbOutReady置1
//接收字节数保存在OutNumber中
//接收数据保存在UsbOutBuffer缓冲区
if(bUsbOutReady)
{
USB_SendData(UsbOutBuffer,OutNumber); //向上位机发送数据
usb_OUT_done(); //处理完成接收的数据后调用该函数接收下一个数据
}
}
然后在main函数中调用
void main()
{
P_SW2 |= 0x80;
USB_CDC_Init();
delay_ms(1000);
printf("USB CDC Start!\r\n");
while(1)
{
usb_handle();
}
}
编译完成后烧录烧录进单片机,结果如图。
免断电自动下载
官方的USB CDC代码还具有免断电下载功能,下载操作如下。
最后
USB_CDC的大体应用如上,请多指教!有疑问的读者欢迎评论区留言。