零死角玩转stm32中级篇1-调试必备串口(UART)

news/2024/12/16 5:58:41/

本篇博文目录:

      • 一.通信相关概念
        • 1.通信的三种分类
          • (1) 串行通信和并行通信
          • (2) 同步传输和异步传输
          • (3) 半双工,全双工,单工
        • 2.常见的通信方式及其分类
      • 二.串口通信相关概念
        • 1.串口通信
        • 2.串口通信的几个比较重要的参数
        • 3.串口的硬件接线
          • (1) DB9和DB25
          • (2) 交叉线和直通线
          • (3) USB转串口
          • (4) RS232和RS485
        • 4.STM32串口工作过程分析
          • (1) 波特率控制
          • (2) 收发控制
          • (3) 数据存储转移部分
      • 三.STM32串口通信发送,接收和重定向代码(标准库版本)

一.通信相关概念

1.通信的三种分类

通信按数据传输方式进行分类,可以分为串行通信和并行通信;按通信机制方式进行分类,可以分为同步传输和异步传输。按照数据传输方向和能力进行分类,可以分为单工,半双工和全双工。

(1) 串行通信和并行通信

串行通信:数据是按照单个比特一个接一个地传输的,需要在数据位之间插入控制位,以确保数据的传输正确。串行通信的优点是使用较少的导线,在长距离传输时更稳定,但传输速度相对较慢。

在这里插入图片描述

并行通信:数据是同时传输多个比特,需要更多的导线来实现。并行通信的优点是传输速度快,但成本高且容易产生电源噪声等干扰。

在这里插入图片描述

备注:图片来源于https://www.eefocus.com/e/526547.html

(2) 同步传输和异步传输

同步通信:发送方和接收方使用共同的时钟信号进行数据传输和控制,这种方式的数据传输速度较快,但需要在发送和接收端维护相同的时钟,并且相对复杂。

在这里插入图片描述

异步通信:在数据传输过程中不需要任何时钟同步信号,而是在数据之间通过特定的协议进行数据同步。这使得异步通信更加简单易用,但传输速率相对较慢,数据传输可靠性也较差。

在这里插入图片描述

(3) 半双工,全双工,单工

单工(Simplex):单工通信只能在一个方向上进行信息传输,即信息只能从一个方向的发送器传送到另一个方向的接收器,无法进行双向传输。例如,电视广播和无线电广播就是一种单向通信,只能通过广播信号发送信息,而无法接收信息反馈。

在这里插入图片描述

半双工(Half Duplex):半双工通信只能在同一时间内进行单向传输,即信息只能从一个方向的发送器传送到另一个方向的接收器,不能同时进行双向传输。例如,对讲机就是一个典型的半双工通信设备,同一时间内只能有一方进行发言,另一方只能听取,不能同时说话和听取。

在这里插入图片描述

全双工(Full Duplex):全双工通信可以在同一时间内进行双向传输,即信息可以同时从两个方向进行传输,例如电话通信、网络通信等。在全双工通信中,每个通信实体都拥有一个发送器和一个接收器,能够在不影响对方通信的情况下进行同时的双向数据传输。

在这里插入图片描述

备注:图片来源于https://zhuanlan.zhihu.com/p/361655746

2.常见的通信方式及其分类

  • 同步/异步+串行/并行
类型描述通信协议数据传输速率传输距离应用
同步串行通信发送方与接收方在时钟方面保持同步,逐位地按照固定的时间间隔同时发送或接收数据SPI、I2C、Microwire等Mbps通常不超过一个设备的长度短距离通信、芯片与芯片之间的通信
异步串行通信发送方和接收方不需要保持时钟同步,每个数据字节之间有一个起始位和一个或多个停止位,实现了帧同步UART、RS-232等Kbps通常不超过几十米数据采集、远程控制、较短距离通信
同步并行通信发送方和接收方在时钟上保持同步,同时传输多个数据位ISA总线Mbps通常不超过一个设备的长度高速数据传输
异步并行通信发送方和接收方不需要时钟同步,在特定情况下可以同时传送多个数据位USB、PCI总线等Gbps通常不超过几米高速数据传输、外部存储设备
  • 其他通信:
