刘刘 stm32学习日记 (十一) UART

一、介绍

 主控与外设之间的通讯,数据收发交换

串口:

二、硬件

 电平标准:

  串口参数及时序:

三、USART(通用同步|异步收发器)

四、流程

 if在某时刻给TDR写入了0x55这个数据,在寄存器里就是二进制存储,01010101,然后硬件会进行检测是否有数据正在移位,如果没有那么01010101就会全部移动到发送移位寄存器,准备发送同时会产生一个标志位TXE(发送寄存器空,如果检查这个标志位为1,那么就可以在TDR进行下一个写入了,)然后,发送控制器就会控制移位寄存器向右移位,然后一位一位地,把数据输出到TX引脚进行发送。

接收同样类似,会产生一个标志位USARTRXNE (RX Not Empty),接收数据寄存器非空,检测到RXNE置1之后,就可以把数据读走了

停止位

波特率发生器:

五、实战

 1、硬件

2、软件打通   发送

 1第一步,开启时钟,把需要用的USART和GPIO的时钟打开

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);   // 使能USART1时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);    // 使能GPIOA时钟

2第一步,GPIO初始化,把TX配置成复用输出,RX配置成输入


    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;         // 复用推挽输出
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;               // GPIOA的引脚9
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;       // GPIO速度50MHz
    GPIO_Init(GPIOA, &GPIO_InitStructure); 

3第三步,配置USART,直接使用一个结构体


 USART_InitTypeDef USART_InitStructure;
    USART_InitStructure.USART_BaudRate = 9600;             // 波特率9600
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  // 无硬件流控
    USART_InitStructure.USART_Mode = USART_Mode_Tx;         // 仅发送模式
    USART_InitStructure.USART_Parity = USART_Parity_No;     // 无奇偶校验
    USART_InitStructure.USART_StopBits = USART_StopBits_1;   // 1个停止位
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;  // 8位数据位
    USART_Init(USART1, &USART_InitStructure);              // 初始化USART1

4发送功能直接开启UART就结束了,如果需要接收那么还需要添加中断



    USART_Cmd(USART1, ENABLE);   

5发送字节函数


void Serial_SendByte(uint8_t Byte)
{
    USART_SendData(USART1, Byte);                               // 发送一个字节
    while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);  // 等待发送完成
}

6发送数组函数(传递数组需要使用指针)



void Serial_SendArray(uint8_t *Array, uint16_t Length)
{
    uint16_t i;
    for (i = 0; i < Length; i++)
    {
        Serial_SendByte(Array[i]);                               // 逐个发送数组中的字节
    }
}

7发送字符串等


.h


#ifndef __SERIAL_H
#define __SERIAL_H

#include <stdio.h>

void Serial_Init(void);
void Serial_SendByte(uint8_t Byte);
void Serial_SendArray(uint8_t *Array, uint16_t Length);
void Serial_SendString(char *String);
void Serial_SendNumber(uint32_t Number, uint8_t Length);
void Serial_Printf(char *format, ...);

#endif

 .c


#include "stm32f10x.h"      // 包含STM32F10x系列微控制器的头文件
#include <stdio.h>
#include <stdarg.h>

void Serial_Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);   // 使能USART1时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);    // 使能GPIOA时钟

    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;         // 复用推挽输出
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;               // GPIOA的引脚9
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;       // GPIO速度50MHz
    GPIO_Init(GPIOA, &GPIO_InitStructure);                 // 初始化GPIOA

    USART_InitTypeDef USART_InitStructure;
    USART_InitStructure.USART_BaudRate = 9600;             // 波特率9600
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  // 无硬件流控
    USART_InitStructure.USART_Mode = USART_Mode_Tx;         // 仅发送模式
    USART_InitStructure.USART_Parity = USART_Parity_No;     // 无奇偶校验
    USART_InitStructure.USART_StopBits = USART_StopBits_1;   // 1个停止位
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;  // 8位数据位
    USART_Init(USART1, &USART_InitStructure);              // 初始化USART1

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

void Serial_SendByte(uint8_t Byte)
{
    USART_SendData(USART1, Byte);                               // 发送一个字节
    while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);  // 等待发送完成
}

void Serial_SendArray(uint8_t *Array, uint16_t Length)
{
    uint16_t i;
    for (i = 0; i < Length; i++)
    {
        Serial_SendByte(Array[i]);                               // 逐个发送数组中的字节
    }
}

