2021-06-17 STM32F103 USART串口代码 使用固件库

本文展示了STM32 USART串口的 识别操作
内容涉及 :
USART串口的识别
IO口输入输出
按键的外部中断处理
32位数据通讯,字符串通讯,单字符通讯


完整代码 GIT完整代码


前言

STM32 的 USART 简介 通用同步异步收发器(Universal Synchronous Asynchronous Receiver and Transmitter)是一 个串行通信设备,可以灵活地与外部设备进行全双工数据交换。有别于 USART 还有一个 UART(Universal Asynchronous Receiver and Transmitter),它是在 USART 基础上裁剪掉了同 步通信功能,只有异步通信。简单区分同步和异步就是看通信时需不需要对外提供时钟输 出,我们平时用的串口通信基本都是 UART。

Git 代码

一、 编程要点

USART:
1) 使能 RX 和 TX 引脚 GPIO 时钟和 USART 时钟;
2) 初始化 GPIO,并将 GPIO 复用到 USART 上;
3) 配置 USART 参数;
4) 配置中断控制器并使能 USART 接收中断;
5) 使能 USART;
6) 在 USART 接收中断服务函数实现数据接收和发送。

二、使用步骤

1.理解原理图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码如下:
: STM32F103ZET6 串口引脚位PA9
: STM32F103ZET6 输出口为PB5低电平点有效
: STM32F103ZET6 Key检测脚为PA8

2.建立USART串口的 头文件 USART_book.h

代码如下(示例):

#ifndef  __USART_BOOK_H_
#define  __USART_BOOK_H_

#include "stm32f10x.h"
#include "stm32f10x_usart.h"
#include "stm32f10x_rcc.h"
 //串口的宏定义  不同的串口挂在的总线和IO不一样
 
 //串口1
#define  _DEBUG_USARTx                  USART1
#define  _DEBUG_USART_CLK               RCC_APB2Periph_USART1
#define  _DEBUG_USART_APBxClkCmd        RCC_APB2PeriphClockCmd
#define  _DEBUG_USART_BAUDRATE          115200
 
// USART  GPIO 引脚定义
#define  _DEBUG_USART_GPIO_CLK          RCC_APB2Periph_GPIOA
#define  _DEBUG_USART_GPIO_APBxCLKCmd   RCC_APB2PeriphClockCmd

#define  _DEBUG_USART_TX_GPIO_PORT      GPIOA
#define  _DEBUG_USART_TX_GPIO_PIN       GPIO_Pin_9
#define  _DEBUG_USART_TX_GPIO_MODE      GPIO_Mode_AF_PP
#define  _DEBUG_USART_RX_GPIO_PORT      GPIOA
#define  _DEBUG_USART_RX_GPIO_PIN       GPIO_Pin_10
#define  _DEBUG_USART_RX_GPIO_MODE      GPIO_Mode_IN_FLOATING

#define  _DEBUG_NVIC_USART_IRQ          USART1_IRQn
#define  _DRBUG_USART_IRQHandler        USART1_IRQHandler
 
void  fn_USART_IO_Config(void);
void  fn_USART_Config(void); 

void fn_Usart_Send_Byte(USART_TypeDef * pUSARTx , uint8_t ch );
void fn_Usart_SendString(USART_TypeDef *pUSARTx , char * str);
void Usart_SendHalf_32_Word( USART_TypeDef * pUSARTx, uint32_t ch);
void _DRBUG_USART_IRQHandler(void);
#endif

3.建立USART串口的 头文件 USART_book.c

代码如下(示例):

#include "USART_book.h"


/**************************************************************
* @brief  
* void fn_LED_Corporate(GPIO_TypeDef*  _GPIO_x , uint16_t  _GPIO_Pin_x , 
*            LED_Corporate_state_t  _LED_Corporate_state_t );
* @param  
* //串口1
*    #define  _DEBUG_NVIC_USART_IRQ               USART1_IRQn
*    #define  _DRBUG_NVIC_USART_IRQHandler        USART1_IRQHandler
* @retval 
*************************************************************/ 
static void NVIC_Configuration(void){
    
    
  NVIC_InitTypeDef  NVIC_InitStructure;
  /* 嵌套向量中断控制寄存器组选择*/
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  
  /* 配置 USART 为中断源 */
  NVIC_InitStructure.NVIC_IRQChannel = _DEBUG_NVIC_USART_IRQ;
  /* 抢断优先级为 1 */
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  /* 子优先级为 1 */
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  /* 使能中断 */
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  /* 初始化配置 NVIC */
  NVIC_Init(&NVIC_InitStructure);
}

