STM32串口使用

来源:互联网 发布:java初级教程 编辑:程序博客网 时间:2024/06/06 01:48

STM32的串口大多数情况下会预留USART1作为烧录接口或者调试接口。

通常做法是调用 stdio.h 将串口的输入输出重新定向,可以直接调用printf.

代码如下:

/**  ******************************************************************************  * 文件名程: bsp_usartx.c   * 版    本: V1.0  * 编写日期:   * 功    能: 串口底层驱动程序  *//* 包含头文件 ----------------------------------------------------------------*/#include "bsp/usart/bsp_usartx.h"/**  * 函数功能: 配置NVIC,设定USART接收中断优先级.  * 输入参数: 无  * 返 回 值: 无  * 说    明:无  */void NVIC_Configuration(void){NVIC_InitTypeDef NVIC_InitStructure;  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); /* 嵌套向量中断控制器组选择 */ NVIC_InitStructure.NVIC_IRQChannel = USARTx_IRQn; /* 配置USART为中断源 */ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;/* 抢断优先级为0 */NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; /* 子优先级为1 */NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; /* 使能中断 */NVIC_Init(&NVIC_InitStructure);/* 初始化配置NVIC */}/**  * 函数功能: 串口参数配置.  * 输入参数: 无  * 返 回 值: 无  * 说    明:使用宏定义方法代替具体引脚号,方便程序移植,只要简单修改bsp_led.h  *           文件相关宏定义就可以方便修改引脚。  */void USARTx_Init(void){    GPIO_InitTypeDef GPIO_InitStructure;/* 定义IO硬件初始化结构体变量 */USART_InitTypeDef USART_InitStructure;/* 定义USART初始化结构体变量 */    NVIC_Configuration();/* 配置NVIC,设定USART接收中断优先级 */    USARTx_ClockCmd(USARTx_CLK,ENABLE);/* 使能USART时钟 */    USARTx_GPIO_ClockCmd(USARTx_TX_CLK | USARTx_RX_CLK | RCC_APB2Periph_AFIO,ENABLE);/* 使能USART功能GPIO时钟 *//* 调试USART功能GPIO初始化 */GPIO_InitStructure.GPIO_Pin =  USARTx_TX_PIN;/* 设定USART发送对应IO编号 */GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;/* 设定USART发送对应IO模式:复用推挽输出 */GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;/* 设定USART发送对应IO最大操作速度 :GPIO_Speed_50MHz */GPIO_Init(USARTx_TX_PORT, &GPIO_InitStructure);/* 初始化USART发送对应IO */   GPIO_InitStructure.GPIO_Pin = USARTx_RX_PIN;/* 设定USART接收对应IO编号 */GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; /* 设定USART发送对应IO模式:浮空输入 */    /* 其他没有重新赋值的成员使用与串口发送相同配置 */GPIO_Init(USARTx_RX_PORT, &GPIO_InitStructure); /* 初始化USART接收对应IO *//* USART工作环境配置 */USART_InitStructure.USART_BaudRate = USARTx_BAUDRATE; /* USART波特率:115200 */USART_InitStructure.USART_WordLength = USART_WordLength_8b; /* USART字长(有效位):8位 */USART_InitStructure.USART_StopBits = USART_StopBits_1;/* USART停止位:1位 */USART_InitStructure.USART_Parity = USART_Parity_No ;/* USART校验位:无 */USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;/* USART硬件数据流控制(硬件信号控制传输停止):无 */    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;/* USART工作模式使能:允许接收和发送 */USART_Init(USARTx, &USART_InitStructure);/* 初始化USART */      USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE);/* 使能接收中断 */USART_ITConfig ( USARTx, USART_IT_IDLE, ENABLE ); //使能串口总线空闲中断  USART_Cmd(USARTx, ENABLE);/* 使能USART */USART_ClearFlag(USARTx, USART_FLAG_TC|USART_FLAG_TXE|USART_FLAG_RXNE);/* 清除发送完成标志 */}/**  * 函数功能: 重定向c库函数printf到USARTx  * 输入参数: 无  * 返 回 值: 无  * 说    明:无  */int fputc(int ch, FILE *f){  /* 发送一个字节数据到调试串口 */  USART_SendData(USARTx, (uint8_t) ch);  /* 等待串口数据发送完毕 */  while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);  return (ch);} struct STRUCT_USARTx_Fram strUsart_Fram_Record = {0};void USARTx_IRQHANDLER(void){uint8_t ucCh;if(USART_GetITStatus(USARTx,USART_IT_RXNE)!=RESET){    ucCh=USART_ReceiveData(USARTx);if(strUsart_Fram_Record.InfBit.FramLength<(RX_BUF_MAX_LEN-1)){strUsart_Fram_Record.Data_RX_BUF[strUsart_Fram_Record.InfBit.FramLength++]=ucCh;}}if(USART_GetITStatus(USARTx,USART_IT_IDLE)==SET){      strUsart_Fram_Record .InfBit .FramFinishFlag = 1;  ucCh = USART_ReceiveData(USARTx); //由软件序列清除中断标志位(先读USART_SR,然后读USART_DR)}}