void Serial_SendString(char *String)
{
    uint8_t i;
    for (i = 0; String[i] != '\0'; i++)
    {
        Serial_SendByte(String[i]);                              // 逐个发送字符串中的字符
    }
}

uint32_t Serial_Pow(uint32_t X, uint32_t Y)
{
    uint32_t Result = 1;
    while (Y--)
    {
        Result *= X;                                            // 计算X的Y次方
    }
    return Result;
}

void Serial_SendNumber(uint32_t Number, uint8_t Length)
{
    uint8_t i;
    for (i = 0; i < Length; i++)
    {
        Serial_SendByte(Number / Serial_Pow(10, Length - i - 1) % 10 + '0');  // 逐位发送数字的每一位
    }
}

int fputc(int ch, FILE *f)
{
    Serial_SendByte(ch);                                        // 将字符发送到串口
    return ch;
}

void Serial_Printf(char *format, ...)
{
    char String[100];
    va_list arg;
    va_start(arg, format);
    vsprintf(String, format, arg);                              // 使用可变参数格式化字符串
    va_end(arg);
    Serial_SendString(String);                                   // 发送格式化后的字符串
}

 main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Serial.h"

int main(void)
{
	OLED_Init();
	
	Serial_Init();
	
	Serial_SendByte(0x41);
	
	uint8_t MyArray[] = {0x42, 0x43, 0x44, 0x45};
	Serial_SendArray(MyArray, 4);
	
	Serial_SendString("\r\nNum1=");
	
	Serial_SendNumber(111, 3);
	
	printf("\r\nNum2=%d", 222);
	
	char String[100];
	sprintf(String, "\r\nNum3=%d", 333);
	Serial_SendString(String);
	
	Serial_Printf("\r\nNum4=%d", 444);
	Serial_Printf("\r\n");
	
	while (1)
	{
		
	}
}

3、发送加接收

库文件要改的部分:新加一个发送口的GPIO,后把UART的模式上添加RX模式

1查询模式:

查询的流程是,在主函数里不断判断RXNE标志位,如果置1了,就说明收到数据了,再调用ReceiveData,读取DR寄存器,这样就行了

在主函数里一直查询:

if (Serial_GetRxFlag() == 1)
		{
			RxData = Serial_GetRxData();
			Serial_SendByte(RxData);
			OLED_ShowHexNum(1, 8, RxData, 2);
		}
2中断模式:

实质:开启RXNE标志位到NVIC的输出,然后配置NVIC就可,然后在中断函数里边写内容就行,

4、数据包发送

作用:把一个个单独的数据给打包起来,方便进行多字节数据通信

当数据里出现包头包尾时,可以限制数据的范围,避免误判,或者固定包长限制数据长度

为自己规定

HEX数据包

优点:传输最直接,解析数据非常简单

缺点:就是灵活性不足、载荷容易和包头包尾重复

文本数据包

优点是,数据直观易理解,非常灵活 ,比较适合一些输入指令进行人机交互的场合

缺点是:解析效率低

收发流程

HEX

文本

 

5、数据包发送实验

 hex

文本:

  • HEX数据包:

.c

#include "stm32f10x.h"                  // 设备头文件
#include <stdio.h>
#include <stdarg.h>

uint8_t Serial_TxPacket[4];             // 串口发送数据包数组,长度为4
uint8_t Serial_RxPacket[4];             // 串口接收数据包数组,长度为4
uint8_t Serial_RxFlag;                   // 串口接收标志位

void Serial_Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);   // 使能USART1时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);    // 使能GPIOA时钟
    
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;          // 复用推挽输出
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;                // TX引脚
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;            // 输入上拉
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;               // RX引脚
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    USART_InitTypeDef USART_InitStructure;
    USART_InitStructure.USART_BaudRate = 9600;               // 波特率设置为9600
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  // 无硬件流控制
    USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;  // 发送和接收模式
    USART_InitStructure.USART_Parity = USART_Parity_No;      // 无奇偶校验
    USART_InitStructure.USART_StopBits = USART_StopBits_1;    // 1个停止位
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;  // 数据位长度为8位
    USART_Init(USART1, &USART_InitStructure);
    
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);          // 使能USART1接收中断
    
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;       // USART1中断
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;         // 使能中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  // 抢占优先级1
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;       // 子优先级1
    NVIC_Init(&NVIC_InitStructure);
    
    USART_Cmd(USART1, ENABLE);                               // 使能USART1
}