类型描述通信协议数据传输速率传输距离应用
USB通信通过USB接口连接各种外部设备,支持异步传输、同步传输和流传输等多种工作模式USB 1.x/2.x/3.xGbps通常不超过几米外部设备连接、高速数据传输
CAN通信用于工业自动化和汽车电子领域的数据总线标准,支持多个节点之间的数据传输CAN 2.0BMbps数百米至数千米工业自动化、汽车电子
Ethernet通信基于帧格式的网络协议,用于互联网和局域网通信,支持快速、可靠的数据传输IEEE 802.3Gbps通常不超过几百米网络通信、数据中心、局域网
WiFi通信基于无线局域网技术的通信方式,通过无线网络实现设备之间的数据传输IEEE 802.11Gbps通常不超过几十米移动设备、家庭网络、公共场所
Bluetooth通信短距离、低功耗的无线通信技术,主要用于移动设备之间的数据传输Bluetooth 4.0/5.0Mbps通常不超过几十米移动设备、家庭娱乐、智能家居

二.串口通信相关概念

1.串口通信

① 串口通信是指通过串行通信接口来进行数据传输的一种通信方式。串口通信有两种基础协议:同步协议和异步协议,其中异步协议广泛应用于单片机开发中。
② 在异步协议中,通信双方的时钟并不需要进行同步,而是利用起始位和停止位来判断每一个字节的开始和结束。异步通信中最常用的协议是UART(Universal Asynchronous Receiver-Transmitter),UART只需要使用一根发送线和一根接收线即可完成单向或双向的串口通信。
③ 串口通信可以实现点对点和多点通信,实现简单,价格低廉,但数据传输速率较慢,一般采用的通信速率为115200bps以下。在单片机开发中,串口通信被广泛应用于与电脑之间的数据传输、与传感器之间的数据传输以及与其他单片机之间的数据传输等场景。(注意有时终线的是同步,没有时钟线的是异步,同步串行通信数据帧如下图所示 )

在这里插入图片描述

例如:MCU单片机给PC机发送一个字符 ‘A’,的通信过程大致如下:

  • 首先是硬件连接,只需要三根线分别是RXD,TXD和GND;需要注意的是MCU的RXD和PC的TXD进行连接,MCU的TXD和PC的RXD进行连接(这里的引脚是真实引脚,交叉线)。

在这里插入图片描述

  • MCU进行数据发送,只需要MCU的TXD和PC机的RXD进行工作,发送一个字符’A’的波形如下图所示,首先是起始位通常都是低电平,然后后面1~8(0 ~ 7)位为数据位,其中第八位(0 ~ 7 中的第7位)可能为奇偶校验位,看用户是否进行设置,在0 ~ 7 位中只有0和6是高电平,这里高电平就是我们发送的有效数据,将高电平对应位的二进制转换成十进制2^0 + 2^6 = 1+64 = 65 会发现这里的65正好对应ASCLL字符’A’, 接着最后一位为停止位(通常为高电平)表示本次数据发送结束。

在这里插入图片描述

在这里插入图片描述

  • 在首次进行串口通信的时候,我们常常会发现会出现乱码或数据接收不到的情况,这通常原因就是MCU和PC二者之间的串口参数配置不一致导致的,比如波特率,这里的波特率指的就是发送数据的速度,比如波特率9600表示1s钟发送9600个这样的数据。

在这里插入图片描述

  • 上面内容如果还不明白可以通过这个视频进行学习https://www.bilibili.com/video/BV1y34y147s5/,进一步了解串口通信

在这里插入图片描述

2.串口通信的几个比较重要的参数