/**************************************************************
* @brief  
* void fn_LED_Corporate(GPIO_TypeDef*  _GPIO_x , uint16_t  _GPIO_Pin_x , 
*            LED_Corporate_state_t  _LED_Corporate_state_t );
* @param  
* //串口1    
*    // USART  GPIO 引脚定义
*    #define  _DEBUG_USART_GPIO_CLK          RCC_APB2Periph_GPIOA
*    #define  _DEBUG_USART_GPIO_APBxCLKCmd   RCC_APB2PeriphClockCmd
*    
*    #define  _DEBUG_USART_TX_GPIO_PORT      GPIOA
*    #define  _DEBUG_USART_TX_GPIO_PIN       GPIO_Pin_9
*    #define  _DEBUG_USART_TX_GPIO_MODE      GPIO_Mode_AF_PP
*    #define  _DEBUG_USART_RX_GPIO_PORT      GPIOA
*    #define  _DEBUG_USART_RX_GPIO_PIN       GPIO_Pin_10
*    #define  _DEBUG_USART_RX_GPIO_MODE      GPIO_Mode_AF_FLOATING
* @retval 
*************************************************************/ 
void  fn_USART_IO_Config(void){
    
    
  GPIO_InitTypeDef    GPIO_InitStructure;
  // 打开串口 GPIO 的时钟
  _DEBUG_USART_GPIO_APBxCLKCmd(_DEBUG_USART_GPIO_CLK , ENABLE);
  
//将USART TX 的GPIO配置为推挽模式
  GPIO_InitStructure.GPIO_Pin = _DEBUG_USART_TX_GPIO_PIN;
  GPIO_InitStructure.GPIO_Mode = _DEBUG_USART_TX_GPIO_MODE;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(_DEBUG_USART_TX_GPIO_PORT,&GPIO_InitStructure);
   //将USART RX 的GPIO配置为浮空输入
  GPIO_InitStructure.GPIO_Pin = _DEBUG_USART_RX_GPIO_PIN;
  GPIO_InitStructure.GPIO_Mode = _DEBUG_USART_RX_GPIO_MODE;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(_DEBUG_USART_RX_GPIO_PORT,&GPIO_InitStructure);
}

/**************************************************************
* @brief  
* void fn_LED_Corporate(GPIO_TypeDef*  _GPIO_x , uint16_t  _GPIO_Pin_x , 
*            LED_Corporate_state_t  _LED_Corporate_state_t );
* @param  
* //串口1
*    #define  _DEBUG_USARTx                  USART1
*    #define  _DEBUG_USART_CLK               RCC_APB2Periph_USART1
*    #define  _DEBUG_USART_APBxClkCmd        RCC_APB2PeriphClockCmd
*    #define  _DEBUG_USART_BAUDRATE          115200
* @retval 
*************************************************************/ 
void  fn_USART_Config(void){
    
    
  USART_InitTypeDef   USART_InitStructure;
 
  // 打开串口外设的时钟
  _DEBUG_USART_APBxClkCmd(_DEBUG_USART_CLK , ENABLE);
  
  //配置串口的工作参数
  USART_InitStructure.USART_BaudRate = _DEBUG_USART_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(_DEBUG_USARTx , &USART_InitStructure);// 完成串口的初始化配置
  
  NVIC_Configuration();// 串口中断优先级配置
  
  USART_ITConfig(_DEBUG_USARTx , USART_IT_RXNE , ENABLE);// 使能串口接收中断
  
  USART_Cmd(_DEBUG_USARTx , ENABLE);// 使能串口
}

/**************************************************************
* @brief  
* void fn_Usart_Send_Byte(USART_TypeDef * pUSARTx , uint8_t ch );
* @param  
* //串口1
*    #define  _DEBUG_USARTx                  USART1
*    #define  _DEBUG_USART_CLK               RCC_APB2Periph_USART1
*    #define  _DEBUG_USART_APBxClkCmd        RCC_APB2PeriphClockCmd
*    #define  _DEBUG_USART_BAUDRATE          115200
* @retval 
*************************************************************/ 
void fn_Usart_Send_Byte(USART_TypeDef * pUSARTx , uint8_t ch ){
    
    
  /*发送一个字节数据到USART*/
  USART_SendData(pUSARTx , ch);
  /*等待发送数据寄存器为空*/
  while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TXE)==RESET);
}