void Serial_SendByte(uint8_t Byte)
{
    USART_SendData(USART1, Byte);
    while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);  // 等待发送完成
}
void Serial_SendArray(uint8_t *Array, uint16_t Length)
{
    uint16_t i;
    for (i = 0; i < Length; i++)
    {
        Serial_SendByte(Array[i]);  // 逐个发送数组中的字节
    }
}

void Serial_SendString(char *String)
{
    uint8_t i;
    for (i = 0; String[i] != '\0'; i++)
    {
        Serial_SendByte(String[i]);  // 逐个发送字符串中的字符
    }
}

uint32_t Serial_Pow(uint32_t X, uint32_t Y)
{
    uint32_t Result = 1;
    while (Y--)
    {
        Result *= X;  // 计算 X 的 Y 次方
    }
    return Result;
}

void Serial_SendNumber(uint32_t Number, uint8_t Length)
{
    uint8_t i;
    for (i = 0; i < Length; i++)
    {
        Serial_SendByte(Number / Serial_Pow(10, Length - i - 1) % 10 + '0');  // 逐位发送数字的每一位
    }
}

int fputc(int ch, FILE *f)
{
    Serial_SendByte(ch);  // 发送字符到串口
    return ch;
}

void Serial_Printf(char *format, ...)
{
    char String[100];
    va_list arg;
    va_start(arg, format);
    vsprintf(String, format, arg);  // 格式化字符串
    va_end(arg);
    Serial_SendString(String);  // 发送格式化后的字符串
}

void Serial_SendPacket(void)
{
    Serial_SendByte(0xFF);  // 发送起始字节
    Serial_SendArray(Serial_TxPacket, 4);  // 发送数据包数组
    Serial_SendByte(0xFE);  // 发送结束字节
}

uint8_t Serial_GetRxFlag(void)
{
    if (Serial_RxFlag == 1)
    {
        Serial_RxFlag = 0;
        return 1;  // 返回接收标志位并清零
    }
    return 0;
}

void USART1_IRQHandler(void)
{
    static uint8_t RxState = 0;
    static uint8_t pRxPacket = 0;
    if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
    {
        uint8_t RxData = USART_ReceiveData(USART1);  // 读取接收到的数据
        
        if (RxState == 0)
        {
            if (RxData == 0xFF)
            {
                RxState = 1;  // 进入数据包接收状态
                pRxPacket = 0;  // 重置接收包计数器
            }
        }
        else if (RxState == 1)
        {
            Serial_RxPacket[pRxPacket] = RxData;  // 存储接收到的数据到数据包数组
            pRxPacket++;
            if (pRxPacket >= 4)
            {
                RxState = 2;  // 数据包接收完成
            }
        }
        else if (RxState == 2)
        {
            if (RxData == 0xFE)
            {
                RxState = 0;  // 结束字节接收,重置状态为初始状态
                Serial_RxFlag = 1;  // 设置接收标志位
            }
        }
        
        USART_ClearITPendingBit(USART1, USART_IT_RXNE);  // 清除接收中断标志位
    }
}

.h

#ifndef __SERIAL_H
#define __SERIAL_H

#include <stdio.h>

extern uint8_t Serial_TxPacket[];  // 声明发送数据包数组
extern uint8_t Serial_RxPacket[];  // 声明接收数据包数组

void Serial_Init(void);  // 初始化串口
void Serial_SendByte(uint8_t Byte);  // 发送单个字节
void Serial_SendArray(uint8_t *Array, uint16_t Length);  // 发送字节数组
void Serial_SendString(char *String);  // 发送字符串
void Serial_SendNumber(uint32_t Number, uint8_t Length);  // 发送数字
void Serial_Printf(char *format, ...);  // 格式化发送字符串

void Serial_SendPacket(void);  // 发送数据包
uint8_t Serial_GetRxFlag(void);  // 获取接收标志位

#endif

main.c

#include "stm32f10x.h"     // 引入STM32F10x芯片的设备头文件
#include "Delay.h"         // 引入延时函数的头文件
#include "OLED.h"          // 引入OLED显示屏的头文件
#include "Serial.h"        // 引入串口通信的头文件
#include "Key.h"           // 引入按键的头文件

uint8_t KeyNum;            // 定义一个按键编号变量

