lilijin1995 发表于 2022-10-23 11:47

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

本帖最后由 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
*
* @brief   Initializes the USARTx peripheral.
*
* @param   baudrate - USART communication baud rate.
*
* @returnNone
*/
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 = 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 学习视频:

https://www.bilibili.com/video/BV1MR4y1Q7Ni/?spm_id_from=333.788&vd_source=2bbde87de845d5220b1d8ba075c12fb0

tpgf 发表于 2022-11-8 11:46

是通过什么方式把接收到的数据显示出来的呢

guanjiaer 发表于 2022-11-8 12:06

串口发送数据的速度和pcb布线有直接的联系吗

heimaojingzhang 发表于 2022-11-8 12:13

一般串口的最高传输速度是不是就115200了呢

keaibukelian 发表于 2022-11-8 13:06

楼主总结出来的初始化串口的过程的6个步骤,可以进行顺序的调换吗

paotangsan 发表于 2022-11-8 13:19

总中断和串口中断的使能顺序有具体的要求吗

renzheshengui 发表于 2022-11-8 13:29

感觉中断服务里边的代码太多了 这样的话会不会造成丢失数据呢

lilijin1995 发表于 2022-11-9 11:22

renzheshengui 发表于 2022-11-8 13:29
感觉中断服务里边的代码太多了 这样的话会不会造成丢失数据呢

都是ifelse,真正执行的没几句,这是参考正点原子的
页: [1]
查看完整版本: CH32V003配置USART实现接收上位机发送过来的数据并回显