欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 能源 > STM32第十二节(中级篇):串口通信(第二节)——串口固件库函数以及串口发送和接收代码讲解

STM32第十二节(中级篇):串口通信(第二节)——串口固件库函数以及串口发送和接收代码讲解

2025/2/24 17:42:58 来源:https://blog.csdn.net/2301_79641086/article/details/141195516  浏览:    关键词:STM32第十二节(中级篇):串口通信(第二节)——串口固件库函数以及串口发送和接收代码讲解

STM32第十二节(中级篇):串口通信(第二节)——串口固件库函数以及串口发送和接收代码讲解


串口固件库函数

代码片段

/** * @brief  USART Init Structure definition  */ typedef struct
{uint32_t USART_BaudRate;            /*!< This member configures the USART communication baud rate.The baud rate is computed using the following formula:- IntegerDivider = ((PCLKx) / (16 * (USART_InitStruct->USART_BaudRate)))- FractionalDivider = ((IntegerDivider - ((u32) IntegerDivider)) * 16) + 0.5 */uint16_t USART_WordLength;          /*!< Specifies the number of data bits transmitted or received in a frame.This parameter can be a value of @ref USART_Word_Length */uint16_t USART_StopBits;            /*!< Specifies the number of stop bits transmitted.This parameter can be a value of @ref USART_Stop_Bits */uint16_t USART_Parity;              /*!< Specifies the parity mode.This parameter can be a value of @ref USART_Parity@note When parity is enabled, the computed parity is insertedat the MSB position of the transmitted data (9th bit whenthe word length is set to 9 data bits; 8th bit when theword length is set to 8 data bits). */uint16_t USART_Mode;                /*!< Specifies wether the Receive or Transmit mode is enabled or disabled.This parameter can be a value of @ref USART_Mode */uint16_t USART_HardwareFlowControl; /*!< Specifies wether the hardware flow control mode is enabledor disabled.This parameter can be a value of @ref USART_Hardware_Flow_Control */
} USART_InitTypeDef;

        本节课的代码是基础的配置,在后续学习以及编写代码的时候有很大的作用在上述代码中,就是对于USART结构体的初始化,我们可以在野火的资料盘中找到,在stm32f10x_usart.h文件中可以找到。我们观察这段代码,逐行解释代码部分。

结构体参数解释

        uint32 _t USART BaudRate;        //波特率 BRR

        uint16_t USART WordLength;     //字长 CR_1/M

        uint16_t USART StopBits;           //停止位 CR_2/STOP

        uint16_t USART Parity;               //校验控制 CR_1 PCE、CR_1 PS 

        uint16_t USART Mode;               //模式选择CR_1 TE、CR_1 RE

        // 硬件流选择 CR_3 CTSE、CR_3 RTSE:

        uintl6_t USART HardwareFlowControl;

结构体参数配置

        字长可以设置为八位或九位,详细内容在上节课有细致讲到。

        每一段数据传输的时候都要有停止位(STOP),对于STOP来说,有四个可选择的时间段。

        如果有效验位的话,会分为奇效验和偶效验两种效验方式,当然也可以选择没有效验位。

        对于USART模式上的选择来说,有输入数据和输出数据的选择。

/** @defgroup USART_Word_Length * @{*/ #define USART_WordLength_8b                  ((uint16_t)0x0000)
#define USART_WordLength_9b                  ((uint16_t)0x1000)#define IS_USART_WORD_LENGTH(LENGTH) (((LENGTH) == USART_WordLength_8b) || \((LENGTH) == USART_WordLength_9b))/** @defgroup USART_Stop_Bits * @{*/ #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)
#define IS_USART_STOPBITS(STOPBITS) (((STOPBITS) == USART_StopBits_1) || \((STOPBITS) == USART_StopBits_0_5) || \((STOPBITS) == USART_StopBits_2) || \((STOPBITS) == USART_StopBits_1_5))/** @defgroup USART_Parity * @{*/ #define USART_Parity_No                      ((uint16_t)0x0000)
#define USART_Parity_Even                    ((uint16_t)0x0400)
#define USART_Parity_Odd                     ((uint16_t)0x0600) 
#define IS_USART_PARITY(PARITY) (((PARITY) == USART_Parity_No) || \((PARITY) == USART_Parity_Even) || \((PARITY) == USART_Parity_Odd))/** @defgroup USART_Mode * @{*/ #define USART_Mode_Rx                        ((uint16_t)0x0004)
#define USART_Mode_Tx                        ((uint16_t)0x0008)
#define IS_USART_MODE(MODE) ((((MODE) & (uint16_t)0xFFF3) == 0x00) && ((MODE) != (uint16_t)0x00))/** @defgroup USART_Hardware_Flow_Control * @{*/ 
#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)
#define IS_USART_HARDWARE_FLOW_CONTROL(CONTROL)\(((CONTROL) == USART_HardwareFlowControl_None) || \((CONTROL) == USART_HardwareFlowControl_RTS) || \((CONTROL) == USART_HardwareFlowControl_CTS) || \((CONTROL) == USART_HardwareFlowControl_RTS_CTS))

        以上就是有关结构体的参数构建,这个是最基本都要会的结构体,当然,还有同步时钟初始化结构体的相关构建。

同步时钟初始化结构体

代码展示

