四、stm32-USART串口通讯(重定向、接发通信、控制LED亮灭)

2023-10-28 16:30

本文主要是介绍四、stm32-USART串口通讯(重定向、接发通信、控制LED亮灭),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 一、固件库模板
  • 二、准备资料
  • 三、STM32串口通讯
    • 1.STM32的USART 简介
    • 2. USART 功能框图
      • 2.1 数据寄存器
      • 2.2 控制器
      • 2.3 发送器
      • 2.4 接收器
      • 2.5 小数波特率生成
    • 3 校验控制
      • 3.1 中断控制
    • 4 USART 初始化结构体详解
  • 四、USART1 接发通信实验
    • 1.硬件设计
    • 2.软件设计
      • 2.1 打开工程 (复制点亮LED工程)
      • 2.1 打开工程
      • 2.2 编写代码
        • USART.c 初始化
        • 2.2.1 重定向
          • USART.c
          • USART.h
        • 2.2.2 接发通信
          • USART.c
          • USART.h
      • led.c(同点灯文件)
      • led.h
      • main.c
    • 3. 编译
    • 4.选择烧录工具并配置MDK
    • 5. 成品
    • 乱码问题
    • 1、重定向
    • 2、接发通信
    • 3、控制LED灯
  • 工程链接

一、固件库模板

见博客:stm32f103c8t6新建固件库模板(可自取)

二、准备资料

  1. 固件库模板
  2. MDK5开发环境
  3. UART串口协议
  4. stm32中断概念
  5. 利用固件库模板点灯工程(下面第三行,手动狗头)

实验程序已经发布到百度网盘,本文末有链接可以自取

串口协议查看这篇博客USART串口协议

stm32中断概念STM32中断应用概括

一、利用固件库模板点灯(附模板及案例程序)

三、STM32串口通讯

1.STM32的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,可实现高速数据通信。

USART 在 STM32 应用最多莫过于“打印”程序信息,一般在硬件设计时都会预留一个 USART
通信接口连接电脑,用于在调试程序是可以把一些调试信息“打印”在电脑端的串口调试助手工
具上,从而了解程序运行是否正确、如果出错哪具体哪里出错等等

2. USART 功能框图

USART 的功能框图包含了 USART 最核心内容,掌握了功能框图,对 USART 就有一个整体的把握,在编程时就思路就非常清晰。 USART 功能框图见图 USART 功能框图 。

在这里插入图片描述
功能引脚

  • TX:发送数据输出引脚。
  • RX:接收数据输入引脚。
  • SW_RX:数据接收引脚,只用于单线和智能卡模式,属于内部引脚,没有具体外部引脚。
  • nRTS:请求以发送 (Request To Send), n 表示低电平有效。如果使能 RTS 流控制,当 USART 接收器准备好接收新数据时就会将 nRTS 变成低电平;当接收寄存器已满时, nRTS 将被设置为高电平。该引脚只适用于硬件流控制。
  • nCTS:清除以发送 (Clear To Send), n 表示低电平有效。如果使能 CTS 流控制,发送器在发送下一帧数据之前会检测 nCTS 引脚,如果为低电平,表示可以发送数据,如果为高电平则在发送完当前数据帧之后停止发送。该引脚只适用于硬件流控制。
  • SCLK:发送器时钟输出引脚。这个引脚仅适用于同步模式。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
STM32F103C8T6 系统控制器有三个 USART,其中 USART1 和时钟来源于 APB2 总线时钟,其最大频率为 72MHz,其他两个的时钟来源于 APB1 总线时钟,其最大频率为 36MHz。

2.1 数据寄存器

USART 数据寄存器 (USART_DR) 只有低 9 位有效,并且第 9 位数据是否有效要取决于 USART控制寄存器 1(USART_CR1) 的 M 位设置,当 M 位为 0 时表示 8 位数据字长,当 M 位为 1 表示 9位数据字长,我们一般使用 8 位数据字长。
USART_DR 包含了已发送的数据或者接收到的数据。 USART_DR 实际是包含了两个寄存器,一个专门用于发送的可写 TDR,一个专门用于接收的可读 RDR。当进行发送操作时,往 USART_DR写入数据会自动存储在 TDR 内;当进行读取操作时,向 USART_DR 读取数据会自动提取 RDR
数据。
TDR 和 RDR 都是介于系统总线和移位寄存器之间。串行通信是一个位一个位传输的,发送时把TDR 内容转移到发送移位寄存器,然后把移位寄存器数据每一位发送出去,接收时把接收到的每一位顺序保存在接收移位寄存器内然后才转移到 RDR。
USART 支持 DMA 传输,可以实现高速数据传输,具体 DMA 使用将在 DMA 章节讲解。

