本帖最后由 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 学习视频:
|