typedef struct
{uint16_t USART_Clock;   /*!< Specifies whether the USART clock is enabled or disabled.This parameter can be a value of @ref USART_Clock */uint16_t USART_CPOL;    /*!< Specifies the steady state value of the serial clock.This parameter can be a value of @ref USART_Clock_Polarity */uint16_t USART_CPHA;    /*!< Specifies the clock transition on which the bit capture is made.This parameter can be a value of @ref USART_Clock_Phase */uint16_t USART_LastBit; /*!< Specifies whether the clock pulse corresponding to the last transmitteddata bit (MSB) has to be output on the SCLK pin in synchronous mode.This parameter can be a value of @ref USART_Last_Bit */
} USART_ClockInitTypeDef;

结构体配置

/** @defgroup USART_Clock * @{*/ 
#define USART_Clock_Disable                  ((uint16_t)0x0000)
#define USART_Clock_Enable                   ((uint16_t)0x0800)
#define IS_USART_CLOCK(CLOCK) (((CLOCK) == USART_Clock_Disable) || \((CLOCK) == USART_Clock_Enable))/** @defgroup USART_Clock_Polarity * @{*/#define USART_CPOL_Low                       ((uint16_t)0x0000)
#define USART_CPOL_High                      ((uint16_t)0x0400)
#define IS_USART_CPOL(CPOL) (((CPOL) == USART_CPOL_Low) || ((CPOL) == USART_CPOL_High))/** @defgroup USART_Clock_Phase* @{*/#define USART_CPHA_1Edge                     ((uint16_t)0x0000)
#define USART_CPHA_2Edge                     ((uint16_t)0x0200)
#define IS_USART_CPHA(CPHA) (((CPHA) == USART_CPHA_1Edge) || ((CPHA) == USART_CPHA_2Edge))/** @defgroup USART_Last_Bit* @{*/#define USART_LastBit_Disable                ((uint16_t)0x0000)
#define USART_LastBit_Enable                 ((uint16_t)0x0100)
#define IS_USART_LASTBIT(LASTBIT) (((LASTBIT) == USART_LastBit_Disable) || \((LASTBIT) == USART_LastBit_Enable))

串口编程常用函数

        我们在编程的时候常用的几个固件库函数一共有六个。接下来就仔细地为大家讲一下这六个函数。分别是串口初始化函数,中断配置函数,串口使能函数,数据发送函数,数据接收函数,中断状态位获取函数。

        串口初始化函数(void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);)

        中断配置函数(void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState);)

        串口使能函数(void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState);)

        数据发送函数(void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);)

        数据接收函数(void USART_SendBreak(USART_TypeDef* USARTx);)

        中断状态位获取函数(ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT);)

        至此,全部理论部分就结束了,接下来就是代码的讲解:

串口发送和接收

硬件设计

                                                        TTL转USB电平(要有CH340驱动)

        今天所编写的第一个代码要求如下:

        单片机给电脑发送数据,电脑上位机把数据打印出来;

        电脑上位机给单片机发数据,单片机接收到数据之后立马发回给电脑,并打印出来。

编程流程

1.初始化串口需要用到的GPIO

        这些代码都放在了bsp_usart.h文件中,采用宏定义把我们所需要的usart串口所需要的GPIO引脚定义好:

// 串口1-USART1
#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_RX_GPIO_PORT       GPIOA
#define  DEBUG_USART_RX_GPIO_PIN        GPIO_Pin_10#define  DEBUG_USART_IRQ                USART1_IRQn
#define  DEBUG_USART_IRQHandler         USART1_IRQHandler
2.初始化串口,USART_InitTypeDef,使能串口,中断配置(接收中断,中断优先级)

        首先,我们先定义结构体GPIO_InitTypeDef GPIO_InitStructure和USART_InitTypeDef USART_InitStructure;然后配置GPIO,首先打开APB2_GPIOA的时钟。然后就是串口外设的时钟,再接着就配置GPIO模式(老三套);配置USART Rx位浮空输入模式;就是我们刚刚讲的那几个串口结构体参数配置;

void USART_Config(void)
{GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;// 打开串口GPIO的时钟DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE);// 打开串口外设的时钟DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE);// 将USART Tx的GPIO配置为推挽复用模式GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;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 = GPIO_Mode_IN_FLOATING;GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);// 配置串口的工作参数// 配置波特率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);	    
}

        在电脑上位机向单片机传输数据时会有中断的产生,所以我们在这里还要配置中断函数,调节中断优先值,最后使能串口。

3.编写中断服务函数
static void NVIC_Configuration(void)
{NVIC_InitTypeDef NVIC_InitStructure;/* 嵌套向量中断控制器组选择 *//* 提示 NVIC_PriorityGroupConfig() 在整个工程只需要调用一次来配置优先级分组*/NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);/* 配置USART为中断源 */NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ;/* 抢断优先级*/NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;/* 子优先级 */NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;/* 使能中断 */NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;/* 初始化配置NVIC */NVIC_Init(&NVIC_InitStructure);
}
4.编写发送和接收函数

        那么我们可以试着编写一个固件库函数使得我们可以发送一个字节:

        首先我们确定参数输入,指定需要的串口,和一个字节的数据(只能是八位);接下来找到SendData函数,第一个形参为串口名,第二个形参为八位的数据;根据上节课的知识,应该是发送数据寄存器为空。我们进入循环,判断USART_GetFlagStatus(形参为串口名和USART_FLAG_TXE位)是否为空。

/*****************  发送一个字节 **********************/
void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch)
{/* 发送一个字节数据到USART */USART_SendData(pUSARTx,ch);/* 等待发送数据寄存器为空 */while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);	
}

 小结

        创作不易,点个三连关注一下吧!!

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词