/**************************************************************
* @brief  
* void fn_Usart_SendString(USART_TypeDef *pUSARTx , char * str);
* @param  
* //串口1
*    #define  _DEBUG_USARTx                  USART1
*    #define  _DEBUG_USART_CLK               RCC_APB2Periph_USART1
*    #define  _DEBUG_USART_APBxClkCmd        RCC_APB2PeriphClockCmd
*    #define  _DEBUG_USART_BAUDRATE          115200
* @retval 
*************************************************************/ 
void fn_Usart_SendString(USART_TypeDef *pUSARTx , char * str){
    
    
  unsigned int k = 0;
  do{
    
    
    fn_Usart_Send_Byte(pUSARTx,*(str + k++));
    
  }while(*(str + k)!='\0');
  
  /*等待发送完成*/
  while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC));
}

/**************************************************************
* @brief  
* void Usart_SendHalf_32_Word( USART_TypeDef * pUSARTx, uint32_t ch);
* @param  
* @retval 
*************************************************************/ 
void Usart_SendHalf_32_Word( USART_TypeDef * pUSARTx, uint32_t ch){
    
    
  uint32_t temp_Half32;
  uint8_t temp_Half=0,i_Half=4; 
  temp_Half32 =ch;
  while(i_Half-->0){
    
    
     temp_Half=(temp_Half32 & 0xFF000000)>>24;
     temp_Half32<<=8;
     fn_Usart_Send_Byte(pUSARTx,temp_Half);
  }
  /*等待发送完成*/
  while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC));
}

/**************************************************************
* @brief  
* void USART1_IRQHandler(void);
* @param  
* @retval 
*************************************************************/ 
void _DRBUG_USART_IRQHandler(void){
    
    
  uint8_t ucTemp =  0; 
  if(USART_GetITStatus(_DEBUG_USARTx,USART_IT_RXNE)!=RESET){
    
    
    ucTemp = USART_ReceiveData(_DEBUG_USARTx);
    USART_SendData(_DEBUG_USARTx ,ucTemp );
  }
}

4.利用之前的LED输出的 头文件 Led_book.h

代码如下(示例):

#ifndef  __LED_BOOK_H_
#define  __LED_BOOK_H_

#include "stm32f10x.h"
 

#define   LED_OUT_GPIO_Port     GPIOB                 //GPIO Point
#define   LED_OUT_GPIO_Clock    RCC_APB2Periph_GPIOB  //GPIO clock
#define   LED_OUT_GPIO_Pin      GPIO_Pin_5             
#define   LED_OUT_GPIO_Pin_Bit  5
#define   LED_OUT_GPIO_Modle    GPIO_Mode_Out_PP

typedef enum {
    
    
		LED_Corporate_On = 1,
		LED_Corporate_OFF = 2,
		LED_Corporate_Toggle = 3, 
} LED_Corporate_state_t;

void fn_LED_GPIO_Config(GPIO_TypeDef* _GPIO_x , uint32_t _GPIO_Clock ,\
          uint16_t _GPIO_Pin_x , GPIOMode_TypeDef _GPIOMode_TypeDef);
void fn_Led_Init(void);
void fn_LED_Corporate(GPIO_TypeDef* _GPIO_x , uint16_t _GPIO_Pin_x , \
          LED_Corporate_state_t _LED_Corporate_state_t );
  

#define __LED_Change__  fn_LED_Corporate(LED_OUT_GPIO_Port,LED_OUT_GPIO_Pin,LED_Corporate_Toggle)
#endif

5.利用之前的LED输出的 头文件 Led_book.c

代码如下(示例):

#include "Led_book.h"

