5、【STM32F0系列学习】之—通用同步异步收发器(UART)

1、USART 介绍

  通用同步异步收发器(Universal Synchronous Asynchronous Receiver and Transmitter)是一个串行通信设备,可以灵活地与外部设备进行全双工数据交换。有别于 USART 还有一个UART(Universal Asynchronous Receiver and Transmitter),它是在 USART 基础上裁剪掉了同步通信功能,只有异步通信。简单区分同步和异步就是看通信时需不需要对外提供时钟输出,我们平时用的串口通信基本都是 UART。
  串行通信一般是以帧格式传输数据,即是一帧一帧的传输,每帧包含有起始信号、数 据信息、停止信息,可能还有校验信息。USART 就是对这些传输参数有具体规定,当然也 不是只有唯一一个参数值,很多参数值都可以自定义设置,只是增强它的兼容性。
  USART 满足外部设备对工业标准 NRZ 异步串行数据格式的要求,并且使用了小数波 特率发生器,可以提供多种波特率,使得它的应用更加广泛。USART 支持同步单向通信和半双工单线通信;还支持局域互连网络 LIN、智能卡(SmartCard)协议与 lrDA(红外线数据 协会) SIR ENDEC 规范。
  USART 支持使用 DMA,可实现高速数据通信,有关 DMA 具体应用将在 DMA 章节 作具体讲解。
  USART 在 STM32 应用最多莫过于“打印”程序信息,一般在硬件设计时都会预留一 个 USART 通信接口连接电脑,用于在调试程序是可以把一些调试信息“打印”在电脑端 的串口调试助手工具上,从而了解程序运行是否正确、如果出错哪具体哪里出错等等。

2、串口通讯协议简介

  串口通讯(Serial Communication)是一种设备间非常常用的串行通讯方式,因为它简单 便捷,因此大部分电子设备都支持该通讯方式,电子工程师在调试设备时也经常使用该通 讯方式输出调试信息。
  在计算机科学里,大部分复杂的问题都可以通过分层来简化。如芯片被分为内核层和 片上外设;STM32 标准库则是在寄存器与用户代码之间的软件层。对于通讯协议,我们也 以分层的方式来理解,最基本的是把它分为物理层和协议层。物理层规定通讯系统中具有 机械、电子功能部分的特性,确保原始数据在物理媒体的传输。协议层主要规定通讯逻辑, 统一收发双方的数据打包、解包标准。简单来说物理层规定我们用嘴巴还是用肢体来交流, 协议层则规定我们用中文还是英文来交流。
  下面我们分别对串口通讯协议的物理层及协议层进行讲解。

2.1、物理层

  串口通讯的物理层有很多标准及变种,我们主要讲解 RS-232 标准 ,RS-232 标准主要 规定了信号的用途、通讯接口以及信号的电平标准。
在这里插入图片描述
  在上面的通讯方式中,两个通讯设备的“DB9 接口”之间通过串口信号线建立起连接, 串口信号线中使用“RS-232 标准”传输数据信号。由于 RS-232 电平标准的信号不能直接被控制器直接识别,所以这些信号会经过一个“电平转换芯片”转换成控制器能识别的 “TTL 标准”的电平信号,才能实现通讯。

2.1.1、电平标准

  根据通讯使用的电平标准不同,串口通讯可分为 TTL 标准及 RS-232 标准,见下表 TTL 电平标准与 RS232 电平标准:
在这里插入图片描述
  我们知道常见的电子电路中常使用 TTL 的电平标准,理想状态下,使用 5V 表示二进制逻辑 1,使用 0V 表示逻辑 0;而为了增加串口通讯的远距离传输及抗干扰能力,它使用-15V 表示逻辑 1,+15V 表示逻辑 0。使用 RS232 与 TTL 电平标准准表示同一个信号时的对比。
在这里插入图片描述
  因为控制器一般使用 TTL 电平标准,所以常常会使用 MAX232 芯片对 TTL 及 RS-232电平的信号进行互相转换。

2.1.2、RS-232 信号线

  在最初的应用中,RS-232 串口标准常用于计算机、路由与调制调解器(modem,俗称“猫”)之间的通讯 ,在这种通讯系统中,设备被分为数据终端设备 DTE(计算机、路由)和数据通讯设备 DCE(调制调解器)。我们以这种通讯模型讲解它们的信号线连接方式及各个
