STM32F103标准库开发---Uart串口通信实验---初始化配置
2022-09-21 来源:csdn
一、Uart 串口通信
1. Uart 简介
UART 全称为Universal Asynchronous Receiver/Transmitter,即通用异步收发器 ,是一种通用串行数据总线,用于异步通信。
该总线双向通信,可以实现全双工数据发送和接收。
常用于单片机和电脑之间以及单片机和单片机之间的板级通信。
2. 接口连接方式
Uart 串口通信的数据由发送设备通过自身的TXD接口传输到接收设备的RXD接口,硬件连接比较简单,仅需要3条线。
具体连接图如下:
3. 传输方式
Uart 串口通信的数据由发送设备通过自身的TXD接口传输到接收设备的RXD接口, 一个字符一个字符地传输,每个字符一位一位地传输,并且传输一个字符时,总是以起始位开始,以停止位结束,字符之间没有固定的时间间隔要求。
实际传输时每一位的信号宽度与波特率有关,波特率越高,宽度越小,在进行传输之前,双方一定要使用同一个波特率设置。
波特率
波特率:每秒钟传输的数据位数(bit)。
波特率的单位是每秒比特数(bps),串口典型的传输波特率600bps,1200bps,2400bps,4800bps,9600bps,19200bps,57600bps,115200bps等。
以波特率9600bps为例:1秒钟传输9600位(bit)数据,所以传输1位(bit)数据需要1000000us/9600=104us。
字符帧格式
每个字符帧,包含起始位、数据位,校验位和停止位。
字符帧格式如下表:
具体如下图所示:
空闲位: 处于逻辑“1”状态,即高电平,每个字符之间都会有一段空闲位,表示当前线路上没有数据传输。
起始位: 处于逻辑”0”状态,即低电平,表示数据传输的开始。因为总线空闲时为高电平所以开始一次通信时先发送一个明显区别于空闲状态的信号,即低电平。
数据位: 起始位之后就是要传输需要传输的数据,数据可以是5,6,7,8,9位构成一个字符,一般都是8位。先发送最低位最后发送最高位,使用低电平表示0,高电平表示1,完成数据位的传输。
校验位: 数据位加上这一位后,使得“1”的位数应为偶数(偶校验)或奇数(奇校验),以此来校验数据传送的正确性。校验方法:奇校验(odd)、偶校验(even)以及无(noparity)。
停止位: 一个字符帧数据的结束标志,可以是1位、1.5位、2位的高电平,表示数据传输的结束。
二、Uart 初始化配置
1. 初始化配置具体步骤
使能USART时钟和GPIO时钟
TX 和 RX 引脚GPIO初始化配置
设置 RX 接收中断为中断源
配置中断优先级NVIC
USART 初始化设置
2. 初始化配置库函数
(1)使能USART时钟和GPIO时钟
APB2 外设时钟启用和禁用函数:
/**
*@功能:启用和禁用APB2外设时钟
*@参数1:指定外围设备
*@参数2:指定外围设备状态
*@返回值:无
*/
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
APB2外设如下:
#define RCC_APB2Periph_AFIO ((uint32_t)0x00000001)
#define RCC_APB2Periph_GPIOA ((uint32_t)0x00000004)
#define RCC_APB2Periph_GPIOB ((uint32_t)0x00000008)
#define RCC_APB2Periph_GPIOC ((uint32_t)0x00000010)
#define RCC_APB2Periph_GPIOD ((uint32_t)0x00000020)
#define RCC_APB2Periph_GPIOE ((uint32_t)0x00000040)
#define RCC_APB2Periph_GPIOF ((uint32_t)0x00000080)
#define RCC_APB2Periph_GPIOG ((uint32_t)0x00000100)
#define RCC_APB2Periph_ADC1 ((uint32_t)0x00000200)
#define RCC_APB2Periph_ADC2 ((uint32_t)0x00000400)
#define RCC_APB2Periph_TIM1 ((uint32_t)0x00000800)
#define RCC_APB2Periph_SPI1 ((uint32_t)0x00001000)
#define RCC_APB2Periph_TIM8 ((uint32_t)0x00002000)
#define RCC_APB2Periph_USART1 ((uint32_t)0x00004000)
#define RCC_APB2Periph_ADC3 ((uint32_t)0x00008000)
#define RCC_APB2Periph_TIM15 ((uint32_t)0x00010000)
#define RCC_APB2Periph_TIM16 ((uint32_t)0x00020000)
#define RCC_APB2Periph_TIM17 ((uint32_t)0x00040000)
#define RCC_APB2Periph_TIM9 ((uint32_t)0x00080000)
#define RCC_APB2Periph_TIM10 ((uint32_t)0x00100000)
#define RCC_APB2Periph_TIM11 ((uint32_t)0x00200000)
本次配置如下:
//使能USART1,GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);
(2)TX 和 RX 引脚 GPIO 初始化配置
GPIO初始化函数如下:
/**
*@功能:初始化GPIO外设
*@参数1:指定GPIO外设(GPIOA~GPIOG)
*@参数2:指定GPIO外设的配置信息
*@返回值:无
*/
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
GPIO初始化配置信息如下:
GPIO_InitTypeDef----GPIO初始化配置信息:
typedef struct
{
uint16_t GPIO_Pin; //指定要配置的GPIO引脚
GPIOSpeed_TypeDef GPIO_Speed; //指定所选引脚的速度
GPIOMode_TypeDef GPIO_Mode; //指定所选引脚的工作模式
}GPIO_InitTypeDef;
GPIO_Pin----指定要配置的GPIO引脚:
#define GPIO_Pin_0 ((uint16_t)0x0001) /*!< Pin 0 selected */
#define GPIO_Pin_1 ((uint16_t)0x0002) /*!< Pin 1 selected */
#define GPIO_Pin_2 ((uint16_t)0x0004) /*!< Pin 2 selected */
#define GPIO_Pin_3 ((uint16_t)0x0008) /*!< Pin 3 selected */
#define GPIO_Pin_4 ((uint16_t)0x0010) /*!< Pin 4 selected */
#define GPIO_Pin_5 ((uint16_t)0x0020) /*!< Pin 5 selected */
#define GPIO_Pin_6 ((uint16_t)0x0040) /*!< Pin 6 selected */
#define GPIO_Pin_7 ((uint16_t)0x0080) /*!< Pin 7 selected */
#define GPIO_Pin_8 ((uint16_t)0x0100) /*!< Pin 8 selected */
#define GPIO_Pin_9 ((uint16_t)0x0200) /*!< Pin 9 selected */
#define GPIO_Pin_10 ((uint16_t)0x0400) /*!< Pin 10 selected */
#define GPIO_Pin_11 ((uint16_t)0x0800) /*!< Pin 11 selected */
#define GPIO_Pin_12 ((uint16_t)0x1000) /*!< Pin 12 selected */
#define GPIO_Pin_13 ((uint16_t)0x2000) /*!< Pin 13 selected */
#define GPIO_Pin_14 ((uint16_t)0x4000) /*!< Pin 14 selected */
#define GPIO_Pin_15 ((uint16_t)0x8000) /*!< Pin 15 selected */
#define GPIO_Pin_All ((uint16_t)0xFFFF) /*!< All pins selected */
GPIO_Speed----指定所选引脚的速度:
typedef enum
{
GPIO_Speed_10MHz = 1,
GPIO_Speed_2MHz,
GPIO_Speed_50MHz
}GPIOSpeed_TypeDef;
GPIO_Mode----指定所选引脚的工作模式:
typedef enum
{
GPIO_Mode_AIN = 0x0, //模拟输入模式
GPIO_Mode_IN_FLOATING = 0x04, //浮空输入模式
GPIO_Mode_IPD = 0x28, //下拉输入模式
GPIO_Mode_IPU = 0x48, //上拉输入模式
GPIO_Mode_Out_OD = 0x14, //开漏输出模式
GPIO_Mode_Out_PP = 0x10, //推挽输出模式
GPIO_Mode_AF_OD = 0x1C, //复用开漏输出模式
GPIO_Mode_AF_PP = 0x18 //复用推挽输出模式
}GPIOMode_TypeDef;
由STM32F103系列参考手册可知以下USART引脚GPIO配置信息:
本次配置如下:
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
//USART1_TX PA9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA9
//USART1_RX PA10
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA10
(3)设置 RX 接收中断为中断源
USART 中断启用函数如下:
/**
*@功能:启用或禁用指定的USART中断
*@参数1:指定USART外设(USART1,USART2,USART3,USART4,USART5)
*@参数2:指定USART中断源
*@参数3:指定USART中断源状态(ENABLE 或 DISABLE)
*@返回值:无
*/
void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState);
USART中断源定义:
#define USART_IT_PE ((uint16_t)0x0028)
#define USART_IT_TXE ((uint16_t)0x0727)
#define USART_IT_TC ((uint16_t)0x0626)
#define USART_IT_RXNE ((uint16_t)0x0525)
#define USART_IT_ORE_RX ((uint16_t)0x0325) /* In case interrupt is generated if the RXNEIE bit is set */
#define USART_IT_IDLE ((uint16_t)0x0424)
#define USART_IT_LBD ((uint16_t)0x0846)
#define USART_IT_CTS ((uint16_t)0x096A)
#define USART_IT_ERR ((uint16_t)0x0060)
#define USART_IT_ORE_ER ((uint16_t)0x0360) /* In case interrupt is generated if the EIE bit is set */
#define USART_IT_NE ((uint16_t)0x0260)
#define USART_IT_FE ((uint16_t)0x0160)
本次配置如下:
//USART1 中断配置
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启串口接受中断
(4)串口接收 RX 中断优先级配置 NVIC
中断优先级NVIC初始化配置函数:
/**
*@功能:初始化NVIC外设
*@参数:指定NVIC外设的配置信息
*@返回值:无
*/
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
中断优先级NVIC初始化配置信息如下:
typedef struct
{
uint8_t NVIC_IRQChannel; //指定中断IRQ通道
uint8_t NVIC_IRQChannelPreemptionPriority; //指定优先级:0~15
uint8_t NVIC_IRQChannelSubPriority; //指定子优先级:0~15
FunctionalState NVIC_IRQChannelCmd; //指定IRQ通道使能和禁用
} NVIC_InitTypeDef;
本次配置如下:
//Usart1 NVIC 配置
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //指定USART1中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;//抢占优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子优先级0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
(4)USART 初始化设置
USART 初始化函数如下:
/**
*@功能:初始化USART外设
*@参数1:指定USART外设(USART1,USART2,USART3,USART4,USART5)
*@参数2:指定USART外设的配置信息
*@返回值:无
*/
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);
USART 初始化配置信息如下:
typedef struct
{
uint32_t USART_BaudRate; //配置USART通信波特率
uint16_t USART_WordLength; //指定数据位位数
uint16_t USART_StopBits; //指定停止位位数
uint16_t USART_Parity; //指定奇偶校验模式
uint16_t USART_Mode; //启用和禁用接收模式和发送模式
uint16_t USART_HardwareFlowControl; //是否开启硬件数据流控制
} USART_InitTypeDef;
USART_BaudRate----配置USART通信波特率:600bps,1200bps,2400bps,4800bps,9600bps,19200bps,57600bps,115200bps等。
USART_WordLength ----指定数据位位数:
#define USART_WordLength_8b ((uint16_t)0x0000) //8位
#define USART_WordLength_9b ((uint16_t)0x1000) //9位
USART_StopBits----指定停止位位数
#define USART_StopBits_1 ((uint16_t)0x0000)
#define USART_StopBits_0_5 ((uint16_t)0x1000)
#define USART_StopBits_2 ((uint16_t)0x2000)
#define USART_StopBits_1_5 ((uint16_t)0x3000)
USART_Parity----指定奇偶校验模式
#define USART_Parity_No ((uint16_t)0x0000) //无校验
#define USART_Parity_Even ((uint16_t)0x0400) //偶校验
#define USART_Parity_Odd ((uint16_t)0x0600) //奇校验
USART_Mode----启用和禁用接收模式和发送模式
#define USART_Mode_Rx ((uint16_t)0x0004) //接收模式
#define USART_Mode_Tx ((uint16_t)0x0008) //发送模式
USART_HardwareFlowControl----是否开启硬件数据流控制
#define USART_HardwareFlowControl_None ((uint16_t)0x0000)
#define USART_HardwareFlowControl_RTS ((uint16_t)0x0100)
#define USART_HardwareFlowControl_CTS ((uint16_t)0x0200)
#define USART_HardwareFlowControl_RTS_CTS ((uint16_t)0x0300)
USART 外设启用函数如下:
/**
*@功能:初始化USART外设
*@参数1:指定USART外设(USART1,USART2,USART3,USART4,USART5)
*@参数2:指定USART外设的配置信息
*@返回值:无
*/
void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState);
本次配置如下:
//USART 初始化设置
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 57600; //串口波特率
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); //初始化串口1
USART_Cmd(USART1, ENABLE); //使能串口1
3. 初始化配置具体程序源码
/**
#物理层:
UART1接口,波特率:57600bps,8位数据位,1位停止位,无奇偶校验
**/
/**
* @功能:串口1初始化函数
* @返回值:无
*/
void Uart1_init(void)
{
//使能时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
//USART1_TX PA9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA9
//USART1_RX PA10初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA10
//USART1 中断配置
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //配置接收为中断源
//USART1 NVIC配置
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //串口1中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;//抢占优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子优先级0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
//USART 初始化设置
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 57600; //串口波特率
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); //初始化串口1
USART_Cmd(USART1, ENABLE); //使能串口1
}