串口通信
处理器与外部设备通信有哪几种方式?
串口配置过程是怎样的?
回帖(1)
2022-2-28 14:49:59
正篇
1.处理器与外部设备通信的两种方式:
并行通信:
-传输原理:数据的各个位同时传输
-优点:速度快
-缺点:占用引脚资源多
串行通信:
-传输原理:一位一位地传输数据
-优点:占用资源较少
-缺点:速度慢
串口通信按照传输的方向可以分为:单工,半双工和全双工。
单工:只能一个方向上进行传输
半双工:允许双向通信,但是同一时间只能是单一方向传输。(类似于两个时间切换方向的单工)
全双工:允许同时间的双向通信。
串口的通信方式可分为:同步和异步通信。
同步通信:带有时钟线的通信方式。
异步通信:不带有时钟线的通信方式。
STM32F103系列单片机共有5个串口,其中1-3是 通用同步/异步串行接口 USART,4、5是 通用异步 串行接口 UART。
(图片来源正点原子B站教程)
(图片来源正点原子B站教程)
对于传输的数据,我们需要一些参数。
1.起始位 2. 数据位(可设置8位或者9位) 3.奇偶校验位 4.停止位 5.波特率(因为是异步通信所以要提前设置好波特率,同样对于通信的对象,也要提前设置好波特率并且要和单片机的波特率相同才能正常通信)
最重要的就是波特率的设置,能够成功通信的前提就是有合适统一的波特率。
波特率的计算公式:
(波特率的产生原理与相关寄存器配置相当麻烦,这里不再说明。只要掌握计算与相应库函数参数配置就可以。)
串口配置过程
了解了串口通信的一些基础知识之后,就要掌握STM32的串口配置过程。前面省略了一些相关寄存器说明,这里会简要说明一下。
我们通过库函数主要配置以下几个寄存器:
状态寄存器(USART_SR)
数据寄存器(USART_DR)
波特比率寄存器(USART_BRR)
控制寄存器 x(USART_CRx)
(具体功能不再细说。)
配置步骤:
串口设置的一般步骤可以总结为如下几个步骤:
- 串口时钟使能,GPIO 时钟使能 RCC_APB2PeriphClockCmd()
- 串口复位 (这一步不是必须)void USART_DeInit();
- GPIO 端口模式设置 GPIO_Init(); GPIO_Mode 设置为复用推挽输出
- 串口参数初始化
{
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);
USART_InitStructure.USART_BaudRate = bound; //波特率设置;
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(USART1, &USART_InitStructure); //初始化串口
}
- 开启中断并且初始化 NVIC(如果需要开启中断才需要这个步骤)
- 使能串口 USART_Cmd();
- 编写中断处理函数 void USART1_IRQHandler()可以在“stm32f0x.h”这个头文件找到。
串口数据的接收和发送:从DR寄存器里读取和写入数据。
uint16_t USART_ReceiveData(USART_TypeDef* USARTx);
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
#include "stm32f10x.h"
void Usart1_Init()
{
//GPIO口初始化参数结构体
GPIO_InitTypeDef GPIO_InitStructure;
// 串口初始化参数结构体
USART_InitTypeDef USART_InitStructure;
//中断初始化参数结构体
NVIC_InitTypeDef NVIC_InitStructure;
//使能GPIOA
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//使能USART 1
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
//设置GPIOA9 为 复用推挽输出 速度为10MHz(PA9 复用为串口发送引脚)
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
//初始化GPIOA9
GPIO_Init(GPIOA, &GPIO_InitStructure);
//设置GPIO10 为 浮空输出 速度为10MHz(PA10 复用为串口接收引脚)
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
//初始化GPIOA10
GPIO_Init(GPIOA, &GPIO_InitStructure);
//串口初始化参数
//设置波特率为115200
USART_InitStructure.USART_BaudRate = 115200;
//不启用硬件流控制
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
//设置为串口收发模式
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
//无奇偶校检位
USART_InitStructure.USART_Parity = USART_Parity_No;
//一个停止位
USART_InitStructure.USART_StopBits = USART_StopBits_1;
//设置数据帧长为 8位
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
//初始化串口
USART_Init(USART1, &USART_InitStructure);
//使能串口
USART_Cmd(USART1, ENABLE);
//开启串口接收中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
//串口1通道
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
//使能中断
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//设置抢占优先级
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
//设置响应优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
//初始化中断优先级
NVIC_Init(&NVIC_InitStructure);
}
/*串口接收中断服务函数*/
void USART1_IRQHandler()
{
//定义接收数据变量
unsigned char res;
//判断串口接收中断是否发生
if(USART_GetITStatus(USART1, USART_IT_RXNE))
{
//接收数据
res = USART_ReceiveData(USART1);
//发送刚接收的数据
USART_SendData(USART1, res);
}
}
int main()
{
//串口初始化
Usart1_Init();
//中断分组
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
while(1);
}
结语:
简单的串口知识与配置已经记录完了,后续可能会有深度详细的补充。
若有错误,还请评论指出。
共同进步。
正篇
1.处理器与外部设备通信的两种方式:
并行通信:
-传输原理:数据的各个位同时传输
-优点:速度快
-缺点:占用引脚资源多
串行通信:
-传输原理:一位一位地传输数据
-优点:占用资源较少
-缺点:速度慢
串口通信按照传输的方向可以分为:单工,半双工和全双工。
单工:只能一个方向上进行传输
半双工:允许双向通信,但是同一时间只能是单一方向传输。(类似于两个时间切换方向的单工)
全双工:允许同时间的双向通信。
串口的通信方式可分为:同步和异步通信。
同步通信:带有时钟线的通信方式。
异步通信:不带有时钟线的通信方式。
STM32F103系列单片机共有5个串口,其中1-3是 通用同步/异步串行接口 USART,4、5是 通用异步 串行接口 UART。
(图片来源正点原子B站教程)
(图片来源正点原子B站教程)
对于传输的数据,我们需要一些参数。
1.起始位 2. 数据位(可设置8位或者9位) 3.奇偶校验位 4.停止位 5.波特率(因为是异步通信所以要提前设置好波特率,同样对于通信的对象,也要提前设置好波特率并且要和单片机的波特率相同才能正常通信)
最重要的就是波特率的设置,能够成功通信的前提就是有合适统一的波特率。
波特率的计算公式:
(波特率的产生原理与相关寄存器配置相当麻烦,这里不再说明。只要掌握计算与相应库函数参数配置就可以。)
串口配置过程
了解了串口通信的一些基础知识之后,就要掌握STM32的串口配置过程。前面省略了一些相关寄存器说明,这里会简要说明一下。
我们通过库函数主要配置以下几个寄存器:
状态寄存器(USART_SR)
数据寄存器(USART_DR)
波特比率寄存器(USART_BRR)
控制寄存器 x(USART_CRx)
(具体功能不再细说。)
配置步骤:
串口设置的一般步骤可以总结为如下几个步骤:
- 串口时钟使能,GPIO 时钟使能 RCC_APB2PeriphClockCmd()
- 串口复位 (这一步不是必须)void USART_DeInit();
- GPIO 端口模式设置 GPIO_Init(); GPIO_Mode 设置为复用推挽输出
- 串口参数初始化
{
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);
USART_InitStructure.USART_BaudRate = bound; //波特率设置;
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(USART1, &USART_InitStructure); //初始化串口
}
- 开启中断并且初始化 NVIC(如果需要开启中断才需要这个步骤)
- 使能串口 USART_Cmd();
- 编写中断处理函数 void USART1_IRQHandler()可以在“stm32f0x.h”这个头文件找到。
串口数据的接收和发送:从DR寄存器里读取和写入数据。
uint16_t USART_ReceiveData(USART_TypeDef* USARTx);
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
#include "stm32f10x.h"
void Usart1_Init()
{
//GPIO口初始化参数结构体
GPIO_InitTypeDef GPIO_InitStructure;
// 串口初始化参数结构体
USART_InitTypeDef USART_InitStructure;
//中断初始化参数结构体
NVIC_InitTypeDef NVIC_InitStructure;
//使能GPIOA
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//使能USART 1
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
//设置GPIOA9 为 复用推挽输出 速度为10MHz(PA9 复用为串口发送引脚)
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
//初始化GPIOA9
GPIO_Init(GPIOA, &GPIO_InitStructure);
//设置GPIO10 为 浮空输出 速度为10MHz(PA10 复用为串口接收引脚)
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
//初始化GPIOA10
GPIO_Init(GPIOA, &GPIO_InitStructure);
//串口初始化参数
//设置波特率为115200
USART_InitStructure.USART_BaudRate = 115200;
//不启用硬件流控制
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
//设置为串口收发模式
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
//无奇偶校检位
USART_InitStructure.USART_Parity = USART_Parity_No;
//一个停止位
USART_InitStructure.USART_StopBits = USART_StopBits_1;
//设置数据帧长为 8位
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
//初始化串口
USART_Init(USART1, &USART_InitStructure);
//使能串口
USART_Cmd(USART1, ENABLE);
//开启串口接收中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
//串口1通道
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
//使能中断
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//设置抢占优先级
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
//设置响应优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
//初始化中断优先级
NVIC_Init(&NVIC_InitStructure);
}
/*串口接收中断服务函数*/
void USART1_IRQHandler()
{
//定义接收数据变量
unsigned char res;
//判断串口接收中断是否发生
if(USART_GetITStatus(USART1, USART_IT_RXNE))
{
//接收数据
res = USART_ReceiveData(USART1);
//发送刚接收的数据
USART_SendData(USART1, res);
}
}
int main()
{
//串口初始化
Usart1_Init();
//中断分组
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
while(1);
}
结语:
简单的串口知识与配置已经记录完了,后续可能会有深度详细的补充。
若有错误,还请评论指出。
共同进步。
举报
更多回帖