int main(void)
{
    OLED_Init();            // 初始化OLED显示屏
    Key_Init();             // 初始化按键
    Serial_Init();          // 初始化串口通信

    OLED_ShowString(1, 1, "TxPacket");  // 在OLED上显示字符串 "TxPacket"
    OLED_ShowString(3, 1, "RxPacket");  // 在OLED上显示字符串 "RxPacket"

    Serial_TxPacket[0] = 0x01;  // 初始化发送数据包数组
    Serial_TxPacket[1] = 0x02;
    Serial_TxPacket[2] = 0x03;
    Serial_TxPacket[3] = 0x04;

    while (1)
    {
        KeyNum = Key_GetNum();  // 获取按键编号

        if (KeyNum == 1)
        {
            Serial_TxPacket[0]++;  // 按键1按下,递增数据包内容
            Serial_TxPacket[1]++;
            Serial_TxPacket[2]++;
            Serial_TxPacket[3]++;

            Serial_SendPacket();  // 发送数据包

            // 在OLED上显示发送数据包内容的十六进制值
            OLED_ShowHexNum(2, 1, Serial_TxPacket[0], 2);
            OLED_ShowHexNum(2, 4, Serial_TxPacket[1], 2);
            OLED_ShowHexNum(2, 7, Serial_TxPacket[2], 2);
            OLED_ShowHexNum(2, 10, Serial_TxPacket[3], 2);
        }

        if (Serial_GetRxFlag() == 1)
        {
            // 在OLED上显示接收数据包内容的十六进制值
            OLED_ShowHexNum(4, 1, Serial_RxPacket[0], 2);
            OLED_ShowHexNum(4, 4, Serial_RxPacket[1], 2);
            OLED_ShowHexNum(4, 7, Serial_RxPacket[2], 2);
            OLED_ShowHexNum(4, 10, Serial_RxPacket[3], 2);
        }
    }
}

这个主程序初始化了OLED显示屏、按键、串口通信,并在一个无限循环中检测按键状态和串口接收状态,根据按键状态递增发送数据包内容,并在OLED上显示发送和接收的数据包内容。 

 

 文本数据包:

.c

 #include "stm32f10x.h"                  // 引入STM32F10x芯片的设备头文件
#include <stdio.h>                      // 引入标准输入输出头文件
#include <stdarg.h>                     // 引入可变参数头文件

char Serial_RxPacket[100];              // 存储接收到的消息的数组,最大长度为100,注意足够大以容纳可能的消息
uint8_t Serial_RxFlag;                  // 标志位,用于指示是否接收到完整的消息

void Serial_Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);  // 使能USART1时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);   // 使能GPIOA时钟
    
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;         // 复用推挽输出
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;              // USART1_TX引脚
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;      // GPIO速度为50MHz
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;          // 上拉输入
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;             // USART1_RX引脚
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;      // GPIO速度为50MHz
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    USART_InitTypeDef USART_InitStructure;
    USART_InitStructure.USART_BaudRate = 9600;             // 波特率9600
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  // 无硬件流控制
    USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;  // 发送和接收模式
    USART_InitStructure.USART_Parity = USART_Parity_No;    // 无奇偶校验
    USART_InitStructure.USART_StopBits = USART_StopBits_1;  // 1个停止位
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;  // 8位数据位
    USART_Init(USART1, &USART_InitStructure);
    
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);  // 使能USART1接收中断
    
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  // 配置中断分组为优先级2
    
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;  // USART1中断
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;     // 使能中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  // 抢占优先级1
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;        // 子优先级1
    NVIC_Init(&NVIC_InitStructure);
    
    USART_Cmd(USART1, ENABLE);  // 使能USART1
}

void Serial_SendByte(uint8_t Byte)
{
    USART_SendData(USART1, Byte);
    while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);  // 等待发送完成
}

void Serial_SendArray(uint8_t *Array, uint16_t Length)
{
    uint16_t i;
    for (i = 0; i < Length; i ++)
    {
        Serial_SendByte(Array[i]);
    }
}

void Serial_SendString(char *String)
{
    uint8_t i;
    for (i = 0; String[i] != '\0'; i ++)
    {
        Serial_SendByte(String[i]);
    }
}

uint32_t Serial_Pow(uint32_t X, uint32_t Y)
{
    uint32_t Result = 1;
    while (Y --)
    {
        Result *= X;
    }
    return Result;
}

void Serial_SendNumber(uint32_t Number, uint8_t Length)
{
    uint8_t i;
    for (i = 0; i < Length; i ++)
    {
        Serial_SendByte(Number / Serial_Pow(10, Length - i - 1) % 10 + '0');
    }
}

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