2.2 控制器

USART 有专门控制发送的发送器、控制接收的接收器,还有唤醒单元、中断控制等等。使用USART 之前需要向USART_CR1 寄存器的 UE 位置 1 使能 USART, UE 位用来开启供给给串口的时钟。
发送或者接收数据字长可选 8 位或 9 位,由 USART_CR1的 M 位控制。

2.3 发送器

当 USART_CR1 寄存器的发送使能位 TE 置 1 时,启动数据发送,发送移位寄存器的数据会在 TX引脚输出,低位在前,高位在后。如果是同步模式 SCLK 也输出时钟信号。
一个字符帧发送需要三个部分:起始位 + 数据帧 + 停止位。起始位是一个位周期的低电平,位周期就是每一位占用的时间;数据帧就是我们要发送的 8 位或 9 位数据,数据是从最低位开始传输的;停止位是一定时间周期的高电平。
停止位时间长短是可以通过 USART 控制寄存器 2(USART_CR2) 的 STOP[1:0] 位控制,可选 0.5个、 1 个、 1.5 个和 2 个停止位。默认使用 1 个停止位。 2 个停止位适用于正常 USART 模式、单线模式和调制解调器模式。 0.5 个和 1.5 个停止位用于智能卡模式。
当选择 8 位字长,使用 1 个停止位时,具体发送字符时序图见图字符发送时序图 。
在这里插入图片描述

当发送使能位 TE 置 1 之后,发送器开始会先发送一个空闲帧 (一个数据帧长度的高电平),接下来就可以往 USART_DR 寄存器写入要发送的数据。在写入最后一个数据后,需要等待 USART 状态寄存器 (USART_SR) 的 TC 位为 1,表示数据传输完成,如果 USART_CR1 寄存器的 TCIE 位置为1,将产生中断。
在发送数据时,编程的时候有几个比较重要的标志位我们来总结下。
在这里插入图片描述

2.4 接收器

如果将 USART_CR1 寄存器的 RE 位置 1,使能 USART 接收,使得接收器在 RX 线开始搜索起始位。在确定到起始位后就根据 RX 线电平状态把数据存放在接收移位寄存器内。接收完成后就把接收移位寄存器数据移到 RDR 内,并把 USART_SR 寄存器的 RXNE 位 置1,同时如果USART_CR2 寄存器的 RXNEIE 置 1 的话可以产生中断。
在接收数据时,编程的时候有几个比较重要的标志位我们来总结下。

名称描述
RE接收使能
RXNE读数据寄存器非空
RXNEIE接收完成中断使能

2.5 小数波特率生成

波特率指数据信号对载波的调制速率,它用单位时间内载波调制状态改变次数来表示,单位为波特。比特率指单位时间内传输的比特数,单位bit/s(bps)。对于 USART 波特率与比特率相等,以后不区分这两个概念。波特率越大,传输速率越快。
USART 的发送器和接收器使用相同的波特率。计算公式如下:
在这里插入图片描述
其中, fPLCK 为 USART 时钟, USARTDIV 是一个存放在波特率寄存器 (USART_BRR) 的一个无符号定点数。其中 DIV_Mantissa[11:0] 位定义 USARTDIV 的整数部分,DIV_Fraction[3:0] 位定义USARTDIV 的小数部分。

例如: DIV_Mantissa=24(0x18), DIV_Fraction=10(0x0A),此时 USART_BRR 值为 0x18A;那么 USARTDIV 的小数位 10/16=0.625;整数位 24,最终 USARTDIV 的值为 24.625。如果知道 USARTDIV 值为 27.68,那么 DIV_Fraction=16*0.68=10.88,最接近的正整数为 11,所以DIV_Fraction[3:0] 为 0xB; DIV_Mantissa= 整数 (27.68)=27,即为 0x1B。波特率的常用值有 2400、 9600、 19200、 115200。下面以实例讲解如何设定寄存器值得到波特率的值。

