第14章 USART 2&3&4&5接发通信实验
第十四章 USART 2&3&4&5接发通信实验
1. 硬件设计
参考第十二章 USART1接发通信实验
2. 软件设计
2.1 USART2宏定义
具体细节可以参考USART1,如果我们要使用其他串口,稍微改一下配置就行了,下面我们以USART2为例
// USARTx 引脚宏定义
#define USARTx_GPIO_CLK RCC_APB2Periph_GPIOA
#define USARTx_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd
// TX-发送数据输出引脚
#define USARTx_TX_GPIO_PORT GPIOA
#define USARTx_TX_GPIO_PIN GPIO_Pin_2
// RX-接收数据输入引脚
#define USARTx_RX_GPIO_PORT GPIOA
#define USARTx_RX_GPIO_PIN GPIO_Pin_3
// USARTx 相关参数宏定义
#define USARTx USART2
#define USARTx_CLK RCC_APB1Periph_USART2
#define USARTx_APBxCLKCmd RCC_APB1PeriphClockCmd
#define USARTx_BaudRate 115200
// NVIC配置
#define USARTx_IRQ USART2_IRQn
#define USARTx_IRQHandler USART2_IRQHandler
2.2 对照一下串口1
// USARTx 引脚宏定义
#define USARTx_GPIO_CLK RCC_APB2Periph_GPIOA
#define USARTx_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd
// TX-发送数据输出引脚
#define USARTx_TX_GPIO_PORT GPIOA
#define USARTx_TX_GPIO_PIN GPIO_Pin_9
// RX-接收数据输入引脚
#define USARTx_RX_GPIO_PORT GPIOA
#define USARTx_RX_GPIO_PIN GPIO_Pin_10
// USARTx 相关参数宏定义
#define USARTx USART1
#define USARTx_CLK RCC_APB2Periph_USART1
#define USARTx_APBxCLKCmd RCC_APB2PeriphClockCmd
#define USARTx_BaudRate 115200
// NVIC配置
#define USARTx_IRQ USART1_IRQn
#define USARTx_IRQHandler USART1_IRQHandler
我们发现就是改了一下名字,RCC我们使用的是APB1这个要注意一下,再就是引脚问题了,总体差距不大
2.3 回顾初始化
#include "usart.h"
static void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = USARTx_IRQ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void USART_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
USARTx_GPIO_APBxClkCmd(USARTx_GPIO_CLK, ENABLE);
USARTx_APBxCLKCmd(USARTx_CLK, ENABLE);
// TX引脚配置
GPIO_InitStructure.GPIO_Pin = USARTx_TX_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStructure);
// RX引脚配置
GPIO_InitStructure.GPIO_Pin = USARTx_RX_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 输入浮空
GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStructure);
// USART 配置
USART_InitStructure.USART_BaudRate = USARTx_BaudRate; // 波特率115200
USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 字长8位数据
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_Rx | USART_Mode_Tx; // 收发模式
USART_Init(USARTx, &USART_InitStructure);
// NVIC配置
NVIC_Configuration();
USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE); // 使能串口接收中断
USART_Cmd(USARTx, ENABLE); // 使能串口
}
// ---------编写接发数据函数----------
// 发送一个字节函数
// 函数参数:USARTx:串口号,ch:发送的字节
void USART_SendByte(USART_TypeDef *pUSARTx, uint8_t ch)
{
USART_SendData(pUSARTx, ch);
while(USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET); // 等待发送完成
}
// 发送一个8位数组函数
// 函数参数:USARTx:串口号,data:发送的8位数据
void USART_SendArray(USART_TypeDef *pUSARTx, uint8_t *pArray, uint16_t len)
{
uint8_t i;
for(i = 0; i < len; i++)
{
USART_SendByte(pUSARTx, pArray[i]); // 循环写入数组
}
while(USART_GetFlagStatus(pUSARTx, USART_FLAG_TC) == RESET); // 等待发送完成
}
// 发送一个字符串函数
// 函数参数:USARTx:串口号,pStr:发送的字符串
void USART_SendString(USART_TypeDef *pUSARTx, uint8_t *pStr)
{
unsigned int k = 0;
do{
USART_SendByte(pUSARTx, *(pStr+k)); // 循环写入字符串
k++;
}while(*(pStr+k)!= '\0'); // 直到遇到结束符‘\0’
while(USART_GetFlagStatus(pUSARTx, USART_FLAG_TC) == RESET);
}
// 发送一个16位数据函数
// 函数参数:USARTx:串口号,ch:发送的16位数据
void USART_SendHalfWord(USART_TypeDef *pUSARTx, uint16_t ch)
{
uint8_t temp_h, temp_l; // 16位数据要分为高位和低位,两次发送
temp_h = (ch & 0xff00) >> 8; // 取高位
temp_l = ch & 0x00ff; // 取低位
USART_SendByte(pUSARTx, temp_h); // 发送高位
while(USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
USART_SendByte(pUSARTx, temp_l); // 发送低位
while(USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
}
// 重定向printf和scanf函数到串口
int USART_PutChar(int ch, FILE *f) // 函数参数:ch:要发送的字符,f:文件指针
{
USART_SendByte(USARTx, (uint8_t)ch); // 发送字符
while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);
return ch; // 返回发送的字符
}
int USART_GetChar(FILE *f) // 函数参数:f:文件指针
{
while(USART_GetFlagStatus(USARTx, USART_FLAG_RXNE) == RESET);
return (int)USART_ReceiveData(USARTx); // 接收字符
}
2.4 主函数
#include "usart.h"
#include "stm32f10x.h"
#include "stdio.h"
int main(void)
{
USART_Config();
USART_SendString(USARTx, (uint8_t*)"USART2 Test\r\n");
while(1)
{
}
}
其他串口也是一样,就是改一下头文件中的宏定义就行啦
3. 小结
理解了串口1的配置,这一章就轻而易举了,主要就是替换头文件配置,把其他串口配置也贴出来吧,自行体会其中差异:
// USARTx 引脚宏定义
#define USARTx_GPIO_CLK RCC_APB2Periph_GPIOB
#define USARTx_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd
// TX-发送数据输出引脚
#define USARTx_TX_GPIO_PORT GPIOB
#define USARTx_TX_GPIO_PIN GPIO_Pin_10
// RX-接收数据输入引脚
#define USARTx_RX_GPIO_PORT GPIOB
#define USARTx_RX_GPIO_PIN GPIO_Pin_11
// USARTx 相关参数宏定义
#define USARTx USART3
#define USARTx_CLK RCC_APB1Periph_USART3
#define USARTx_APBxCLKCmd RCC_APB1PeriphClockCmd
#define USARTx_BaudRate 115200
// NVIC配置
#define USARTx_IRQ USART3_IRQn
#define USARTx_IRQHandler USART3_IRQHandler
// USARTx 引脚宏定义
#define USARTx_GPIO_CLK RCC_APB2Periph_GPIOC
#define USARTx_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd
// TX-发送数据输出引脚
#define USARTx_TX_GPIO_PORT GPIOC
#define USARTx_TX_GPIO_PIN GPIO_Pin_10
// RX-接收数据输入引脚
#define USARTx_RX_GPIO_PORT GPIOC
#define USARTx_RX_GPIO_PIN GPIO_Pin_11
// USARTx 相关参数宏定义
#define USARTx UART4
#define USARTx_CLK RCC_APB1Periph_UART4
#define USARTx_APBxCLKCmd RCC_APB1PeriphClockCmd
#define USARTx_BaudRate 115200
// NVIC配置
#define USARTx_IRQ UART4_IRQn
#define USARTx_IRQHandler UART4_IRQHandler
// USARTx 引脚宏定义
#define USARTx_GPIO_CLK (RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD)
#define USARTx_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd
// TX-发送数据输出引脚
#define USARTx_TX_GPIO_PORT GPIOC
#define USARTx_TX_GPIO_PIN GPIO_Pin_12
// RX-接收数据输入引脚
#define USARTx_RX_GPIO_PORT GPIOD
#define USARTx_RX_GPIO_PIN GPIO_Pin_2
// USARTx 相关参数宏定义
#define USARTx UART5
#define USARTx_CLK RCC_APB1Periph_UART5
#define USARTx_APBxCLKCmd RCC_APB1PeriphClockCmd
#define USARTx_BaudRate 115200
// NVIC配置
#define USARTx_IRQ UART5_IRQn
#define USARTx_IRQHandler UART5_IRQHandler
2024.8.27 第一次修订,后期不再维护
2025.1.12 修补部分内容
本文作者:hazy1k
本文链接:https://www.cnblogs.com/hazy1k/p/18383592
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步