信号线的作用。
  在旧式的台式计算机中一般会有 RS-232 标准的 COM 口(也称 DB9 接口),如下图:
在这里插入图片描述
  其中接线口以针式引出信号线的称为公头,以孔式引出信号线的称为母头。在计算机中一般引出公头接口,而在调制调解器设备中引出的一般为母头,使用上图中的串口线即可把它与计算机连接起来。通讯时,串口线中传输的信号就是使用前面讲解的 RS-232 标准调制的。
  在这种应用场合下,DB9 接口中的公头及母头的各个引脚的标准信号线接法见下图:
在这里插入图片描述
  下面对各个信号线进行说明
在这里插入图片描述
  上表中的是计算机端的 DB9 公头标准接法,由于两个通讯设备之间的收发信号(RXD与 TXD)应交叉相连,所以调制调解器端的 DB9 母头的收发信号接法一般与公头的相反,两个设备之间连接时,只要使用“直通型”的串口线连接起来即可,见下图:
在这里插入图片描述
  串口线中的 RTS、CTS、DSR、DTR 及 DCD 信号,使用逻辑 1 表示信号有效,逻辑 0 表示信号无效。例如,当计算机端控制 DTR 信号线表示为逻辑 1 时,它是为了告知远端的 调制调解器,本机已准备好接收数据,0 则表示还没准备就绪。
  在目前的其它工业控制使用的串口通讯中,一般只使用 RXD、TXD 以及 GND 三条信 号线,直接传输数据信号,而 RTS、CTS、DSR、DTR 及 DCD 信号都被裁剪掉了。

2.2、协议层

  串口通讯的数据包由发送设备通过自身的 TXD 接口传输到接收设备的 RXD 接口。在 串口通讯的协议层中,规定了数据包的内容,它由启始位、主体数据、校验位以及停止位 组成,通讯双方的数据包格式要约定一致才能正常收发数据,其组成见下图。
在这里插入图片描述

  • 总线在发送或接收前应处于空闲状态
  • 一个起始位
  • 一个数据字(8或9位),最低有效位在前
  • 一个校验位
  • 一个或两个停止位
    以上为在普通UART模式下串行数据的发送接收数据帧结构组成,但通常情况下,我们是采用一个起始位、一个8位的数据字、无校验位,1个停止位来组成一帧数据,如下图:
    在这里插入图片描述

2.2.1、波特率

  波特率是指串行异步通信时的传输速率,由于异步通讯中没有时钟信号,所以两个通讯设备之间需要约定好波特率,即每个码元的长度,一遍对信号进行解码。而串行同步通信在通信的两个设备之间是有一根时钟信号线的,双方的通信是基于这根时钟信号线上的时钟的。传送速率用于说明数据传送的快慢。在串行通信中,数据是按位进行传送的,因此传送速率用每秒钟传送格式位的数目来表示,称之为波特率(band rate)。每秒传送一个格式位就是1波特。常见的波特率为4800、9600、115200等。

2.2.2、通讯的起始和停止信号

  串口通讯的一个数据包从起始信号开始,直到停止信号结束。数据包的起始信号由一 个逻辑 0 的数据位表示,而数据包的停止信号可由 0.5、1、1.5 或 2 个逻辑 1 的数据位表示, 只要双方约定一致即可。

2.2.3、有效数据

  在数据包的起始位之后紧接着的就是要传输的主体数据内容,也称为有效数据,有效 数据的长度常被约定为 5、6、7 、8或9 位长。

2.2.4、数据校验

  在有效数据之后,有一个可选的数据校验位。由于数据通信相对更容易受到外部干扰 导致传输数据出现偏差,可以在传输过程加上校验位来解决这个问题。校验方法有奇校验 (odd)、偶校验(even)、0 校验(space)、1 校验(mark)以及无校验(noparity)。
  奇校验要求有效数据和校验位中“1”的个数为奇数,比如一个 8 位长的有效数据为: 01101001,此时总共有 4 个“1”,为达到奇校验效果,校验位为“1”,最后传输的数据 将是 8 位的有效数据加上 1 位的校验位总共 9 位。
偶校验与奇校验要求刚好相反,要求帧数据和校验位中“1”的个数为偶数,比如数据 帧:11001010,此时数据帧“1”的个数为 4 个,所以偶校验位为“0”。
  0 校验是不管有效数据中的内容是什么,校验位总为“0”,1 校验是校验位总为“1”。