串口通信的几个比较重要的参数包括:

  1. 波特率(Baud Rate):表示通信双方之间每秒传输的比特数,通常用bps(bits per second)来表示。波特率越高,数据传输速度越快,但同时也会增加误码率,降低传输可靠性。

  2. 数据位(Data Bits):表示每个字节中所包含的数据位数,常见的取值有5、6、7和8位。数据位的选择取决于数据所包含的信息量以及传输的精度要求。

  3. 停止位(Stop Bits):表示每个字节传输结束后,发送方在发送线上保持的电平状态,通常有1位和2位两种取值。停止位的作用是为了告诉接收方当前数据传输已经结束。

  4. 校验位(Parity):在数据传输过程中,加入一个校验位来判断数据是否正确传输。常见的校验方式有奇偶校验、偶校验、无校验等,其中奇偶校验最为常用。

以上参数需要双方进行协商确定,并在通信时保持一致,否则数据传输将会出现错误。在单片机开发中,常常使用的串口通信参数为波特率9600bps、8数据位、1停止位、无校验位。

3.串口的硬件接线

(1) DB9和DB25

串口线的接口标准通常有DB9和DB25两种,其中DB9有9根引脚,适用于较少信号的串口设备,而DB25有25根引脚,适用于需要传输大量信号的串口设备。在串口线的选择时,需要根据具体的设备类型和接口标准进行选择。同时,还需要注意串口线的长度和屏蔽效果,以确保数据传输的稳定性和可靠性。

  • DB9

DB9是一种常用的串口接口标准,也称作DE-9(D形9针),其中“D”指代连接器的外形类似于字母D。DB9接口共有9个引脚,分别为:

  1. DCD(Data Carrier Detect) - 数据载波检测
  2. RD(Data Receive) - 数据接收
  3. TD(Data Transmit) - 数据发送
  4. DTR(Data Terminal Ready) - 数据终端就绪
  5. GND(Signal Ground) - 路径接地
  6. DSR(Data Set Ready) - 数据集就绪
  7. RTS(Request To Send) - 请求发送
  8. CTS(Clear To Send) - 清除发送
  9. RI(Ring Indicator) - 响铃指示

DB9接口广泛应用于串口设备之间的通信,如串口打印机、调制解调器、路由器、终端设备等。在使用DB9接口时,需要注意接口针脚的正确连接和通信参数的正确设置,以确保数据传输的稳定和可靠。

在这里插入图片描述

  • DB25

DB25是一种串口接口标准,也称作DE-25(D形25针),其中“D”指代连接器的外形类似于字母D。DB25接口共有25个引脚,与DB9接口相比,其拥有更多的信号引脚,能够支持更复杂的通信方式。DB25接口的引脚定义如下:

1.protective ground(保护接地)
2.TxD(Data Transmit) - 数据发送
3.RxD(Data Receive) - 数据接收
4.RTS(Request To Send) - 请求发送
5.CTS(Clear To Send) - 清除发送
6.DSR(Data Set Ready) - 数据集就绪
7.Signal ground(Signal Ground) - 信号地
8.CD(Carrier Detect) - 载波检测
9.RI(Ring Indicator) - 响铃指示
10.交替行选通
11.设备选择1
12.设备选择2
13.设备选择3
14.设备选择4
15.线路就绪
16.时钟
17.端口就绪
18.暂停
19.申请握手
20.结束握手
21.数据线就绪1
22.数据线就绪2
23.数据线就绪3
24.数据线就绪4
25.保留

DB25接口广泛应用于串口设备之间的通信,如计算机、打印机、调制解调器、路由器、终端设备等。在使用DB25接口时,需要注意接口针脚的正确连接和通信参数的正确设置,以确保数据传输的稳定和可靠。

在这里插入图片描述

(2) 交叉线和直通线

串口的连接需要结合实际原理图来连接,看是采用的交叉线方式还是直通线方式,如果采用交叉线方式就把单片机的TXD与其他设备的RXD相连,RXD与TXD相连;如果采用的是直通线就把单片机的TXD与其他设备的TXD相连,RXD与RXD相连。

  • 交叉线