我们知道 USART1 使用 APB2 总线时钟,最高可达 72MHz,其他 USART 的最高频率为 36MHz。我们选取 USART1 作为实例讲解,即fPLCK=72MHz。为得到 115200bps 的波特率,此时:

115200 =72000000/(16 ∗ USARTDIV)

解得 USARTDIV=39.0625,可算得 DIV_Fraction=0.0625*16=1=0x01, DIV_Mantissa=39=0x27,即应该设置 USART_BRR 的值为 0x271。

3 校验控制

STM32F103 系列控制器 USART 支持奇偶校验。当使用校验位时,串口传输的长度将是 8 位的数
据帧加上 1 位的校验位总共 9 位,此时 USART_CR1 寄存器的 M 位需要设置为 1,即 9 数据位。将 USART_CR1 寄存器的 PCE 位置 1 就可以启动奇偶校验控制,奇偶校验由硬件自动完成。启动了奇偶校验控制之后,在发送数据帧时会自动添加校验位,接收数据时自动验证校验位。接收数据时如果出现奇偶校验位验证失败,会见 USART_SR 寄存器的 PE 位置 1,并可以产生奇偶校验中断。
使能了奇偶校验控制后,每个字符帧的格式将变成:起始位 + 数据帧 + 校验位 + 停止位。

3.1 中断控制

USART 有多个中断请求事件,具体见表 USART 中断请求 。
在这里插入图片描述

4 USART 初始化结构体详解

标准库函数对每个外设都建立了一个初始化结构体,比如 USART_InitTypeDef,结构体成员用于
设置外设工作参数,并由外设初始化配置函数,比如 USART_Init() 调用,这些设定参数将会设置
外设相应的寄存器,达到配置外设工作环境的目的。
初始化结构体和初始化库函数配合使用是标准库精髓所在,理解了初始化结构体每个成员意义基本上就可以对该外设运用自如了。初始化结构体定义在 stm32f10x_usart.h 文件中,初始化库函数定义在 stm32f10x_usart.c 文件中,编程时我们可以结这两个文件内注释使用。
USART 初始化结构体

typedef struct {
uint32_t USART_BaudRate; // 波特率
uint16_t USART_WordLength; // 字长
uint16_t USART_StopBits; // 停止位
uint16_t USART_Parity; // 校验位
uint16_t USART_Mode; // USART 模式
uint16_t USART_HardwareFlowControl; // 硬件流控制
}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 时钟初始化结构体
typedef struct {
uint16_t USART_Clock; // 时钟使能控制
uint16_t USART_CPOL; // 时钟极性
uint16_t USART_CPHA; // 时钟相位
uint16_t USART_LastBit; // 最尾位时钟脉冲
} 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 位的值。

四、USART1 接发通信实验

USART 只需两根信号线即可完成双向通信,对硬件要求低,使得很多模块都预留 USART 接口来实现与其他模块或者控制器进行数据传输,比如 GSM 模块, WIFI 模块、蓝牙模块等,以后都会在实验中提及,在硬件设计时,注意还需要一根“共地线”。
我们经常使用 USART 来实现控制器与电脑之间的数据传输。这使得我们调试程序非常方便,比如我们可以把一些变量的值、函数的返回值、寄存器标志位等等通过 USART 发送到串口调试助手,这样我们可以非常清楚程序的运行状态,当我们正式发布程序时再把这些调试信息去除即可。
我们不仅仅可以将数据发送到串口调试助手,我们还可以在串口调试助手发送数据给控制器,控制器程序根据接收到的数据进行下一步工作。

1.硬件设计

为利用 USART 实现开发板与电脑通信,需要用到一个 USB 转 USART 的 IC,我们选择CH340G芯片来实现这个功能, CH340G 是一个 USB 总线的转接芯片,实现 USB 转 USART、 USB 转 lrDA红外或者 USB 转打印机接口,我们使用其 USB 转 USART 功能。

连接引脚
CH340的TXD-----USART1的RX引脚相连(c8t6 的PA10)
CH340的RXD-----USART1的TX引脚相连(c8t6 的PA9)