3、RS232串口通信配置

3.1、【标准库】的配置方式

步骤:
1、初始化USART1的GPIO引脚以及初始化操作

/*-------------------------------------------------- usart.h --------------------------------------------------*/
/**
  ********************************  STM32F0xx  *********************************
  * @文件名     : usart.h
  * @作者       : JayYang
  * @库版本     : V1.5.0
  * @文件版本   : V1.0.0
  * @日期       : 2020年08月11日
  * @摘要       : USART头文件
  ******************************************************************************/

/* 定义防止递归包含 ----------------------------------------------------------*/
#ifndef _USART_H
#define _USART_H

/* 包含的头文件 --------------------------------------------------------------*/
#include "stm32f0xx.h"


/* 函数申明 ------------------------------------------------------------------*/
void USART_Initializes(void);
void USART1_SendByte(uint8_t Data);
void USART1_SendNByte(uint8_t *pData, uint16_t Length);
void USART1_Printf(uint8_t *String);


#endif /* _USART_H */

/**** Copyright (C)2020 JayYang. All Rights Reserved **** END OF FILE ****/

/*-------------------------------------------------- usart.c --------------------------------------------------*/
/**
  ********************************  STM32F0xx  *********************************
  * @文件名     : usart.c
  * @作者       : JayYang
  * @库版本     : V1.5.0
  * @文件版本   : V1.0.0
  * @日期       : 2020年08月11日
  * @摘要       : USART源文件
  ******************************************************************************/
/*----------------------------------------------------------------------------
  更新日志:
  2020-08-11 V1.0.0:初始版本
  ----------------------------------------------------------------------------*/
/* 包含的头文件 --------------------------------------------------------------*/
#include "usart.h"

/* 函数申明 ------------------------------------------------------------------*/
static void USART_GPIO_Configuration(void);
static void USART_Configuration(void);

/* 函数定义 ------------------------------------------------------------------*/
/************************************************
函数名称 : USART_GPIO_Configuration
功    能 : USART所使用管脚输出输入定义
参    数 : 无
返 回 值 : 无
作    者 : JayYang
*************************************************/
static void USART_GPIO_Configuration(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);    //配置PA9引脚使用复用功能:USART1_TX
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);   //配置PA10引脚使用复用功能:USART1_RX

    /* 定义USART TX_RX 引脚为复用输出 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //引脚
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;            //复用模式
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;       //高速
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;          //推完输出
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;            //上拉(空闲状态为高电平)
    GPIO_Init(GPIOA, &GPIO_InitStructure);                  //初始化引脚
}

/************************************************
函数名称 : USART_Configuration
功    能 : 配置USART
参    数 : 无
返 回 值 : 无
作    者 : JayYang
*************************************************/
static void USART_Configuration(void)
{
    USART_InitTypeDef USART_InitStructure;

    /******************************************************************
    USART参数初始化:  波特率     传输位数   停止位数  校验位数
                    115200         8         1        0(NO)
    *******************************************************************/
    USART_InitStructure.USART_BaudRate = 115200;                       //设定传输速率
    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);                          //初始化USART1

    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);                     //使能USART1接收中断

    USART_Cmd(USART1, ENABLE);                                         //使能USART1
}

/************************************************
函数名称 : USART_Initializes
功    能 : 串口初始化
参    数 : 无
返 回 值 : 无
作    者 : JayYang
*************************************************/
void USART_Initializes(void)
{
    USART_GPIO_Configuration();
    USART_Configuration();
}

/************************************************
函数名称 : USART1_SendByte
功    能 : 串口1发送一字节数据
参    数 : Data --- 数据
返 回 值 : 无
作    者 : JayYang
*************************************************/
void USART1_SendByte(uint8_t Data)
{
    while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);   //等待发送寄存器为空
    USART_SendData(USART1,Data);        //发送数据
}

/************************************************
函数名称 : USART1_SendNByte
功    能 : 串口1发送N个字符
参    数 : pData ----- 字符串
            Length --- 长度
返 回 值 : 无
作    者 : JayYang
*************************************************/
void USART1_SendNByte(uint8_t *pData, uint16_t Length)
{
    while(Length--)
    {
        USART1_SendByte(*pData);
        pData++;
    }
}