标准串口引脚2是RX,引脚3是TX,(即九针串口的2号引脚连接的是主控芯片的RXD引脚,3号引脚连接的是主控芯片的TXD引脚),如果单片机开发板的串口和电脑串口都是标准串口,则俩串口应该用交叉线连接。(单片机的TXD连接电脑的RXD;单片机的RXD连接串口的RXD)

  • 直通线

不过现实中直通线居多,为了配合直通线的使用,在画板的时候,把主控芯片的RXD引脚连接至串口的3脚(RXD实际是TXD),主控芯片的TXD引脚连接至串口的2脚(TXD实际是RXD),这样这个开发板上的串口就不是标准串口了,即2变成TX,3变成RX,和标准串口连接时当然应该使用直连线了。(单片机的TXD(实际是RXD)和电脑的TXD相连;单片机的RXD(实际是TXD)和电脑RXD相连)

在这里插入图片描述
备注:参考了这篇博文:https://new.qq.com/rain/a/20210527A01UNY00

(3) USB转串口

① USB转串口是指通过USB接口将计算机与串口设备进行连接的一种方式。由于现代笔记本电脑大多已经取消了串口接口,而很多应用场合仍需要使用串口设备进行通信,因此USB转串口逐渐成为了一种常见的解决方案。
② USB转串口一般需要使用专门的转换器,这种转换器内部会集成一个串口芯片和USB芯片,可以实现USB和串口之间的信号转换和协议转换。在使用时,用户只需要将USB转串口转换器插入计算机的USB接口上,就可以通过串口通信软件来访问串口设备进行数据传输。
③ 需要注意的是,不同的USB转串口转换器支持的串口标准可能不同,如RS232、TTL等,因此在选择转换器时需要确认其支持的串口标准是否符合自己的需求。同时,在使用USB转串口转换器时也需要特别注意其驱动程序是否已经安装,以及通信参数的设置是否正确。

在这里插入图片描述

(4) RS232和RS485
  • 串口通信采用的电平为TTL电平,这种电平输出的高电平最低为2.4V,低电平最高为0.4V,如果在传输的过程中受到干扰(静电),可能将某一个低电平变高,所以串口通信通常的距离很短,一般为1m之内。

在这里插入图片描述

在这里插入图片描述

  • 所以串口通信常用于MCU与MCU或MCP和PC之间进行通信

在这里插入图片描述

  • 为了提供通信的稳定性有了RS232和RS485通信,所谓的RS232通信指的是将TTL电平转换为RS232电平,这里的转换常用负逻辑,意思就是TTL的+5V转换为-12V,0V转换为12V这样就是-12V表示高电平,+12V表示低电平(二者之间可以分别进行转换),并且RS232的电平范围要比TTL电平大一些,从而提高通信的稳定。

在这里插入图片描述

在这里插入图片描述

  • RS232的通信距离可以达到15m,但是速率仅有20k,也就是19200的波特率

在这里插入图片描述

  • 针对一些工业环境或者对距离有更远的要求,RS232就力不从心了,所以这时就可以考虑采用RS485通信;RS485通信就是在MCU外加一个485转换芯片,RS485采用差分信号,传递的高低电平通过RS485_A和RS485_B线来传递,当RS485_A>RS485_B时为高电平,当RS485_A<RS485_B时为低电平。

在这里插入图片描述

在这里插入图片描述

  • 因为RS485采用差分信号,所以即使受到干扰也没有什么影响。

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

  • RS485传输距离可达1200米并且传输频率也远远高于RS232,可达50M

在这里插入图片描述

4.STM32串口工作过程分析

串口外设的架构图从下至上,我们看到串口外设主要由三个部分组成,分别是波特率的控制部分①、收发控制部分②及数据存储转移部分 ③。

在这里插入图片描述

(1) 波特率控制