/**************************************************************
* @brief  
* void fn_LED_GPIO_Config(GPIO_TypeDef* _GPIO_x , uint32_t _GPIO_Clock ,
*             uint16_t _GPIO_Pin_x , GPIOMode_TypeDef _GPIOMode_TypeDef);
* @param  
* @retval 
*************************************************************/ 
#define LED_GPIO_Speed GPIO_Speed_10MHz 
void fn_LED_GPIO_Config(GPIO_TypeDef* _GPIO_x , uint32_t _GPIO_Clock ,uint16_t _GPIO_Pin_x , GPIOMode_TypeDef _GPIOMode_TypeDef){
    
    
  GPIO_InitTypeDef  GPIO_InitStruct;
  GPIO_InitStruct.GPIO_Mode = _GPIOMode_TypeDef;
  GPIO_InitStruct.GPIO_Pin = _GPIO_Pin_x;
  GPIO_InitStruct.GPIO_Speed = LED_GPIO_Speed;
  RCC_APB2PeriphClockCmd(_GPIO_Clock ,ENABLE); 
  GPIO_Init(_GPIO_x , &GPIO_InitStruct) ; 
  GPIO_SetBits(_GPIO_x,_GPIO_Pin_x);
}

/**************************************************************
* @brief  
* void fn_Led_Init(void);
* @param  
* @retval 
*************************************************************/ 
void fn_Led_Init(void){
    
    
  fn_LED_GPIO_Config (LED_OUT_GPIO_Port,LED_OUT_GPIO_Clock,LED_OUT_GPIO_Pin,LED_OUT_GPIO_Modle);
}

/**************************************************************
* @brief  
* void fn_LED_Corporate(GPIO_TypeDef*  _GPIO_x , uint16_t  _GPIO_Pin_x , 
*            LED_Corporate_state_t  _LED_Corporate_state_t );
* @param  
* @retval 
*************************************************************/ 
void fn_LED_Corporate(GPIO_TypeDef*  _GPIO_x , uint16_t  _GPIO_Pin_x , LED_Corporate_state_t  _LED_Corporate_state_t ){
    
    
  switch(_LED_Corporate_state_t){
    
    
    case  LED_Corporate_On :
      GPIO_SetBits(_GPIO_x,_GPIO_Pin_x);
      break;
		case  LED_Corporate_OFF:
      GPIO_ResetBits(_GPIO_x,_GPIO_Pin_x);
      break;
		case  LED_Corporate_Toggle:
      GPIO_ReadOutputDataBit(_GPIO_x,_GPIO_Pin_x)?GPIO_ResetBits(_GPIO_x,_GPIO_Pin_x):GPIO_SetBits(_GPIO_x,_GPIO_Pin_x);
      break;    
  }
}


//practice
//fn_LED_GPIO_Config (LED_OUT_GPIO_Port,LED_OUT_GPIO_Clock,LED_OUT_GPIO_Pin,LED_OUT_GPIO_Modle);
// while(1){
    
    
//  delay(10000);
//  fn_LED_Corporate(LED_OUT_GPIO_Port,LED_OUT_GPIO_Pin,LED_Corporate_Toggle);		 
// }	 

6.建立USART 输出的 主程序 main.c

代码如下(示例):

/**
  ******************************************************************************
  * @file    GPIO/JTAG_Remap/main.c 
  * @author  MCD Application Team
  * @version V3.5.0
  * @date    08-April-2011
  * @brief   Main program body
  ******************************************************************************
  * @attention
  *
  * 
  ******************************************************************************
  */ 

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "PROJ_book.h" 

/* Private functions ---------------------------------------------------------*/

/**
  * @brief  Main program.
  * @param  None
  * @retval None
  */
void delay(int x);
void fn_LED_Flash_Init(void);
void fn_usart_show_Init(void);
int main(void)
{
    
     
      fn_Led_Init();
      fn_LED_Flash_Init();  
      fn_usart_show_Init();
      fn_EXTI_GPIO_Config();
      
      while(1){
    
            
        delay(10000);
        fn_Usart_SendString(_DEBUG_USARTx," : 你瞅啥 \n");
      }
}

void fn_LED_Flash_Init(void){
    
    
  uint16_t  count_Init = 2;
  while(count_Init-->0){
    
    
    __LED_Change__;
    fn_Systick_Delay(500,_Systick_ms);
    __LED_Change__;
    fn_Systick_Delay(100,_Systick_ms);
    __LED_Change__;
    fn_Systick_Delay(100,_Systick_ms);
    __LED_Change__;
    fn_Systick_Delay(500,_Systick_ms);
  } 
}