2.软件设计

  1. 使能 RX 和 TX 引脚 GPIO 时钟和 USART 时钟;

  2. 初始化 GPIO,并将 GPIO 复用到 USART 上;

  3. 配置 USART 参数;

  4. 配置中断控制器并使能 USART 接收中断;

  5. 使能 USART;

  6. 在 USART 接收中断服务函数实现数据接收和发送。

2.1 打开工程 (复制点亮LED工程)

2.1 打开工程

在这里插入图片描述

2.2 编写代码

重定向和USART1初始化已经完成打开usart.c文件
在这里插入图片描述

USART.c 初始化
void uart1_init(u32 bound) {//GPIO端口设置GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	//使能USART1,GPIOA时钟//USART1_TX   GPIOA.9GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9//USART1_RX	  GPIOA.10初始化GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10//Usart1 NVIC 配置NVIC_PriorityGroupConfig(macNVIC_PriorityGroup_x);NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器//USART 初始化设置USART_InitStructure.USART_BaudRate = bound;//串口波特率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); //初始化串口1USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);//使能串口总线空闲中断USART_Cmd(USART1, ENABLE);
}

其中 中断在之前STM32中断应用概括已经讲过,不清楚的可以继续查看。

2.2.1 重定向
USART.c
#if Open_redirection
#if MicroLIB
/*重定向c库函数printf到串口,重定向后可以使用printf函数*/
int fputc(int ch,FILE  *f){/* 发送一个字节数据到串口*/USART_SendData(USARTx,(uint8_t)ch);/*等待发送完毕*/while(USART_GetFlagStatus(USARTx,USART_FLAG_TC)==RESET);return ch;
}/*重定向c库函数scanf到串口,重写后可使用scanf、getchar等函数*/
int fgetc(FILE *f){/*等待串口输入数据*/while(USART_GetFlagStatus(USARTx,USART_FLAG_RXNE)==RESET);return (int)USART_ReceiveData(USARTx);
}
#else
//重定义fputc函数
int fputc(int ch, FILE *f)
{while((USARTx->SR&0X40)==0);//循环发送,直到发送完毕USARTx->DR = (u8) ch;return ch;
}
//重定向scanf,
int fgetc(FILE *f){//  读数据寄存器非空,中断产生,RXNE对USART_DR的读操作可以将改为清零。//	0:数据没有收到//	1:收到数据,可以读出while (!(USART1->SR & USART_FLAG_RXNE));return ((int)(USART1->DR & 0x1FF));
}#endif
#endif
USART.h
#define Open_redirection  1   //是否开启printf重定向
#define MicroLIB  				1		//是否开启MicroLIB
#define USARTx						USART1		//重定向的UART口

定义#define MicroLIB 1 这个宏为了使用MicroLIB,
在这里插入图片描述
否则将使用printf的c文件都必须引入#include “stdio.h”

2.2.2 接发通信
USART.c
struct  STRUCT_USARTx_Fram strUSART_Fram_Record = { 0 };//使用接收结构体
void USART1_IRQHandler(void)                	//串口1中断服务程序
{u8 Res;if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾){Res =USART_ReceiveData(USART1);	//读取接收到的数据//USART_SendData(USART1,Res);if ( strUSART_Fram_Record .InfBit .FramLength < ( RX_BUF_MAX_LEN - 1 ) )                       //预留1个字节写结束符strUSART_Fram_Record .Data_RX_BUF [ strUSART_Fram_Record .InfBit .FramLength ++ ]  = Res;}if ( USART_GetITStatus( USART1, USART_IT_IDLE ) == SET )   //数据帧接收完毕{strUSART_Fram_Record .InfBit .FramFinishFlag = 1;Res = USART_ReceiveData( USART1 );}
}
USART.h
//在gun或者定义#pragma anon_unions的情况下,才支持匿名联合
#if defined ( __CC_ARM   )
#pragma anon_unions
#endif/******************************* 宏定义 ***************************/
#define            macNVIC_PriorityGroup_x                     NVIC_PriorityGroup_2#define USART1_REC_LEN  		200  	//定义最大接收字节数 200#define Open_redirection  		1   	//是否开启printf重定向
#define MicroLIB  				1		//是否开启MicroLIB
#define USARTx					USART1	//重定向的UART口#define EN_USART1_RX 			1		//使能(1)/禁止(0)串口1接收#define RX_BUF_MAX_LEN     1024   /********************************************************************************
*    同USART_RX_STA接收状态寄存器bit15,	  接收完成标志bit14,	  接收到0x0dbit13~0,	接收到的有效字节数目
********************************************************************************/
extern struct  STRUCT_USARTx_Fram                                  //串口数据帧的处理结构体
{//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;//如果想串口中断接收,请不要注释以下宏定义
void uart1_init(u32 bound);/********************************** 函数声明 ***************************************/
void USART_printf   ( USART_TypeDef * pUSARTx, char * Data, ... );
void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch);
void Usart_SendString( USART_TypeDef * pUSARTx, char *str);
void Usart_SendHalfWord( USART_TypeDef * pUSARTx, uint16_t ch);