波特率,即每秒传输的二进制位数,用 b/s (bps)表示,通过对时钟的控制可以改变波特率。在配置波特率时,我们向波特比率寄存器 USART_BRR 写入参数,修改了串口时钟的分频值USARTDIV 。 USART_BRR寄存器包括两部分,分别是DIV_Mantissa (USARTDIV 的整数部分)和DIVFraction (USARTDIV的小数)部分,最终,计算公式为USARTDIV=DIV_Mantissa+(DIVFraction/16)。USARTDIV 是对串口外设的时钟源进行分频的,对于USART1 ,由于它是挂载在 APB2 总线上的,所以它的时钟源为 fPCLK2 ;而 USART2、3 挂载在APB1 上,时钟源则为 fPCLK1 ,串口的时钟源经过 USARTDIV 分频后分别输出作为发送器时钟及接收器时钟 ,控制发送和接收的时序。

(2) 收发控制

围绕着发送器和接收器控制部分,有好多个寄存器:CR1、CR2、CR3、SR,即USART的三个控制寄存器 (Control Register)及一个 状态寄存器 (StatusRegister)。通过向寄存器写入各种控制参数 ,来控制发送和接收,如奇偶校验位,停止位等,还包括对USART中断的控制;串口的状态在任何时候都可以从状态寄存器中查询得到。

(3) 数据存储转移部分

收发控制器根据我们的寄存器配置,对 数据存储转移部分 的 移位寄存器 进行控制。当我们需要发送数据时,内核或 DMA 外设(一种数据传输方式)把数据从内存(变量)写入到 发送数据寄存器 TDR 后, 发送控制器 将适时地自动把数据从 TDR 加载到 发送移位寄存器 ,然后通过 串口线 Tx ,把数据 一位一位 地发送出去,在数据从 TDR 转移到 移位寄存器 时,会产生 发送寄存器TDR 已空事件 TXE ,当数据从 移位寄存器 全部发送出去时,会产生数据 发送完成事件 TC ,这些事件可以在 状态寄存器 中查询到。而 接收数据 则是一个 逆过程 ,数据从 串口线 Rx 一位一位地输入到 接收移位寄存器 ,然后自动地转移到 接收数据寄存器 RDR ,最后用内核指令或 DMA读取到内存(变量)中。

三.STM32串口通信发送,接收和重定向代码(标准库版本)

  • usart1.c