void fn_usart_show_Init(void){
    
    
  fn_USART_IO_Config();
  fn_USART_Config();
  fn_Usart_Send_Byte(_DEBUG_USARTx,'T');
  fn_Usart_Send_Byte(_DEBUG_USARTx,'O');
  Usart_SendHalf_32_Word(_DEBUG_USARTx,0xA69B4B7C);
  fn_Usart_SendString(_DEBUG_USARTx," : 你瞅啥 \n");
}

void delay(int x){
    
    
	int y = 0xFFFFF;
	while((x--)>0){
    
    
		while((y--)>0){
    
    
			__NOP();
			__NOP();
			__NOP();
			__NOP();
			__NOP();
		}
	}
}
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

www.firebbs.cn。


参考笔记。
_STM32f103 中断 以及 EXT

STM32 EXIT – LED 程序

STM32 EXIT – EXIT 程序

STM32 EXIT – Key 程序

STM32 RCC – 主程序

总结

USART 初始化结构体
1 typedef struct {
2 uint32_t USART_BaudRate; // 波特率
3 uint16_t USART_WordLength; // 字长
4 uint16_t USART_StopBits; // 停止位
5 uint16_t USART_Parity; // 校验位
6 uint16_t USART_Mode; // USART 模式
7 uint16_t USART_HardwareFlowControl; // 硬件流控制
8 } USART_InitTypeDef;
1) USART_BaudRate:波特率设置。一般设置为 2400、9600、19200、115200。标准
库函数会根据设定值计算得到 USARTDIV 值,从而设置 USART_BRR 寄存器值。
2) USART_WordLength:数据帧字长,可选 8 位或 9 位。它设定 USART_CR1 寄存
器的 M 位的值。如果没有使能奇偶校验控制,一般使用 8 数据位;如果使能了奇
偶校验则一般设置为 9 数据位。
3) USART_StopBits:停止位设置,可选 0.5 个、1 个、1.5 个和 2 个停止位,它设定
USART_CR2 寄存器的 STOP[1:0]位的值,一般我们选择 1 个停止位。
4) USART_Parity : 奇 偶 校 验 控 制 选 择 , 可 选 USART_Parity_No( 无校验 ) 、
USART_Parity_Even( 偶校验 ) 以 及 USART_Parity_Odd( 奇 校 验 ) , 它 设 定
USART_CR1 寄存器的 PCE 位和 PS 位的值。
5) USART_Mode:USART 模式选择,有 USART_Mode_Rx 和 USART_Mode_Tx,
允许使用逻辑或运算选择两个,它设定 USART_CR1 寄存器的 RE 位和 TE 位。
6) USART_HardwareFlowControl:硬件流控制选择,只有在硬件流控制模式才有效,
可选有⑴使能 RTS、⑵使能 CTS、⑶同时使能 RTS 和 CTS、⑷不使能硬件流。
当使用同步模式时需要配置 SCLK 引脚输出脉冲的属性,标准库使用一个时钟初始化
结构体 USART_ClockInitTypeDef 来设置,该结构体内容也只有在同步模式才需要设置。
USART 时钟初始化结构体
1 typedef struct {
2 uint16_t USART_Clock; // 时钟使能控制
3 uint16_t USART_CPOL; // 时钟极性
4 uint16_t USART_CPHA; // 时钟相位
5 uint16_t USART_LastBit; // 最尾位时钟脉冲
6 } USART_ClockInitTypeDef;
1) USART_Clock:同步模式下 SCLK 引脚上时钟输出使能控制,可选禁止时钟输出
(USART_Clock_Disable)或开启时钟输出(USART_Clock_Enable);如果使用同步模
式发送,一般都需要开启时钟。它设定 USART_CR2 寄存器的 CLKEN 位的值。
2) USART_CPOL:同步模式下 SCLK 引脚上输出时钟极性设置,可设置在空闲时
SCLK 引脚为低电平(USART_CPOL_Low)或高电平(USART_CPOL_High)。它设
定 USART_CR2 寄存器的 CPOL 位的值。


