STM32的串口(USART/UART)通信是通过微控制器内的串行通信接口实现的。以下是STM32串口通信的基本原理和工作流程:
串口的基本概念:
串口(Serial Port)是一种逐位发送和接收数据的通信方式。USART(Universal Synchronous/Asynchronous Receiver/Transmitter)和UART(Universal Asynchronous Receiver/Transmitter)是两种常见的串口通信协议。USART可以支持同步和异步通信,而UART仅支持异步通信。
老师的代码修改下就可用。
代码:
main.c:
#include "stm32f10x.h"
#include "bsp/usart/bsp_usartx.h"
uint8_t Rxflag=0;
uint8_t ucTemp;
uint8_t ucaRxBuf[256];
uint16_t usRxCount;
int main(void)
{
USARTx_Init();
Usart_SendString("这是一个串口中断接收回显实验\n");
Usart_SendString("输入数据并以回车键结束\n");
usRxCount = 0;
while (1)
{
if(Rxflag)
{
if (usRxCount < sizeof(ucaRxBuf))
{
ucaRxBuf[usRxCount++] = ucTemp;
}
else
{
usRxCount = 0;
}
if (ucTemp == 0x0A)
{
Usart_SendStr_length(ucaRxBuf, usRxCount);
usRxCount = 0;
}
Rxflag = 0;
}
}
}
void USARTx_IRQHANDLER(void)
{
if(USART_GetITStatus(USARTx, USART_IT_RXNE) != RESET)
{
Rxflag = 1;
ucTemp = USART_ReceiveData(USARTx);
}
}
bsp_usartx.c:
#include "bsp/usart/bsp_usartx.h"
// 配置NVIC,设定USART接收中断优先级
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); // 设置优先级分组
NVIC_InitStructure.NVIC_IRQChannel = USARTx_IRQn; // 设置USART中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 抢断优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 子优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 使能中断
NVIC_Init(&NVIC_InitStructure); // 初始化NVIC
}
// 配置USART参数并初始化
void USARTx_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_Configuration(); // 配置NVIC
// 使能USART和GPIO时钟
USARTx_ClockCmd(USARTx_CLK, ENABLE);
USARTx_GPIO_ClockCmd(USARTx_TX_CLK | USARTx_RX_CLK | RCC_APB2Periph_AFIO, ENABLE);
// 初始化USART发送引脚
GPIO_InitStructure.GPIO_Pin = USARTx_TX_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(USARTx_TX_PORT, &GPIO_InitStructure);
// 初始化USART接收引脚
GPIO_InitStructure.GPIO_Pin = USARTx_RX_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 浮空输入
GPIO_Init(USARTx_RX_PORT, &GPIO_InitStructure);
// 初始化USART参数
USART_InitStructure.USART_BaudRate = USARTx_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_Rx | USART_Mode_Tx;
USART_Init(USARTx, &USART_InitStructure);
USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE); // 使能接收中断
USART_Cmd(USARTx, ENABLE); // 使能USART
USART_ClearFlag(USARTx, USART_FLAG_TC | USART_FLAG_TXE | USART_FLAG_RXNE); // 清除标志位
}
// 通过USART发送一个字节数据
void Usart_SendByte(uint8_t ch)
{
USART_SendData(USARTx, ch); // 发送数据
while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET); // 等待发送完成
}
// 通过USART发送指定长度的字符串
void Usart_SendStr_length(uint8_t *str, uint32_t strlen)
{
unsigned int k = 0;
do
{
Usart_SendByte(*(str + k)); // 逐字节发送数据
k++;
} while(k < strlen);
}
// 通过USART发送字符串,直到遇到字符串结束符
void Usart_SendString(uint8_t *str)
{
unsigned int k = 0;
do
{
Usart_SendByte(*(str + k)); // 逐字节发送数据
k++;
} while(*(str + k) != '\0'); // 直到遇到结束符
}
bsp_usartx.h:
#ifndef __BSP_USARTX_H
#define __BSP_USARTX_H
#include "stm32f10x.h"
// USARTx配置相关宏定义
#define USARTx USART1
#define USARTx_CLK RCC_APB2Periph_USART1
#define USARTx_IRQn USART1_IRQn
#define USARTx_IRQHandler USART1_IRQHandler
#define USARTx_TX_PIN GPIO_Pin_9
#define USARTx_TX_PORT GPIOA
#define USARTx_TX_CLK RCC_APB2Periph_GPIOA
#define USARTx_RX_PIN GPIO_Pin_10
#define USARTx_RX_PORT GPIOA
#define USARTx_RX_CLK RCC_APB2Periph_GPIOA
#define USARTx_BAUDRATE 115200
// 函数原型声明
void NVIC_Configuration(void);
void USARTx_Init(void);
void Usart_SendByte(uint8_t ch);
void Usart_SendStr_length(uint8_t *str, uint32_t strlen);
void Usart_SendString(uint8_t *str);
#endif /* __BSP_USARTX_H */
演示视频:
stm32串口接发