RT-thread STM32F103 USB虚拟串口配置

发布于 2020-07-27 00:24:37

RT-thread STM32F103 USB虚拟串口配置
一、使用的环境
硬件环境:
芯片STM32F103VET6,外部晶振8M,USB电路接口如下图,USB做从设备时,D+引脚要上拉到高电平,这里控制PA8引脚输出低电平即可使能D+为高电平。
image001.png

软件环境:
代码编辑和编译软件:RT-Thread Studio 1.1.2;RTOS:rt-thread4.0.2;Windows的串口驱动:VCP_V1.4.0_Setup.exe

二、移植修改过程
(一)基础工程的创建
1.项目工程创建
选择RT-Thread Studio的文件->新建->RT-Thread项目
image003.png

2.选择保存的目录,选择使用的芯片,选择串口及引脚,选择下载工具
image005.png

3.生成的工程使用内部时钟(在drv_clk.c文件中),往串口输出信息,这个工程可以直接编译下载到芯片中校验工程的正确性。
image007.png

(二)使用CubeMX生成时钟配置和外设配置
1.在CubeMX中选择使用的STM32F103VE芯片创建工程
image011.png

2.选择RCC项为外部高速时钟为晶振;选择USB项打开使能,选择USB的IP包;设置时钟频率,主时钟设置为73Mhz,USB时钟设置为48Mhz,cubeMX自动计算分频系数。
image013.png
image015.png
image017.png
image019.png

3.设置工程选项,生成工程代码。
image024.jpg
image022.jpg

(三)RT-thread工程修改
1.时钟配置修改
从CubeMX工程的main.c文件中拷贝SystemClock_Config函数的内容覆盖RT-Thred studio工程drv_clk.c文件中的SystemClock_Config函数中的内容,让时钟能使用外部晶振。
image025.png

2.进行RTOS内核配置,保存。
image031.png

3.因为STM32F103的时钟要单独打开,在drv_clk.c文件中的SystemClock_Config函数中增加USB的时钟使能,在stm32f1xx_hal_conf.h打开HAL库的USB相关代码编译选项。
image033.png
image035.png

4.配置驱动
打开rtconfig.h文件,在USB驱动配置的地方增加USB设备的BSP定义选项和D+上拉电平控制引脚(从drv_gpio.c中按照对应的管脚查到对应的控制编号,如果D+已经接到搞电平可以不用添加这个控制),修改USB_VENDOR_ID 为0x0483,修改USB_PRODUCT_ID为 0x5740(需改这两项才可以使用ST提供的Windows虚拟串口驱动,否则设备被识别为其他设备)
image037.png
image039.png
image041.png

5.main.c函数修改
/ 用于接收消息的信号量 /
static struct rt_semaphore rx_sem;
static rt_device_t serial;

/ 接收数据回调函数 /
static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
{

/* 串口接收到数据后产生中断,调用此回调函数,然后发送接收信号量 */
rt_sem_release(&rx_sem);

return RT_EOK;

}
static void serial_thread_entry(void *parameter)
{

char ch;
while (1)
{
    /* 从串口读取一个字节的数据,没有读取到则等待接收信号量 */
    while (rt_device_read(serial, -1, &ch, 1) != 1)
    {
        /* 阻塞等待接收信号量,等到信号量后再次读取数据 */
        rt_sem_take(&rx_sem, RT_WAITING_FOREVER);
    }
    /* 读取到的数据通过串口错位输出 */
    rt_device_write(serial, 0, &ch, 1);
}

}
int main(void)
{

int count = 1;
int err = 0;
rt_thread_t tid;
char buf[] = "hello rt-thread!\r\n";
serial = rt_device_find("vcom");
if (!serial)
{
    rt_kprintf("find failed!\n");
    return RT_ERROR;
}
err = rt_device_init(serial);
if (!serial)
{
    rt_kprintf("find failed!\n");
    return RT_ERROR;
}
err = rt_device_open(serial, 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(serial, uart_input);
rt_thread_t thread = rt_thread_create("serial", serial_thread_entry, RT_NULL, 1024, 25, 10);
if (thread != RT_NULL)
{
    rt_thread_startup(thread);
}
while (count++)
{
    rt_device_write(serial, 0, buf, rt_strlen(buf));
    LOG_D("Hello RT-Thread!");
    rt_thread_mdelay(1000);
}

return RT_EOK;

}
5.测试收发,串口工具要打开DTR控制
image043.png

三、参考资料

  1. https://blog.csdn.net/newbie_Blogger/article/details/92617242
  2. https://blog.csdn.net/ckg3824278/article/details/107388105
  3. https://blog.csdn.net/qq_27508477/article/details/103673793
2 条评论

发布
问题