3) USART_CPHA:同步模式下 SCLK 引脚上输出时钟相位设置,可设置在时钟第一
个变化沿捕获数据(USART_CPHA_1Edge)或在时钟第二个变化沿捕获数据。它设
定 USART_CR2 寄存器的 CPHA 位的值。USART_CPHA 与 USART_CPOL 配合
使用可以获得多种模式时钟关系。
4) USART_LastBit:选择在发送最后一个数据位的时候时钟脉冲是否在 SCLK 引脚
输 出 , 可 以 是 不 输 出 脉 冲 (USART_LastBit_Disable) 、 输 出 脉 冲
(USART_LastBit_Enable)。它设定 USART_CR2 寄存器的 LBCL 位的值。
21.5 USART1 接发通信实验
USART 只需两根信号线即可完成双向通信,对硬件要求低,使得很多模块都预留
USART 接口来实现与其他模块或者控制器进行数据传输,比如 GSM 模块,WIFI 模块、蓝
牙模块等等。在硬件设计时,注意还需要一根“共地线”。
我们经常使用 USART 来实现控制器与电脑之间的数据传输。这使得我们调试程序非
常方便,比如我们可以把一些变量的值、函数的返回值、寄存器标志位等等通过 USART
发送到串口调试助手,这样我们可以非常清楚程序的运行状态,当我们正式发布程序时再
把这些调试信息去除即可。
我们不仅仅可以将数据发送到串口调试助手,我们还可以在串口调试助手发送数据给
控制器,控制器程序根据接收到的数据进行下一步工作。
首先,我们来编写一个程序实现开发板与电脑通信,在开发板上电时通过 USART 发
送一串字符串给电脑,然后开发板进入中断接收等待状态,如果电脑有发送数据过来,开
发板就会产生中断,我们在中断服务函数接收数据,并马上把数据返回发送给电脑。
21.5.1 硬件设计
为利用 USART 实现开发板与电脑通信,需要用到一个 USB 转 USART 的 IC,我们选
择 CH340G 芯片来实现这个功能,CH340G 是一个 USB 总线的转接芯片,实现 USB 转
USART、USB 转 lrDA 红外或者 USB 转打印机接口,我们使用其 USB 转 USART 功能。具
体电路设计见图 21-9。
我们将 CH340G 的 TXD 引脚与 USART1 的 RX 引脚连接,CH340G 的 RXD 引脚与
USART1 的 TX 引脚连接。CH340G 芯片集成在开发板上,其地线(GND)已与控制器的
GND 连通。

使用 GPIO_InitTypeDef 和 USART_InitTypeDef 结构体定义一个 GPIO 初始化变量以及
一个 USART 初始化变量,这两个结构体内容我们之前已经有详细讲解。
调用 RCC_APB2PeriphClockCmd 函数开启 GPIO 端口时钟,使用 GPIO 之前必须开启
对应端口的时钟。使用 RCC_APB2PeriphClockCmd 函数开启 USART 时钟。
使用 GPIO 之前都需要初始化配置它,并且还要添加特殊设置,因为我们使用它作为
外设的引脚,一般都有特殊功能。我们在初始化时需要把它的模式设置为复用功能。这里
把串口的 Tx 引脚配置为复用推挽输出,Rx 引脚为浮空输入,数据完全由外部输入决定。
接下来,我们配置 USART1 通信参数为:波特率 115200,字长为 8,1 个停止位,没
有校验位,不使用硬件流控制,收发一体工作模式,然后调用 USART 初始化函数完成配
置。
程序用到 USART 接收中断,需要配置 NVIC,这里调用 NVIC_Configuration 函数完成
配置。配置完 NVIC 之后调用 USART_ITConfig 函数使能 USART 接收中断。


Usart_SendByte 函数用来在指定 USART 发送一个 ASCLL 码值字符,它有两个形参,
第一个为 USART,第二个为待发送的字符。它是通过调用库函数 USART_SendData 来实
现的,并且增加了等待发送完成功能。通过使用 USART_GetFlagStatus 函数来获取 USART
事件标志来实现发送完成功能等待,它接收两个参数,一个是 USART,一个是事件标志。
这里我们循环检测发送数据寄存器为空这个标志,当跳出 while 循环时说明发送数据寄存
器为空这个事实。
Usart_SendString 函数用来发送一个字符串,它实际是调用 Usart_SendByte 函数发送每
个字符,直到遇到空字符才停止发送。最后使用循环检测发送完成的事件标志 TC 来实现
保证数据发送完成后才退出函数。

猜你喜欢

转载自blog.csdn.net/u012651389/article/details/118010978