嵌入式技术论坛
直播中

马祥

7年用户 774经验值
私信 关注
[经验]

USBD设备虚拟串口使用评测

一.USB入门
1.硬件层

USB的传输线分别由地线、电源线、D+、D-四条线构成,D+和D-是差分输入线,在USB设备端,D-接上拉电阻是USB低速设备,D+接上拉电阻是全速设备,高速设备在初始化阶段以全速设备身份出现,设备与主机经过一系列握手信号确认是全速设备还是高速设备。数据在USB线里传送是由低位到高位发送的,USB采用不归零取反来传输数据,当传输线上的差分数据输入0时就取反,输入1时就保持原值,为了确保信号发送的准确性,当在USB总线上发送一个包时,传输设备就要进行位插入(即在数据流中每连续6个1后就插入一个0),从而强迫NRZI码发生变化。
2.软件层
USB数据是由二进制数字串构成的,数字串构成最小的单位域(同步域,标识域,地址域,端点域,帧号域,数据域,校验域),域再构成包(令牌包、数据包、握手包),包再构成事务(IN、OUT、SETUP),事务最后构成传输(中断传输、同步传输、批量传输和控制传输)。
二.评测内容
USBD设备虚拟串口使用(即CDC)
1.进入RT-THREAD官网,查看新手指导教程,这里用RT-Thread Studio软件测试。
2.Numaker-IoT-M487 USB Full-Speed OTG连接原理图

3.打开RT-Thread Studio软件,下载Numaker-IoT-487开发板的软件支持包,点击文件->新建->RT-THREAD项目

4.输入工程名,选择基于开发板,点击完成。

5.点击工程下,RT-THREAD SettingS,在Drivers下面,鼠标右击一下,进入配置项。

6.在USB配置项,设备类型选Enable to use device as CDC device.
7.主函数进行相关初始化

int main(int argc, char **argv)
{
int err;
rt_kprintf("this is rt-thread test!
");
virtual_com =rt_device_find("vcom");//查找设备
if(virtual_com!=RT_NULL)
{
err=rt_device_init(virtual_com);
}
else
return -1;
rt_device_open(virtual_com,RT_DEVICE_FLAG_RDWR|RT_DEVICE_FLAG_INT_RX);//打开设备
rt_sem_init(&rx_sem,"rx_sem",0,RT_IPC_FLAG_FIFO);//初始化接收信号量

rt_device_set_rx_indicate(virtual_com,uart_input);//设置串口接收回调函数
rt_thread_t thread =rt_thread_create("virtual_com",virtual_com_thread_entry,RT_NULL,1024,25,10);
if(thread!=RT_NULL) //创建串口处理函数线程
rt_thread_startup(thread);
else
return -1;

return 0;
}
8.接收数据并处理,上位机发送的数据,开发板收到后,再发送给上位机。

static rt_device_t virtual_com =RT_NULL;
static struct rt_semaphore rx_sem;
static char rcv_buf[64];
static unsigned char rcv_num=0;
static unsigned char rcv_startf=1;//上电默认一直等待接收数据

static rt_err_t uart_input(rt_device_t virtual_com,rt_size_t size)
{
rt_sem_release(&rx_sem);
return RT_EOK;
}
static char uart_get_char(void)
{
char ch;

while (rt_device_read(virtual_com, 0, &ch, 1) !=1)
{
rt_sem_control(&rx_sem, RT_IPC_CMD_RESET, RT_NULL);
if(rcv_startf)
rt_sem_take(&rx_sem, RT_WAITING_FOREVER);
else if(-RT_ETIMEOUT == rt_sem_take(&rx_sem, 100))
{ //接收的数据之间加等待超时,超时或者有'
',认为一包数据接收完。
rcv_startf = 1;
ch = '
';
return ch;
}
}
rcv_startf = 0; //
return ch;
}
static void virtual_com_thread_entry(void *parameter)
{
char ch,temp;

while(1)
{
temp = uart_get_char();
if(temp != '
')
{
if(rcv_num<64)
rcv_buf[rcv_num++] = temp;
else {
rt_device_write(virtual_com,0,&rcv_buf,sizeof(rcv_buf));
rt_memset(rcv_buf, 0, sizeof(rcv_buf));
rcv_num=0;
rcv_buf[rcv_num++] = temp;
}
}
else
{
rt_device_write(virtual_com,0,&rcv_buf,sizeof(rcv_buf));
rcv_num = 0;
rt_memset(rcv_buf, 0, sizeof(rcv_buf));
}
}
}
9.编译工程,下载完成后,按下开发板复位键,打开电脑端串口软件。


原作者:转角偶遇幸福_

回帖(1)

joker0530

2022-6-9 14:50:19
古德古德,么么哒
举报

更多回帖

发帖
×
20
完善资料,
赚取积分