led.c(同点灯文件)

stm32f103c8t6自带一个led灯,使用PC13引脚就行了,

切记尽量避免使用PB3、PB4,具体看stm32f103c8t6使用PB3和PB4做普通GPIO使用时发现异常

#include "led.h"	//绑定led.hvoid LED_GPIO_Config(void) {GPIO_InitTypeDef GPIO_InitStruct; //初始化参数结构体指针,结构体类型为 GPIO_InitTypeDef。//开启RCC时钟RCC_APB2PeriphClockCmd(LED_G_GPIO_CLK, ENABLE);//配置初始化,推挽输出方式和LED_G_GPIO_PIN管脚、赫兹GPIO_InitStruct.GPIO_Pin = LED_G_GPIO_PIN;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;//GPIO口初始化GPIO_Init(LED_G_GPIO_PORT, &GPIO_InitStruct);
}

led.h

#ifndef __LED_H_
#define __LED_H_#include "stm32f10x.h"
#include "sys.h"#define LED_G_GPIO_PIN         GPIO_Pin_13
#define LED_G_GPIO_PORT        GPIOC
#define LED_G_GPIO_CLK         RCC_APB2Periph_GPIOC
//使用位带操作来实现操作某个IO口的 1个位,由sys.h实现
#define LED 				   PCout(13)void LED_GPIO_Config(void); //函数定义#endif

main.c