/************************************************
函数名称 : USART1_Printf
功    能 : 串口1打印输出
参    数 : String --- 字符串
返 回 值 : 无
作    者 : JayYang
*************************************************/
void USART1_Printf(uint8_t *String)
{
    while((*String) != '\0')
    {
        USART1_SendByte(*String);
        String++;
    }
    USART1_SendByte(0x0A);
}


/**** Copyright (C)2020 JayYang. All Rights Reserved **** END OF FILE ****/

2、开启USART外设的时钟以及所用引脚GPIOA的时钟,以及接收中断函数的处理

/*-------------------------------------------------- bsp.h --------------------------------------------------*/
/**
  *********************************  STM32F0xx  ********************************
  * @文件名     : bsp.h
  * @作者       : JayYang
  * @库版本     : V1.5.0
  * @文件版本   : V1.0.0
  * @日期       : 2020年08月11日
  * @摘要       : BSP板级支持包头文件
  ******************************************************************************/

/* 定义防止递归包含 ----------------------------------------------------------*/
#ifndef _BSP_H
#define _BSP_H

/* 包含的头文件 --------------------------------------------------------------*/
#include "stm32f0xx.h"

/* 自定义的头文件 --------------------------------------------------------------*/
#include "usart.h"

/* 宏定义 --------------------------------------------------------------------*/

/* 函数申明 ------------------------------------------------------------------*/
void BSP_Initializes(void);

#endif /* _BSP_H */

/**** Copyright (C)2020 JayYang. All Rights Reserved **** END OF FILE ****/

/*-------------------------------------------------- bsp.c --------------------------------------------------*/
/**
  ********************************  STM32F0xx  *********************************
  * @文件名     : bsp.c
  * @作者       : JayYang
  * @库版本     : V1.5.0
  * @文件版本   : V1.0.0
  * @日期       : 2020年08月11日
  * @摘要       : BSP板级支持包源文件
  ******************************************************************************/
/*----------------------------------------------------------------------------
  更新日志:
  2020-06-24 V1.0.0:初始版本
  ----------------------------------------------------------------------------*/
/* 包含的头文件 --------------------------------------------------------------*/
#include "bsp.h"

/* 函数申明 ------------------------------------------------------------------*/
static void RCC_Configuration(void);
static void NVIC_Configuration(void);

/* 函数定义 ------------------------------------------------------------------*/
/************************************************
函数名称 : BSP_Initializes
功    能 : 底层初始化
参    数 : 无
返 回 值 : 无
作    者 : JayYang
*************************************************/
void BSP_Initializes(void)
{
    RCC_Configuration();        //时钟配置
    USART_Initializes();        //串口1初始化
    NVIC_Configuration();       //外设中断配置
}

/************************************************
函数名称 : NVIC_Configuration
功    能 : NVIC配置
参    数 : 无
返 回 值 : 无
作    者 : JayYang
*************************************************/
static void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;

  /* 外设中断 */
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;                  //IRQ通道:串口1
  NVIC_InitStructure.NVIC_IRQChannelPriority = 1;                    //优先级 :1级
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                    //使能IRQ通道
  NVIC_Init(&NVIC_InitStructure);
}

/************************************************
函数名称 : RCC_Configuration
功    能 : 时钟配置
参    数 : 无
返 回 值 : 无
作    者 : JayYang
*************************************************/
static void RCC_Configuration(void)
{
    /* 使能AHB时钟:USART1的引脚为 PA9-TX P10-RX */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
    
    /* 使能APB2时钟:开启USART1的时钟 */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
    
}

/**** Copyright (C)2020 JayYang. All Rights Reserved **** END OF FILE ****/

/*------------------------------------------------ stm32f0xx_it.c ------------------------------------------------*/
/******************************************************************************/
/*                 STM32F0xx Peripherals Interrupt Handlers                   */
/*  Add here the Interrupt Handler for the used peripheral(s) (PPP), for the  */
/*  available peripheral interrupt handler's name please refer to the startup */
/*  file (startup_stm32f0xx.s).                                            */
/******************************************************************************/

/************************************************
函数名称 : USART1_IRQHandler
功    能 : USART1中断
参    数 : 无
返 回 值 : 无
作    者 : JayYang
*************************************************/
void USART1_IRQHandler(void)
{
  if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) != RESET)    //判断是否接收完成
  {
    USART1_SendByte((uint8_t)(USART_ReceiveData(USART1)));    //发送接收到的字符数据
  }
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

