打印
[单片机芯片]

CH32V003配置USART实现接收上位机发送过来的数据并回显

[复制链接]
4337|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 lilijin1995 于 2022-10-23 11:56 编辑

#申请原创#
@21小跑堂
3.3 Eg3_USART
前面几节介绍了 CH32V003的 IO 口操作。这一节我们将学习 CH32V003的串口,教大家如何使用 CH32V003的串口来发送和接收数据。本章将实现如下功能:CH32V003通过串口和上位机的对话,CH32V003在收到上位机发过来的字符串后,原原本本的返回给上位机。
串口作为 MCU 的重要外部接口,同时也是软件开发重要的调试手段,其重要性不言而喻。现在基本上所有的 MCU 都会带有串口,CH32V003自然也不例外。
3.3.1硬件设计:
硬件过于简单,这里展示一下原理图,USART1 TX-->D.5   RX-->D.6。
3.3.2 软件设计:
本节的代码设计,我们直接在MRS(MounRiver Studio)建立的工程目录Debug下面的debug.c,debug.h上修改。这里我们对代码部分稍作讲解。打开串口实验工程,我们就可以看到上述两个文件里面的代码,先介绍 USART_Printf_Init函数,该函数代码如下:
/*********************************************************************
* @fn      USART_Printf_Init
*
* [url=home.php?mod=space&uid=247401]@brief[/url]   Initializes the USARTx peripheral.
*
* @param   baudrate - USART communication baud rate.
*
* [url=home.php?mod=space&uid=266161]@return[/url]  None
*/
void USART_Printf_Init(uint32_t baudrate) {
    GPIO_InitTypeDef GPIO_InitStructure = { 0 };
    USART_InitTypeDef USART_InitStructure = { 0 };
    NVIC_InitTypeDef NVIC_InitStructure = { 0 };

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_USART1,
            ENABLE);

    /* USART1 TX-->D.5   RX-->D.6 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOD, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOD, &GPIO_InitStructure);

    USART_InitStructure.USART_BaudRate = baudrate;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl =
            USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;

    USART_Init(USART1, &USART_InitStructure);
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    ;

    USART_Cmd(USART1, ENABLE);
}

从该代码可以看出,其初始化串口的过程,总结出6个步骤。我们用标号①~⑥标示了顺序:① 串口时钟使能,GPIO 时钟使能② 串口复位③ GPIO 端口模式设置④ 串口参数初始化⑤ 初始化 NVIC 并且开启中断⑥ 使能串口这里需要重申的是,对于复用功能下的 GPIO 模式怎么判定,这个需要查看《CH32V003RM》P54 的表格“表 7-3 通用同步异步串行收发器(USART)”,这里还是拿出来再讲解一下吧。查看手册得知,配置全双工的串口 1,那么 TX(PA9)管脚需要配置为推挽复用输出,RX(PA10)管脚配置为浮空输入或者带上拉输入。模式配置参考下面表格:
file:///C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/image-20221022222712218.png?lastModify=1666496354
接下来,还要编写中断服务函数。串口 1 的中断服务函数USART1_IRQHandler

void USART1_IRQHandler(void) {
    u8 Res;
    if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
        Res = USART_ReceiveData(USART1);
        if ((USART_RX_STA & 0x8000) == 0)       //接收未完成
                {
            if (USART_RX_STA & 0x4000)       //接收到了0x0d
                    {
                if (Res != 0x0a)
                    USART_RX_STA = 0;       //接收错误,重新开始
                else
                    USART_RX_STA |= 0x8000;  //接收完成了
            } else //还没收到0X0D
            {
                if (Res == 0x0d)
                    USART_RX_STA |= 0x4000;
                else {
                    USART_RX_BUF[USART_RX_STA & 0X3FFF] = Res;
                    USART_RX_STA++;
                    if (USART_RX_STA > (USART_REC_LEN - 1))
                        USART_RX_STA = 0; //接收数据错误,重新开始接收
                }
            }
        }
    }
}

大家对上面代码一定很熟悉,没错这就是正点原子STM32的串口接收代码,这里大家可以去支持正版学习一下;
3.3.3 下载验证:
打开串口调试助手可以看到,“请输入数据,以回车键结束”提示发送数据,勾选发送新行后,发送数据直接回显;
file:///C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/image-20221022224532898.png?lastModify=1666496354

3.3.4 学习视频:



使用特权

评论回复
沙发
tpgf| | 2022-11-8 11:46 | 只看该作者
是通过什么方式把接收到的数据显示出来的呢

使用特权

评论回复
板凳
guanjiaer| | 2022-11-8 12:06 | 只看该作者
串口发送数据的速度和pcb布线有直接的联系吗

使用特权

评论回复
地板
heimaojingzhang| | 2022-11-8 12:13 | 只看该作者
一般串口的最高传输速度是不是就115200了呢

使用特权

评论回复
5
keaibukelian| | 2022-11-8 13:06 | 只看该作者
楼主总结出来的初始化串口的过程的6个步骤,可以进行顺序的调换吗

使用特权

评论回复
6
paotangsan| | 2022-11-8 13:19 | 只看该作者
总中断和串口中断的使能顺序有具体的要求吗

使用特权

评论回复
7
renzheshengui| | 2022-11-8 13:29 | 只看该作者
感觉中断服务里边的代码太多了 这样的话会不会造成丢失数据呢

使用特权

评论回复
8
lilijin1995|  楼主 | 2022-11-9 11:22 | 只看该作者
renzheshengui 发表于 2022-11-8 13:29
感觉中断服务里边的代码太多了 这样的话会不会造成丢失数据呢

都是ifelse,真正执行的没几句,这是参考正点原子的

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

54

主题

162

帖子

7

粉丝