0
点赞
收藏
分享

微信扫一扫

串口通信相关理论知识

UART和USART

UART:universal asynchronous receiver and transmitter 通用异步收发器

USART:universal synchronous asynchronous receiver and transmitter 通用同步和异步收发器

UART:一般只能用于异步串行通信。

USART:既可以用于同步串行通讯,也能用于异步串行通讯。

通信方式

  • 串行通信:
  • 传输原理:数据按位顺序传输
  • 优点:占用引脚资源少
  • 缺点:速度相对较慢
  • 并行通信:
  • 传输原理:数据各个为同时传输
  • 优点:速度快
  • 缺点:占用引脚资源多

传送模式

  • 单工模式
  • 半双工模式
  • 全工模式

同步和异步

  • 同步:发送方发出数据后,等接收方回响应以后才发下一个数据包的通讯方式
  • 异步:发送方发出数据后,不等接收方回响应,接着发送下个数据包的通讯方式

同步是阻塞模式,异步是非阻塞模式

通信标准

通信方式

通信方向

UART

异步通信

全双工

SPI

同步通信

全双工

I2C

同步通信

半双工

开发板的串口资源

引脚编号

引脚名称

默认复用功能

12

PA2

USART2_TX

13

PA3

USART2_RX

21

PB10

USART3_TX

22

PB11

USART3_RX

30

PA9

USART1_TX

31

PA10

USART1_RX

串口1用于下载程序,串口2用于与WIFI等的连接。

外设GPIO的USART配置

串口通信相关理论知识_数据寄存器

串口通信的配置流程

  1. 串口、GPIO时钟使能

RCC_APB2PeriphClockCmd();

  1. GPIO端口模式设置

CPIO_Init();

  1. 串口参数初始化

USART_Init();

  1. 开启中断并且初始化NVIC

NVIC_Init();
USART_ITConfig();

  1. 使能串口

USART_Cmd();

  1. 编写中断处理函数

USARTx_IRQHandler();

串口数据收发:

void USART_SendData();
uint16_t USART_ReceiveData();

串口传输状态:

//得到标志位状态
//参数:哪个串口,变量
//返回标志位的状态:0或1
FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
//清除标志位
void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG);

//获取中断的状态,判断中断是否打开
ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT);
//清除与中断相关的标志位
void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT);

  1. 不论接收还是发送,都是通过两个寄存器(发送数据寄存器TDR、接收数据寄存器RDR)
  2. 接受和发送使用的都是同个寄存器(数据寄存器DR)
  3. 整个过程是由CPU或者DMA处理

相关寄存器

状态寄存器(USART_SR)

串口通信相关理论知识_串口_02

串口通信相关理论知识_数据_03

串口通信相关理论知识_UART_04

TXE:发送数据寄存器空(Transmit data register empty),与发送数据寄存器相关

TC:发送完成(Transmission complete),与发送移位寄存器相关

RXNE:读数据寄存器非空(Read data register not empty)

TEX和TC的复位值为1,RXNE的复位值为0!

小实验

单片机通过串口1发送一个字符到电脑上

//my_usart1.h

#define USART1_GPIO_PIN_TX GPIO_Pin_9
#define USART1_GPIO_PIN_RX GPIO_Pin_10
#define USART1_GPIO_PORT GPIOA

void My_USART1(void);

void My_USART1(void){
GPIO_InitTypeDef GPIO_InitStruct;
USART_InitTypeDef USART1_InitStrue;

//1. 串口、GPIO时钟使能
RCC_APB2PeriphClockCmd(RCC_APB1Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);

//2.GPIO端口模式设置
GPIO_InitStructure.GPIO_Pin = USART1_GPIO_PIN_TX;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Pin = USART1_GPIO_PIN_RX;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

//3. 串口参数初始化
USART1_InitStrue.USART_BaudRate = 9600; //波特率
USART1_InitStrue.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //硬件流动控制,一般选择无
USART1_InitStrue.USART_Mode = USART_Mode_Rx|USART_Mode_Tx; //模式
USART1_InitStrue.USART_Parity = USART_Parity_No; //
USART1_InitStrue.USART_StopBits = 8; //发送位数
USART1_InitStrue.USART_WordLength = USART_WordLength_8b; //长度
USART_Init(USART1,&USART1_InitStrue);

//4. 开启中断并且初始化NVIC
//本次没有使用中断,暂时不需要

//5. 使能串口
USART_Cmd(USART1,ENABLE);

//6. 编写中断处理函数
//本次没有使用中断,暂时不需要
}

在主函数中调用

int main(void){
My_USART1();
USART_SendData(USART1,'H');

while(1){}
}

举报

相关推荐

0 条评论