3、调用打印函数进行测试

/*-------------------------------------------------- main.c --------------------------------------------------*/
/**
  ********************************  STM32F0xx  *********************************
  * @文件名     : main.c
  * @作者       : JayYang
  * @库版本     : V1.5.0
  * @文件版本   : V1.0.0
  * @日期       : 2020年06月24日
  * @摘要       : 主函数 - 工程模板
  ******************************************************************************/
/*----------------------------------------------------------------------------
  更新日志:
  2020-06-24 V1.0.0:初始版本
  ----------------------------------------------------------------------------*/
/* 包含的头文件 --------------------------------------------------------------*/
#include "bsp.h"

unsigned char str[6]={'A','B','C','D','\r','\n'};

/************************************************
函数名称 : SoftwareDelay
功    能 : 软件延时
参    数 : 无
返 回 值 : 无
作    者 : JayYang
*************************************************/
void SoftwareDelay(uint32_t nCount)
{
  for(; nCount != 0; nCount--);
}

/************************************************
函数名称 : main
功    能 : 主函数入口
参    数 : 无
返 回 值 : int
作    者 : JayYang
*************************************************/
int main(void)
{
    BSP_Initializes();

    while(1)
    {
        //测试发送一个字节
//        USART1_SendByte(0xF0);
//        SoftwareDelay(0x3FFFFF);
        
        //测试发送一串字符
//        USART1_SendNByte(str,6);
//        SoftwareDelay(0x3FFFFF);
        
        USART1_Printf((uint8_t*)"串口打印测试\r\n");
        SoftwareDelay(0x3FFFFF);
    }
}
/**** Copyright (C)2020 JayYang. All Rights Reserved **** END OF FILE ****/

3.2、【HAL库】的配置方式

步骤:
1、配置RCC时钟,使用外部8MHz,然后PLL倍频到48MHz
在这里插入图片描述
在这里插入图片描述
2、在STM32CubeMX中配置USART1的相关参数
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
3、 编辑驱动代码

/*-------------------------------------------------- rs232.h --------------------------------------------------*/
/**
  *********************************  STM32F0xx  ********************************
  * @文件名     : rs232.h
  * @作者       : JayYang
  * @库版本     : V1.5.0
  * @文件版本   : V1.0.0
  * @日期       : 2020年06月24日
  * @摘要       : RS232驱动头文件
  ******************************************************************************/

/* 定义防止递归包含 ----------------------------------------------------------*/
#ifndef _RS232_H
#define _RS232_H

/* 包含的头文件 --------------------------------------------------------------*/
#include "stm32f0xx_hal.h"

/* 宏定义 --------------------------------------------------------------------*/
#define rs232_Buf_Max 20

/* 变量声明 --------------------------------------------------------------------*/
extern uint8_t rs232_Buf;
extern uint8_t rs232_Buf_count;
extern uint8_t rs232_Buf_try[rs232_Buf_Max];

/* 函数声明 --------------------------------------------------------------------*/
void RS232_RecvData(void);
void RS232_Demo1(void);


#endif /* _RS232_H */

/**** Copyright (C)2020 JayYang. All Rights Reserved **** END OF FILE ****/

/*-------------------------------------------------- rs232.c --------------------------------------------------*/
/**
  ********************************  STM32F0xx  *********************************
  * @文件名     : rs232.c
  * @作者       : JayYang
  * @库版本     : V1.5.0
  * @文件版本   : V1.0.0
  * @日期       : 2020年06月24日
  * @摘要       : RS232驱动源文件
  ******************************************************************************/
/*----------------------------------------------------------------------------
  更新日志:
  2020-06-24 V1.0.0:初始版本
  ----------------------------------------------------------------------------*/
/* 包含的头文件 --------------------------------------------------------------*/
#include "bsp.h"

uint8_t rs232_Buf=0;
uint8_t rs232_Buf_count=0;
uint8_t rs232_Buf_try[rs232_Buf_Max];

/************************************************
函数名称 : RS232_RecvData
功    能 : 接收数据
参    数 : 无
返 回 值 : 无
作    者 : JayYang
*************************************************/
void RS232_RecvData(void)
{
	if(rs232_Buf_count<rs232_Buf_Max)
	{
		rs232_Buf_try[rs232_Buf_count++]=rs232_Buf;
	}
	else
	{
		rs232_Buf_count=0;
	}
	
	HAL_UART_Receive_IT(&huart1,&rs232_Buf,1);
}