#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "stm32f10x.h"
#include "led.h"		//引用led文件int main()
{/*********************************************************************************    Delay_init();				  //本实验使用的是SysTick时钟*    CPU_TS_TmrInit();      //已经使能宏,不需要初始化*    uart1_init(115200);	 	//串口初始化为115200,需要在usart.h中使能*    uart3_init(115200);	 	//串口初始化为115200********************************************************************************//* 初始化 */uart1_init(115200);		//usart初始化,波特率为115200,中断优先为NVIC_PriorityGroup_2LED_GPIO_Config();		//初始化led使用的GPIO口printf("--USART串口通讯--");while (1){if(strUSART_Fram_Record .InfBit .FramFinishFlag)  	//如果串口接收到数据,并结束{//增加一个结束符。strUSART_Fram_Record .Data_RX_BUF [ strUSART_Fram_Record .InfBit .FramLength ]  = '\0';//将USART1接收到的东西全部打印出来,接收到的保存在这个数组里,再通过串口1发送出来,这样就能看到,我们发送的指令的响应,是否出错,printf( "\r\n%s\r\n", strUSART_Fram_Record .Data_RX_BUF );if(strstr ( strUSART_Fram_Record .Data_RX_BUF, "LED=1" )){PCout(13) = 1; //PC口13引脚输出,高电平printf("LED灭");Delay_ms(500);		//已经在delay.h中初始化}else	if(strstr ( strUSART_Fram_Record .Data_RX_BUF, "LED=0" )){PCout(13) = 0; //PC口13引脚输出,低电平printf("LED亮");Delay_ms(500);}strUSART_Fram_Record .InfBit .FramLength = 0;                             //清除接收标志strUSART_Fram_Record.InfBit.FramFinishFlag = 0;}}

3. 编译

在这里插入图片描述

4.选择烧录工具并配置MDK

本文选择的是ST_Link烧录工具
在这里插入图片描述
在这里插入图片描述
如果没有ID号看博客:ST-Link V2烧录问题(已解决)
在这里插入图片描述
在这里插入图片描述

5. 成品

乱码问题

查看USART串口printf重定向中文乱码这篇博客

1、重定向

在这里插入图片描述

2、接发通信

在这里插入图片描述

3、控制LED灯

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

在这里插入图片描述

工程链接

链接:https://pan.baidu.com/s/1MwaPFX2reHsimbbGzwFSlQ 提取码:0000

这篇关于四、stm32-USART串口通讯(重定向、接发通信、控制LED亮灭)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/294488

相关文章

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

【STM32】SPI通信-软件与硬件读写SPI

SPI通信-软件与硬件读写SPI 软件SPI一、SPI通信协议1、SPI通信2、硬件电路3、移位示意图4、SPI时序基本单元(1)开始通信和结束通信(2)模式0---用的最多(3)模式1(4)模式2(5)模式3 5、SPI时序(1)写使能(2)指定地址写(3)指定地址读 二、W25Q64模块介绍1、W25Q64简介2、硬件电路3、W25Q64框图4、Flash操作注意事项软件SPI读写W2

vue2 组件通信

props + emits props:用于接收父组件传递给子组件的数据。可以定义期望从父组件接收的数据结构和类型。‘子组件不可更改该数据’emits:用于定义组件可以向父组件发出的事件。这允许父组件监听子组件的事件并作出响应。(比如数据更新) props检查属性 属性名类型描述默认值typeFunction指定 prop 应该是什么类型,如 String, Number, Boolean,

STM32(十一):ADC数模转换器实验

AD单通道: 1.RCC开启GPIO和ADC时钟。配置ADCCLK分频器。 2.配置GPIO,把GPIO配置成模拟输入的模式。 3.配置多路开关,把左面通道接入到右面规则组列表里。 4.配置ADC转换器, 包括AD转换器和AD数据寄存器。单次转换,连续转换;扫描、非扫描;有几个通道,触发源是什么,数据对齐是左对齐还是右对齐。 5.ADC_CMD 开启ADC。 void RCC_AD

STM32内部闪存FLASH(内部ROM)、IAP

1 FLASH简介  1 利用程序存储器的剩余空间来保存掉电不丢失的用户数据 2 通过在程序中编程(IAP)实现程序的自我更新 (OTA) 3在线编程(ICP把整个程序都更新掉) 1 系统的Bootloader写死了,只能用串口下载到指定的位置,启动方式也不方便需要配置BOOT引脚触发启动  4 IAP(自己写的Bootloader,实现程序升级) 1 比如蓝牙转串口,

FreeRTOS-基本介绍和移植STM32

FreeRTOS-基本介绍和STM32移植 一、裸机开发和操作系统开发介绍二、任务调度和任务状态介绍2.1 任务调度2.1.1 抢占式调度2.1.2 时间片调度 2.2 任务状态 三、FreeRTOS源码和移植STM323.1 FreeRTOS源码3.2 FreeRTOS移植STM323.2.1 代码移植3.2.2 时钟中断配置 一、裸机开发和操作系统开发介绍 裸机:前后台系

Java Websocket实例【服务端与客户端实现全双工通讯】

Java Websocket实例【服务端与客户端实现全双工通讯】 现很多网站为了实现即时通讯,所用的技术都是轮询(polling)。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发 出HTTP request,然后由服务器返回最新的数据给客服端的浏览器。这种传统的HTTP request 的模式带来很明显的缺点 – 浏 览器需要不断的向服务器发出请求,然而HTTP

寻迹模块TCRT5000的应用原理和功能实现(基于STM32)

目录 概述 1 认识TCRT5000 1.1 模块介绍 1.2 电气特性 2 系统应用 2.1 系统架构 2.2 STM32Cube创建工程 3 功能实现 3.1 代码实现 3.2 源代码文件 4 功能测试 4.1 检测黑线状态 4.2 未检测黑线状态 概述 本文主要介绍TCRT5000模块的使用原理,包括该模块的硬件实现方式,电路实现原理,还使用STM32类

控制反转 的种类

之前对控制反转的定义和解释都不是很清晰。最近翻书发现在《Pro Spring 5》(免费电子版在文章最后)有一段非常不错的解释。记录一下,有道翻译贴出来方便查看。如有请直接跳过中文,看后面的原文。 控制反转的类型 控制反转的类型您可能想知道为什么有两种类型的IoC,以及为什么这些类型被进一步划分为不同的实现。这个问题似乎没有明确的答案;当然,不同的类型提供了一定程度的灵活性,但