void Serial_Printf(char *format, ...)
{
    char String[100];
    va_list arg;
    va_start(arg, format);
    vsprintf(String, format, arg);
    va_end(arg);
    Serial_SendString(String);
}

void USART1_IRQHandler(void)
{
    static uint8_t RxState = 0;
    static uint8_t pRxPacket = 0;
    if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
    {
        uint8_t RxData = USART_ReceiveData(USART1);
        
        if (RxState == 0)
        {
            if (RxData == '@' && Serial_RxFlag == 0)  // 判断是否接收到消息的起始符 '@',并且接收标志位为0
            {
                RxState = 1;
                pRxPacket = 0;
            }
        }
        else if (RxState == 1)
        {
            if (RxData == '\r')  // 判断是否接收到消息的结束符 '\r'
            {
                RxState = 2;
            }
            else
            {
                Serial_RxPacket[pRxPacket] = RxData;
                pRxPacket ++;
            }
        }
        else if (RxState == 2)
        {
            if (RxData == '\n')  // 判断是否接收到消息的结束符 '\n'
            {
                RxState = 0;
                Serial_RxPacket[pRxPacket] = '\0';  // 添加字符串结束符
                Serial_RxFlag = 1;  // 设置接收标志位
            }
        }
        
        USART_ClearITPendingBit(USART1, USART_IT_RXNE);  // 清除接收中断标志位
    }
}

.h

#ifndef __SERIAL_H
#define __SERIAL_H

#include <stdio.h>

extern char Serial_RxPacket[];   // 外部声明接收消息的数组
extern uint8_t Serial_RxFlag;     // 外部声明接收标志位

void Serial_Init(void);           // 串口初始化函数声明
void Serial_SendByte(uint8_t Byte);    // 发送单个字节函数声明
void Serial_SendArray(uint8_t *Array, uint16_t Length);  // 发送字节数组函数声明
void Serial_SendString(char *String);   // 发送字符串函数声明
void Serial_SendNumber(uint32_t Number, uint8_t Length);   // 发送数字函数声明
void Serial_Printf(char *format, ...);  // 格式化输出并发送函数声明

#endif

main.c

#include "stm32f10x.h"                  // 引入STM32F10x芯片的设备头文件
#include "Delay.h"
#include "OLED.h"
#include "Serial.h"
#include "LED.h"
#include "string.h"

int main(void)
{
    OLED_Init();                       // OLED屏幕初始化
    LED_Init();                        // LED初始化
    Serial_Init();                     // 串口初始化
    
    OLED_ShowString(1, 1, "TxPacket"); // OLED显示发送数据提示
    OLED_ShowString(3, 1, "RxPacket"); // OLED显示接收数据提示
    
    while (1)
    {
        if (Serial_RxFlag == 1)        // 如果接收到完整的消息
        {
            OLED_ShowString(4, 1, "                ");  // 清空之前的显示
            OLED_ShowString(4, 1, Serial_RxPacket);         // 在OLED上显示接收到的消息
            
            if (strcmp(Serial_RxPacket, "LED_ON") == 0)    // 如果接收到的消息是"LED_ON"
            {
                LED1_ON();                                   // 打开LED1
                Serial_SendString("LED_ON_OK\r\n");         // 发送成功响应
                OLED_ShowString(2, 1, "                ");  // 清空之前的显示
                OLED_ShowString(2, 1, "LED_ON_OK");          // 在OLED上显示LED打开成功
            }
            else if (strcmp(Serial_RxPacket, "LED_OFF") == 0)  // 如果接收到的消息是"LED_OFF"
            {
                LED1_OFF();                                   // 关闭LED1
                Serial_SendString("LED_OFF_OK\r\n");        // 发送成功响应
                OLED_ShowString(2, 1, "                ");  // 清空之前的显示
                OLED_ShowString(2, 1, "LED_OFF_OK");         // 在OLED上显示LED关闭成功
            }
            else
            {
                Serial_SendString("ERROR_COMMAND\r\n");      // 发送错误响应
                OLED_ShowString(2, 1, "                ");  // 清空之前的显示
                OLED_ShowString(2, 1, "ERROR_COMMAND");       // 在OLED上显示错误命令
            }
            
            Serial_RxFlag = 0;  // 清除接收标志位,准备接收下一条消息
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值