/************************************************
函数名称 : RS232_Demo1
功    能 : 将接收到的数据返回
参    数 : 无
返 回 值 : 无
作    者 : JayYang
*************************************************/
void RS232_Demo1(void)
{
	uint8_t i=0;
	
	if(rs232_Buf_count>0)
	{
		HAL_Delay(20);
		
		for(i=0;i<rs232_Buf_count;i++)
		{
			HAL_UART_Transmit(&huart1,&rs232_Buf_try[i],1,1000);
		}
		rs232_Buf_count=0;
	}
}

/**** Copyright (C)2020 JayYang. All Rights Reserved **** END OF FILE ****/

/*-------------------------------------------------- bsp.h --------------------------------------------------*/
/**
  *********************************  STM32F0xx  ********************************
  * @文件名     : bsp.h
  * @作者       : JayYang
  * @库版本     : V1.5.0
  * @文件版本   : V1.0.0
  * @日期       : 2020年06月24日
  * @摘要       : BSP板级支持包头文件
  ******************************************************************************/

/* 定义防止递归包含 ----------------------------------------------------------*/
#ifndef _BSP_H
#define _BSP_H

/* 包含的头文件 --------------------------------------------------------------*/
#include "main.h"
#include "stm32f0xx_hal.h"
#include "gpio.h"
#include "usart.h"
#include "string.h"

#include "rs232.h"


/* 宏定义 --------------------------------------------------------------------*/


/* 函数申明 ------------------------------------------------------------------*/
void BSP_Configuration(void);


#endif /* _BSP_H */

/**** Copyright (C)2020 JayYang. All Rights Reserved **** END OF FILE ****/

/*-------------------------------------------------- bsp.c --------------------------------------------------*/
/**
  ********************************  STM32F0xx  *********************************
  * @文件名     : bsp.c
  * @作者       : JayYang
  * @库版本     : V1.5.0
  * @文件版本   : V1.0.0
  * @日期       : 2020年06月24日
  * @摘要       : BSP板级支持包源文件
  ******************************************************************************/
/*----------------------------------------------------------------------------
  更新日志:
  2020-06-24 V1.0.0:初始版本
  ----------------------------------------------------------------------------*/
/* 包含的头文件 --------------------------------------------------------------*/
#include "bsp.h"

/************************************************
函数名称 : BSP_Configuration
功    能 : 初始化程序
参    数 : 无
返 回 值 : 无
作    者 : JayYang
*************************************************/
void BSP_Configuration(void)
{
	HAL_UART_Receive_IT(&huart1,&rs232_Buf,1);
}

/************************************************
函数名称 : HAL_UART_RxCpltCallback
功    能 : 串口接收中断回调函数
参    数 : 无
返 回 值 : 无
作    者 : JayYang
*************************************************/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart==&huart1)
	{
		RS232_RecvData();
	}
}



/**** Copyright (C)2020 JayYang. All Rights Reserved **** END OF FILE ****/


/*-------------------------------------------------- main.c --------------------------------------------------*/
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "bsp.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
uint8_t str[6]={'A','B','C','D','\r','\n'};
/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
uint32_t sysclk,pck1,pck2;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  BSP_Configuration();		//板级初始化
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
      RS232_Demo1();    //将上位机发送过来接收到的数据回发
      
      HAL_Delay(500);
      
      HAL_UART_Transmit(&huart1,(uint8_t *)0xFF,1,1000);	//发送一个字节
      
      HAL_Delay(500);
      
      HAL_UART_Transmit(&huart1,str,6,1000);				//发送字符数组

	  HAL_Delay(500);

      HAL_UART_Transmit(&huart1,(uint8_t *)"测试字符串\r\n",sizeof("测试字符串\r\n"),1000);

  }
  /* USER CODE END 3 */
}

3、串口实现 printf 打印

步骤:
1、引入头文件

#include "stdio.h"

2、在Keil中点击魔术棒设置,把这个选项勾选 Options for Target ->Target->Use MicroLIB

3.1、标准库重定向printf函数

int fputc(int ch, FILE *f)
{
	USART1_SendByte((uint8_t)ch);
	return ch;
}

//下面的代码可以省略
int fgetc(FILE *f)
{
         /* Loop until received a char */
         while(!(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == SET));
         /* Read a character from the USART and RETURN */
         return (USART_ReceiveData(USART1));
}

