USB-CDC虚拟串口,和传统串口
程序需要单片机的串口1,兼容2种方式,不需要同时1、通过USB有线和计算机通讯
2、串口通过蓝牙模块,无线和计算机通讯
是不是,程序中调用usb_init(),串口1就作为USB虚拟串口,否则就可以作为传统串口用
USB只能使用P30、P31,所以只能复用串口1
打开USB,关闭串口,IO设置高阻使用USB
关闭USB,打开串口(包括波特率发生器),P30设置准双向+4K上拉,P31设置推挽使用串口 DebugLab 发表于 2026-1-9 11:15
USB只能使用P30、P31,所以只能复用串口1
打开USB,关闭串口,IO设置高阻使用USB
关闭USB,打开串口(包括 ...
谢谢回复,打开USB,就是调用usb_init()? zanjun 发表于 2026-1-12 10:58
谢谢回复,打开USB,就是调用usb_init()?
使用一个IO口,上电时判断高低电平,高电平程序使用USB通讯,低电平使用传统串口
使用传统串口下载程序,试了传统串口通讯,没有问题
可USB通讯,系统不能识别出USB-CDC
bit Detect_Ext_Port(void)
{
P33 = 1;
Delay1ms(1);
if (P33 == 1) return(1);
return(0);
}
void Init_COMM(void)
{
//串口1,与PC通讯,蓝牙
P_SW1 &= B00111111; //串口1在p3.0 p3.1
PCON &= B00111111; //速度不加倍
SCON = B01010000; //串口1,模式1,8位数据,可变波特率
AUXR |= B00000001; //串口1选择定时器2为波特率发生器
AUXR |= B00000100; //定时器2时钟为Fosc,即1T,
AUXR &= B11110111; //T2定时方式
T2L = 0xD8; //设定定时初值,250000,晶振40MHz
T2H = 0xFF;
AUXR |= B00010000; //启动定时器2,T2固定16位自动重装
//SBUF
RI = 0;
TI = 0;
REN = 1; //开放串口1接收
ES = 1; //串口1中断允许
//IP.4 IPH.4优先级
//0k
EA = 1;
}
void UART1_Routine(void) interrupt 4
{
unsigned char temp;
if (RI == 0) return;
temp = SBUF;
bb = temp;
RI = 0;
}
void Send_Byte_COM1(unsigned char chr)
{
TI = 0;
TB8 = 0;
NOP2();
SBUF = chr;
while(TI == 0);
TI = 0;
}
void main()
{
unsigned int aa, i;
bb=0;
Delay1ms(2000);
P_SW2 |= 0x80;
P0M1 = 0x00; P0M0 = 0x00;
P1M1 = 0x00; P1M0 = 0x00;
P2M1 = 0x00; P2M0 = 0x00;
P3M1 = 0x00; P3M0 = 0x00;
P4M1 = 0x00; P4M0 = 0x00;
P5M1 = 0x00; P5M0 = 0x00;
P6M1 = 0x00; P6M0 = 0x00;
P7M1 = 0x00; P7M0 = 0x00;
P3M1 = B00001000; //I/O口3模式控制器1,初始值=高阻输入,
P3M0 = B00000000;
P3PU = B00001000; //p33高阻输入,内部4.2k上拉
USB_Flag = Detect_Ext_Port();
if (USB_Flag==1)
{
P34 = 0;
Delay1ms(200);
P34 = 1;
Delay1ms(200);
P34 = 0;
usb_init(); //USB CDC 接口配置
}
if (USB_Flag==0)
{
P3M1 = B00000000; //I/O口3模式控制器1,初始值=高阻输入,
P3M0 = B00000010; //准双向口不能接上拉??
Init_COMM();
Delay1ms(100);
Send_Byte_COM1('1');
Send_Byte_COM1('2');
Send_Byte_COM1('3');
Send_Byte_COM1('4');
Send_Byte_COM1('5');
Send_Byte_COM1('6');
P34 = 0;
Delay1ms(200);
P34 = 1;
Delay1ms(200);
P34 = 0;
Delay1ms(200);
P34 = 1;
}
EA = 1;
//可有可无???可以主动发数据了
//if(DeviceState!=DEVSTATE_CONFIGURED); //如果USB配置没有完成,等待
aa=0x30;
while (1)
{
if (bb > 0)
{
Send_Byte_COM1(bb);
P34 = ~P34;
bb = 0;
}
if (bUsbOutReady)
{
if (UsbOutBuffer == '1')
{
ff = 1;
}else
if (UsbOutBuffer == '2')
{
ff = 0;
CDC_Buffer=0x36;
CDC_Buffer=0x37;
CDC_Buffer=0x38;
CDC_Buffer=0x39;
CDC_Buffer=0x41;
CDC_Buffer=0x42;
P36 = 0;
USB_SendData(CDC_Buffer,9);//22us,每字节2.5us,每秒400k字节
P36 = 1;
}else
{
USB_SendData(UsbOutBuffer,OutNumber); //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
}
usb_OUT_done();//当前包的数据处理完成
}
if (ff == 1)
{
CDC_Buffer=0x55;
CDC_Buffer=0xAA;
CDC_Buffer=0x30;
CDC_Buffer=0x31;
CDC_Buffer=0x32;
CDC_Buffer=0x33;
CDC_Buffer=0x34;
CDC_Buffer=0x35;
CDC_Buffer=0x0D;
P36 = 0;
USB_SendData(CDC_Buffer,9);
P36 = 1;
}
}
}
使用传统串口下载如下程序,也不能识别USB
void main()
{
P_SW2 |= 0x80;
P0M1 = 0x00; P0M0 = 0x00;
P1M1 = 0x00; P1M0 = 0x00;
P2M1 = 0x00; P2M0 = 0x00;
P3M1 = 0x00; P3M0 = 0x00;
P4M1 = 0x00; P4M0 = 0x00;
P5M1 = 0x00; P5M0 = 0x00;
P6M1 = 0x00; P6M0 = 0x00;
P7M1 = 0x00; P7M0 = 0x00;
usb_init(); //USB CDC 接口配置
EA = 1;
while (1)
{
if (bUsbOutReady)
{
USB_SendData(UsbOutBuffer,OutNumber); //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
usb_OUT_done();
}
}
}
#include"stc8h.h" //头文件不分大小写,但关键字分大小写
#include"ai_usb.h" //USB库和USB虚拟设备的头文件
voidmain(void)
{
P_SW2 |= 0x80; //允许访问扩展的特殊寄存器,XFR
//32位8051需要使用下面3句进行初始化
// EAXFR = 1; //允许访问扩展的特殊寄存器,XFR
// WTST = 0; //设置取程序代码等待时间,赋值为0表示不等待,程序以最快速度运行
// CKCON = 0; //设置访问片内的xdata速度,赋值为0表示用最快速度访问,不增加额外的等待时间
P0M0 = 0x00; P0M1 = 0x00; //初始化P0口为准双向口模式
P1M0 = 0x00; P1M1 = 0x00; //初始化P1口为准双向口模式
P2M0 = 0x00; P2M1 = 0x00; //初始化P2口为准双向口模式
P3M0 = 0x00; P3M1 = 0x00; //初始化P3口为准双向口模式
P4M0 = 0x00; P4M1 = 0x00; //初始化P4口为准双向口模式
P5M0 = 0x00; P5M1 = 0x00; //初始化P5口为准双向口模式
usb_init();
//初始化USB模块,并且会将【P3.0,P3.1】初始化为高阻输入,不影响USB【D-,D+】通讯
EA = 1; //使能总中断
while (1)
{
printf_usb("Hello World !\r\n");
//\r是回车,并跳到行首,\n是换行,就是换到下一行;\r\n不要交换次序
}
}
推荐优先看的 printf_usb()及usb不停电下载演示视频 - 学习打卡区 ,为集中维护,一个学习专题只发一个贴持续跟贴 国芯人工智能技术交流网站 - AI32位8051交流社区
页:
[1]