#include "usart1.h"
#include <stdbool.h>
#if USART1_RX_EN
uint8_t USART1_RX_Buffer[USART1_RX_MAX] = {0};// 接收缓存
uint8_t USART1_RX_Index = 0; // 接收下标
uint8_t USART1_RX_OverFlag = 0;// 接收完成
#endif // 初始化中断优先级
static void NVIC_Configuration(void){NVIC_InitTypeDef NVIC_InitStructure;// 中断控制器NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 配置优先分组// 中断源NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;// 抢占优先级NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;// 子优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;// 使能中断NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;// 初始化NVICNVIC_Init(&NVIC_InitStructure);}// 初始化串口
void USART1_Config(){// 初始化GPIO_InitTypeDef和USART_InitTypeDef结构体对象GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;// 开启USART1和GPIOA的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);// 初始化GPIO9(PA9作为TXD)GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;// 复用推挽输出模式GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;// 初始化的引脚PA9GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;// 设置GPIO的速率为50MHzGPIO_Init(GPIOA, &GPIO_InitStructure);// 初始化GPIO// 初始化GPIO10(PA10作为RXD)GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//初始化的引脚PA10GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;// 浮空输入模式GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;// 设置GPIO的速率为50MHzGPIO_Init(GPIOA, &GPIO_InitStructure);// 初始化GPIO// 初始化USART1USART_InitStructure.USART_BaudRate = 115200;// 波特率USART_InitStructure.USART_WordLength = USART_WordLength_8b;// 数据位USART_InitStructure.USART_StopBits = USART_StopBits_1;// 停止位USART_InitStructure.USART_Parity = USART_Parity_No ;// 奇偶校验位0// 无硬件流模式:在无硬件流控制模式下,数据通信没有任何限制,也就是说,当接收缓冲区溢出时会发生数据丢失USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;// 指定硬件流模式为无硬件流模式USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;// 工作模式:同时启用串口的发送和接收模式USART_Init(USART1, &USART_InitStructure);// 初始化串口USART_Cmd(USART1, ENABLE);// 串口使能#if USART1_RX_EN// 使能串口接收中断USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);// 接收数据不为空的中断// 串口中断优先级NVIC_Configuration();
#endif}/*****************  发送一个字节 **********************/
void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch)
{/* 发送一个字节数据到USART */USART_SendData(pUSARTx,ch);/* 等待发送数据寄存器为空 */while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);	
}/****************** 发送8位的数组 ************************/
void Usart_SendArray( USART_TypeDef * pUSARTx, uint8_t *array, uint16_t num)
{uint8_t i;for(i=0; i<num; i++){/* 发送一个字节数据到USART */Usart_SendByte(pUSARTx,array[i]);	}/* 等待发送完成 */while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET);
}/*****************  发送字符串 **********************/
void Usart_SendString( USART_TypeDef * pUSARTx, char *str)
{unsigned int k=0;do {Usart_SendByte( pUSARTx, *(str + k) );k++;} while(*(str + k)!='\0');/* 等待发送完成 */while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET){}
}/*****************  发送一个16位数 **********************/
void Usart_SendHalfWord( USART_TypeDef * pUSARTx, uint16_t ch)
{uint8_t temp_h, temp_l;/* 取出高八位 */temp_h = (ch&0XFF00)>>8;/* 取出低八位 */temp_l = ch&0XFF;/* 发送高八位 */USART_SendData(pUSARTx,temp_h);	while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);/* 发送低八位 */USART_SendData(pUSARTx,temp_l);	while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);	
}///重定向c库函数printf到串口,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{/* 发送一个字节数据到串口 */USART_SendData(USART1, (uint8_t) ch);/* 等待发送完毕 */while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);		return (ch);
}///重定向c库函数scanf到串口,重写向后可使用scanf、getchar等函数
int fgetc(FILE *f)
{/* 等待串口输入数据 */while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);return (int)USART_ReceiveData(USART1);
}
  • usart1.h
#ifndef __usart1_h
#define __usart1_h
#include "stm32f10x.h"
#include <stdio.h>
#define USART1_RX_EN 1
#define USART1_RX_MAX 255#if USART1_RX_EN
extern uint8_t USART1_RX_Buffer[USART1_RX_MAX];// 接收缓存
extern uint8_t USART1_RX_Index; // 接收下标
extern uint8_t USART1_RX_OverFlag;// 接收完成
#endif void USART1_Config(void);
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);
void Usart_SendArray( USART_TypeDef * pUSARTx, uint8_t *array, uint16_t num);
#endif /*__usart1_h */
  • stm32f10x_it.c
// 串口中断服务函数
void USART1_IRQHandler(void)
{uint8_t ucTemp;if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET){		ucTemp = USART_ReceiveData(USART1);// 防止下标越界if(USART1_RX_Index >=USART1_RX_MAX){USART1_RX_Index = 0;}if(ucTemp !=  '#'){USART1_RX_Buffer[USART1_RX_Index++] = ucTemp;}// 发送的结束符if(ucTemp == '#'){USART1_RX_Buffer[USART1_RX_Index++] = ucTemp;USART1_RX_OverFlag = 1;// 发送完成}}	 USART_ClearITPendingBit(USART1,USART_IT_RXNE); // 清除中断标识【可以加;可不加】
}
  • main.c