3.2、HAL库重定向printf函数

int fputc(int ch, FILE *f)
{
	HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 1000);
	return ch;
}
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: STM32F0xx_DFP是指针对STMicroelectronics公司的STM32F0系列微控制器设计的设备包装(Device Family Pack)。 STM32F0系列是STMicroelectronics公司的一款低功耗、高性能的32位微控制器系列产品。而Device Family Pack是为了方便开发者快速使用STM32F0系列产品而设计的一套软件和固件组合。 STM32F0xx_DFP中提供了一系列的软件工具和固件库,包括HAL(Hardware Abstraction Layer)库、CMSIS(Cortex Microcontroller Software Interface Standard)固件、外设驱动库等。开发者可以通过这些工具和库进行STM32F0系列微控制器的开发和编程。 使用STM32F0xx_DFP可以极大地简化开发流程,加快开发速度。开发者可以通过使用提供的库函数,轻松调用STM32F0系列微控制器的各种外设,如GPIO(通用输入输出)、USART(串行通信接口)、SPI(串行外设接口)等,从而实现各种功能。 另外,STM32F0xx_DFP还提供了许多示例代码,方便开发者学习和使用。开发者可以根据自己的需求选择相应的示例代码进行修改和扩展。 总之,STM32F0xx_DFP是STMicroelectronics公司专门为STM32F0系列微控制器设计的一套软件和固件组合,可以帮助开发者更快速、方便地进行STM32F0系列微控制器的开发和编程。 ### 回答2: STM32F0xx_DFP是指STMicroelectronics公司针对STM32F0系列微控制器开发的设备家族包库。DFP代表Device Family Pack,即设备家族包,它是一种软件包,包含了针对特定设备系列的库文件和驱动程序。 STM32F0系列微控制器是STMicroelectronics公司的一款低功耗、高性能的32位ARM Cortex-M0内核微控制器系列。这个系列的微控制器广泛应用于各种嵌入式系统和工业控制应用中。 STM32F0xx_DFP为STM32F0系列微控制器提供了丰富的外围设备库和驱动程序,使得开发者可以更方便地使用这些外设,并快速构建其应用程序。这个设备家族包库包含了各种设备外设的API函数和操作示例,例如通用定时器、UART串行通信接口、ADC模数转换器等等。开发者只需引用这些库文件,并按照API函数的调用方式编写代码,即可实现对特定外设的控制和配置。 除了外设库,STM32F0xx_DFP还提供了开发工具的支持,例如编译器和调试器。这些开发工具使得开发者可以在真实硬件上调试并测试他们的应用程序,加快开发周期。 总之,STM32F0xx_DFP是STM32F0系列微控制器的设备家族包库,提供了丰富的外围设备库和驱动程序,方便开发者使用STM32F0系列微控制器的外设,并快速构建嵌入式应用程序。 ### 回答3: STM32F0xx_DFP是指STM32F0系列微控制器的设备外设包(Device Family Pack)。在STM32F0系列微控制器的开发中,需要使用一些特定的外设驱动和软件库,而这些外设驱动和软件库通常被打包成一个软件包,即STM32F0xx_DFP。 STM32F0xx_DFP中包含了一系列针对STM32F0系列微控制器的外设驱动和软件库,包括GPIO(通用输入输出)外设驱动、USART(通用同步/异步串行接口)外设驱动、SPI(串行外设接口)外设驱动等等。这些外设驱动和软件库提供了封装好的接口和函数,方便开发者们在应用程序中使用和控制这些外设。同时,STM32F0xx_DFP还包含一些开发工具和示例代码,帮助开发者们更加高效地进行开发。 使用STM32F0xx_DFP可以大大简化STM32F0系列微控制器开发的过程,开发者们可以直接调用外设驱动和软件库提供的函数,而不需要从头编写驱动程序。这样可以节省开发时间,并且减少错误的可能性。此外,STM32F0xx_DFP还提供了丰富的示例代码,开发者们可以参考这些示例代码来学习和掌握如何使用不同的外设。 总的来说,STM32F0xx_DFP是一个方便、实用的开发工具,它为STM32F0系列微控制器的开发者们提供了丰富的外设驱动和软件库,简化了开发过程,提高了开发效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Geek@Yang

码字不易,来点鼓励~~~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值