#ifndef __BSP_USARTX_H__#define __BSP_USARTX_H__/* 包含头文件 ----------------------------------------------------------------*/#include <stm32f10x.h>#include <stdio.h>/* 类型定义 ------------------------------------------------------------------*//* 宏定义 --------------------------------------------------------------------*/#define USARTx_BAUDRATE                        115200#define USARTx_ClockCmd                        RCC_APB2PeriphClockCmd#define USARTx_CLK                             RCC_APB2Periph_USART1#define USARTx_GPIO_ClockCmd                   RCC_APB2PeriphClockCmd    #define USARTx_TX_PORT                         GPIOA   #define USARTx_TX_PIN                          GPIO_Pin_9#define USARTx_TX_CLK                          RCC_APB2Periph_GPIOA #define USARTx_RX_PORT                         GPIOA #define USARTx_RX_PIN                          GPIO_Pin_10#define USARTx_RX_CLK                          RCC_APB2Periph_GPIOA#define USARTx_IRQHANDLER                      USART1_IRQHandler#define USARTx_IRQn                            USART1_IRQn#define USARTx                                 USART1/* 扩展变量 ------------------------------------------------------------------*//* 函数声明 ------------------------------------------------------------------*/void USARTx_Init(void);void Usart_SendByte(uint8_t ch);void Usart_SendStr_length(uint8_t *str,uint32_t strlen);void Usart_SendString(uint8_t *str);#if defined ( __CC_ARM   )#pragma anon_unions#endif/******************************* ESP8266 外部全局变量声明 ***************************/#define RX_BUF_MAX_LEN     500                                     //最大接收缓存字节数extern  struct  STRUCT_USARTx_Fram                                  //串口数据帧的处理结构体{char  Data_RX_BUF [ RX_BUF_MAX_LEN ];  union {    __IO u16 InfAll;    struct {  __IO u16 FramLength       :15;                               // 14:0   __IO u16 FramFinishFlag   :1;                                // 15   } InfBit;  }; }strUsart_Fram_Record;#endif  

上面重新定义了C库文件。


如果我们不仅仅想使用串口的调试功能,同样也希望使用其他串口做其他功能,那么需要重新编写printf函数。

如下:可以写入字符或者字符串

/**  * 函数功能: 串口发送一个字节数据   * 输入参数: ch:待发送字符  * 返 回 值: 无  * 说    明:无  */void Usart_SendByte(uint8_t ch){  /* 发送一个字节数据到USART1 */  USART_SendData(USARTx,ch);  /* 等待发送完毕 */  while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);}/**  * 函数功能: 串口发送指定长度的字符串  * 输入参数: str:待发送字符串缓冲器  *           strlen:指定字符串长度  * 返 回 值: 无  * 说    明:无  */void Usart_SendStr_length(uint8_t *str,uint32_t strlen){  unsigned int k=0;  do   {    Usart_SendByte(*(str + k));    k++;  } while(k < strlen);}/**  * 函数功能: 串口发送字符串,直到遇到字符串结束符  * 输入参数: str:待发送字符串缓冲器  * 返 回 值: 无  * 说    明:无  */void Usart_SendString(uint8_t *str){unsigned int k=0;  do   {    Usart_SendByte(*(str + k));    k++;  } while(*(str + k)!='\0');}