#include "stm32f10x.h"
#include "led.h"
#include "usart1.h"
#include "string.h"const char cmd1[8] = "on#";
const char cmd2[8] = "off#";
int main(void){// 初始化串口USART1_Config();// 初始化LEDledInit();ledOnOrOff(LED_ON);while(1){if(USART1_RX_OverFlag == 1){// 解析命令if(strstr((const char*)USART1_RX_Buffer,cmd1)!= NULL){ledOnOrOff(LED_ON);printf("灯已开");}if(strstr((const char*)USART1_RX_Buffer,cmd2)!= NULL){ledOnOrOff(LED_OFF);printf("灯已关");}// 重置接收标识USART1_RX_Index = 0;USART1_RX_OverFlag = 0;memset(USART1_RX_Buffer,0,USART1_RX_MAX);// 将缓存请0}}}

http://www.ppmy.cn/news/398848.html

相关文章

【ESP 保姆级教程】疯狂毕设篇 —— 案例:基于ESP8266的WiFi自动打卡考勤系统

忘记过去,超越自己 ❤️ 博客主页 单片机菜鸟哥,一个野生非专业硬件IOT爱好者 ❤️❤️ 本篇创建记录 2022-12-29 ❤️❤️ 本篇更新记录 2022-12-29 ❤️🎉 欢迎关注 🔎点赞 👍收藏 ⭐️留言📝🙏 此博客均由博主单独编写,不存在任何商业团队运营,如发现错误,请…

1分钟获取上千ID,暴力破解、端口扫描、拖库攻击如何防范

你有注意过自己家的摄像头&#xff0c;悄悄移动了位置么&#xff1f; 1月17日&#xff0c;有网友发现&#xff0c;有用户在B站上传疑似破解公共场所摄像头后获得的监控视频。 针对该情况&#xff0c;B站马上发布了处理公告。 现在大家的安全意识越来越好&#xff0c;也知道去酒…

java+SWT+Oracle做的一款类似于QQ的实时通讯软件

1.产品展示 1.1这是我们的登录界面 2.细节&#xff01;&#xff01;&#xff01;talk is cheap&#xff0c;show me the code • UI设计 • Socket网络编程 • 多线程与线程通讯 2.1主页面 2.1.1注册表记住密码 /*** 注册表实现记住密码,注册表在我们的电脑里面&#xf…

C#串口通信从入门到精通(2)——串口相关参数介绍

文章目录 前言1、作者简介2、串口相关参数介绍2.1端口号&#xff08;Port&#xff09;2.2 波特率2.3 起始位2.4 数据位2.5 停止位2.6 校验位2.7 发送缓冲区2.8 接收缓冲区 3、串口助手SComTool1.1介绍3.1 串口设置3.2 发送设置3.2.1 手动发送3.2.2 定时发送3.2.3 发送16进制3.2…

phpstudy80端口被占用时的解决方案

1.适合人群&#xff1f; 之前笔记本单独安装过Apache、php、mysql环境&#xff0c;但是后期想用集成开发环境phpstudy的&#xff0c;安装完phpstudy后(之前的单独环境依然存在)&#xff0c;发现启动时&#xff0c;总是显示80端口被占用&#xff0c;如何解决&#xff0c;看第二条…

关于笔记本电脑建虚拟机如何设置虚拟机IP问题

关于笔记本电脑建虚拟机如何设置虚拟机IP问题 打开网络共享中心->更改配置器选项 查看你使用的网络连接方式&#xff08;我这里是笔记本&#xff0c;使用的是wifi连接&#xff0c;注意红框里的内容&#xff0c;此处是正在使用的网卡&#xff09;。 打开虚拟机->编辑-&…

正点原子linux开发板无屏幕,使用笔记本屏幕显示

买个正点原子linux板子用&#xff0c;发现屏幕和正点原子stm32的屏幕不通用&#xff0c;另购买一块屏幕还是贵&#xff0c;思考如何通过不购买屏幕也可以体验它到显示。可以通过一根网线来解决 解决思路&#xff0c;linux开发板运行应用程序&#xff0c;使用网线将的数据通过网…

模拟QQ软件的基于多线程的流媒体加密传输软件技术

模拟QQ软件的基于多线程的流媒体加密传输软件技术 模拟QQ软件&#xff0c;基于多线程编程捕捉摄像头及麦克风实时数据&#xff0c;基于socket通信设计发送端、接收端两个部分的&#xff0c;对音频和视频进行采集、加密或加水印、传输、解密或提取水印。同时基于数据库进行存储存…