STM32实验之USART串口发送+接受数据(二进制/HEX/文本)

涉及三个实验:

1.USART串口发送和接收数据

我们使用的是将串口封装成为一个Serial.c模块.其中包含了

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);//串口发送数字uint8_t Serial_GetRxFlag(void);//串口接收标志位
uint8_t Serial_GetRxData(void);//接受数据模块

在这次实验中,我们调用中断函数申请中断,中断函数为USART1_IRQHandler(void)
  同时也要判断在中断中数据接收标志位,在最后也要清除中断数据接受标志位if(USART_GetITStatus(USART1,USART_IT_RXNE)==SET)
    {
        Serial_RxData=USART_ReceiveData(USART1);
        Serial_RxFlag=1;
        USART_ClearITPendingBit(USART1,USART_IT_RXNE);//清除标志位
    }

1.1Serial.c串口模块

#include "stm32f10x.h"                  // Device header
#include <stdio.h>
#include <stdarg.h>uint8_t Serial_RxData;
uint8_t Serial_RxFlag;
void Serial_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;//引脚9为TX发送端GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;//上拉输入GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//引脚10为RX输入端口GPIO_Init(GPIOB, &GPIO_InitStructure);//USART配置9600波特率 8位字长 1位停止位 无校验位 无硬件流控制 只有发送模式USART_InitTypeDef USART_InitStructure;USART_InitStructure.USART_BaudRate=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 ;//停止位占一位USART_InitStructure.USART_WordLength=USART_WordLength_8b ;//发送字长为8bitUSART_Init(USART1,&USART_InitStructure);//开启RXNE标志位到NVIC的输出,一旦RXEN标志位置1,就开始向NVIC申请中断,之后,我们就可以在中断里接受数据USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel= USART1_IRQn;//指定中断通道NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//指定抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;//指定响应优先级NVIC_Init(&NVIC_InitStructure);USART_Cmd(USART1,ENABLE);
}
//串口发送一个字节
void  Serial_SendByte(uint8_t  Byte)
{USART_SendData(USART1,Byte);//将将数据写入发送数据寄存器中while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);//发送数据寄存器是否发送完成,发送完成跳出循环
}//串口发送一个数组
// *Array 要发送数组的首地址
//Length 要发送数组的长度
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]);}
}//函    数:次方函数(内部使用)//返 回 值:返回值等于X的Y次方
uint32_t Serial_Pow(uint32_t X,uint32_t Y)
{uint32_t Result =1;while(Y--){Result *=X;}return Result;
}
//串口发送数字
//Number 要发送的数字,范围:0~4294967295
//Length 要发送数字的长度,范围:0~10
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');}
}
//fputc为printf的底层,printf在打印的时候不断调用fputc函数
int fputc(int ch,FILE *f)
{Serial_SendByte(ch);//在这里我们把fputc函数重定向到串口,那printf自然输出到串口return ch;
}//将printf打印的内容输出到串口
//将可变参数发送出去
void Serial_Printf(char *format,...)//format参数用来接收格式化字符串,...用来接收后面的可变参数列表
{char String[100];va_list arg;//定义一个参数列表变量va_start(arg,format);//从format位置开始接收参数表,放在arg里vsprintf(String,format,arg);va_end(arg);//释放参数列表Serial_SendString(String);
}
//实现读后自动清除
uint8_t Serial_GetRxFlag(void)
{if(Serial_RxFlag==1)//接受数据标志位置1,接收到数据{Serial_RxFlag=0;return 1;}return 0;
}
//变量封装返回接收到的数据
uint8_t Serial_GetRxData(void)
{return Serial_RxData;
}
void USART1_IRQHandler(void)
{if(USART_GetITStatus(USART1,USART_IT_RXNE)==SET){Serial_RxData=USART_ReceiveData(USART1);Serial_RxFlag=1;USART_ClearITPendingBit(USART1,USART_IT_RXNE);//清除标志位}
}	

 1.2Serial.h函数

#ifndef __SERIAL_H
#define __SERIAL_Hvoid 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,...);
uint8_t Serial_GetRxFlag(void);//接受数据标志位
uint8_t Serial_GetRxData(void);#endif

1.3 main.c函数

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Serial.h"uint8_t RxData;			//定义用于接收串口数据的变量int main(void)
{OLED_Init();		//OLED初始化OLED_ShowString(1, 1, "RxData:");Serial_Init();		//串口初始化while (1){if (Serial_GetRxFlag() == 1)			//检查串口接收数据的标志位{RxData = Serial_GetRxData();		//获取串口接收的数据Serial_SendByte(RxData);			//串口将收到的数据回传回去,用于测试OLED_ShowHexNum(1, 8, RxData, 2);	//显示串口接收的数据}}
}

2.USART串口发送和接受HEX数据

在接受HEX数据包时使用一个状态机的理念。

2.1状态机代码

	    RxData=USART_ReceiveData(USART1);if(RxState==0)/*当前状态为0,接收数据包包头*/{if(RxData==0xFF)//如果数据确实是包头{RxState = 1;			//置下一个状态pRxPacket = 0;			//数据包的位置归零}}else if(RxState==1)/*当前状态为1,接收数据包数据*/{Serial_RxPacket[pRxPacket]=RxData;//将数据存入数据包数组的指定位置pRxPacket++;//数据包的位置自增if(pRxPacket>=4)//如果收够4个数据{RxState=2;//置下一个状态}}else if(RxState==2)/*当前状态为2,接收数据包包尾*/{if(RxData==0xFE)//如果数据确实是包尾部{RxState=0;//状态归0Serial_RxFlag=1;//接收数据包标志位置1,成功接收一个数据包}}

 2.2Serial.c串口模块

#include "stm32f10x.h"                  // Device header
#include <stdio.h>
#include <stdarg.h>
//这里的数据只存储发送和接受的载荷数据,包头包尾不包含
uint8_t Serial_TxPacket[4];//发送的数据包
uint8_t Serial_RxPacket[4];//接收的数据包
uint8_t Serial_RxFlag;//收到数据标志位
uint8_t RxData;
void Serial_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;//引脚9为TX发送端GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;//上拉输入GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//引脚10为RX输入端口GPIO_Init(GPIOB, &GPIO_InitStructure);//USART配置9600波特率 8位字长 1位停止位 无校验位 无硬件流控制 只有发送模式USART_InitTypeDef USART_InitStructure;USART_InitStructure.USART_BaudRate=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 ;//停止位占一位USART_InitStructure.USART_WordLength=USART_WordLength_8b ;//发送字长为8bitUSART_Init(USART1,&USART_InitStructure);//开启RXNE标志位到NVIC的输出,一旦RXEN标志位置1,就开始向NVIC申请中断,之后,我们就可以在中断里接受数据USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel= USART1_IRQn;//指定中断通道NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//指定抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;//指定响应优先级NVIC_Init(&NVIC_InitStructure);USART_Cmd(USART1,ENABLE);
}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');}
}
//fputc为printf的底层,printf在打印的时候不断调用fputc函数
int fputc(int ch,FILE *f)
{Serial_SendByte(ch);//在这里我们把fputc函数重定向到串口,那printf自然输出到串口return ch;
}//将printf打印的内容输出到串口
//将可变参数发送出去
void Serial_Printf(char *format,...)//format参数用来接收格式化字符串,...用来接收后面的可变参数列表
{char String[100];va_list arg;//定义一个参数列表变量va_start(arg,format);//从format位置开始接收参数表,放在arg里vsprintf(String,format,arg);va_end(arg);//释放参数列表Serial_SendString(String);
}
//模块:发送HEX数据包
void Serial_SendPacket(void)
{Serial_SendByte(0xFF);Serial_SendArray(Serial_TxPacket,4);Serial_SendByte(0xFE);
}
//实现读后自动清除
uint8_t Serial_GetRxFlag(void)
{if(Serial_RxFlag==1)//接受数据标志位置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){//使用状态机机制//接收数据包的状态机RxData=USART_ReceiveData(USART1);if(RxState==0)/*当前状态为0,接收数据包包头*/{if(RxData==0xFF)//如果数据确实是包头{RxState = 1;			//置下一个状态pRxPacket = 0;			//数据包的位置归零}}else if(RxState==1)/*当前状态为1,接收数据包数据*/{Serial_RxPacket[pRxPacket]=RxData;//将数据存入数据包数组的指定位置pRxPacket++;//数据包的位置自增if(pRxPacket>=4)//如果收够4个数据{RxState=2;//置下一个状态}}else if(RxState==2)/*当前状态为2,接收数据包包尾*/{if(RxData==0xFE)//如果数据确实是包尾部{RxState=0;//状态归0Serial_RxFlag=1;//接收数据包标志位置1,成功接收一个数据包}}USART_ClearITPendingBit(USART1,USART_IT_RXNE);//清除标志位}
}	

2.3Serial.h函数

#ifndef __SERIAL_H
#define __SERIAL_H#include <stdio.h>
extern uint8_t Serial_TxPacket[4];//外部可调用数组
extern uint8_t Serial_RxPacket[4];
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,...);uint8_t Serial_GetRxFlag(void);//这个函数判断是不是接收到了数据包void Serial_SendPacket(void);void USART1_IRQHandler(void);#endif

2.4 main.c函数

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#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_ShowString(3, 1, "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)				//按键1按下{Serial_TxPacket[0] ++;		//测试数据自增Serial_TxPacket[1] ++;Serial_TxPacket[2] ++;Serial_TxPacket[3] ++;Serial_SendPacket();		//串口发送数据包Serial_TxPacketOLED_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_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);}}
}

3.USART串口发送和接受文本数据

在接受文本数据包时使用一个状态机的理念

3.1状态机代码

if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)	//判断是否是USART1的接收事件触发的中断{uint8_t RxData = USART_ReceiveData(USART1);			//读取数据寄存器,存放在接收的数据变量/*使用状态机的思路,依次处理数据包的不同部分*//*当前状态为0,接收数据包包头*/if (RxState == 0){if (RxData == '@' && Serial_RxFlag == 0)		//如果数据确实是包头,并且上一个数据包已处理完毕{RxState = 1;			//置下一个状态pRxPacket = 0;			//数据包的位置归零}}/*当前状态为1,接收数据包数据,同时判断是否接收到了第一个包尾*/else if (RxState == 1){if (RxData == '\r')			//如果收到第一个包尾{RxState = 2;			//置下一个状态}else						//接收到了正常的数据{Serial_RxPacket[pRxPacket] = RxData;		//将数据存入数据包数组的指定位置pRxPacket ++;			//数据包的位置自增}}/*当前状态为2,接收数据包第二个包尾*/else if (RxState == 2){if (RxData == '\n')			//如果收到第二个包尾{RxState = 0;			//状态归0Serial_RxPacket[pRxPacket] = '\0';			//将收到的字符数据包添加一个字符串结束标志Serial_RxFlag = 1;		//接收数据包标志位置1,成功接收一个数据包}}

 3.2Serial.c函数

#include "stm32f10x.h"                  // Device header
#include <stdio.h>
#include <stdarg.h>
//这里的数据只存储发送和接受的载荷数据,包头包尾不包含char Serial_RxPacket[100];//接收的数据包
uint8_t Serial_RxFlag;//收到数据标志位
uint8_t RxData;void Serial_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;//引脚9为TX发送端GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;//上拉输入GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//引脚10为RX输入端口GPIO_Init(GPIOB, &GPIO_InitStructure);//USART配置9600波特率 8位字长 1位停止位 无校验位 无硬件流控制 只有发送模式USART_InitTypeDef USART_InitStructure;USART_InitStructure.USART_BaudRate=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 ;//停止位占一位USART_InitStructure.USART_WordLength=USART_WordLength_8b ;//发送字长为8bitUSART_Init(USART1,&USART_InitStructure);//开启RXNE标志位到NVIC的输出,一旦RXEN标志位置1,就开始向NVIC申请中断,之后,我们就可以在中断里接受数据USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel= USART1_IRQn;//指定中断通道NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//指定抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;//指定响应优先级NVIC_Init(&NVIC_InitStructure);USART_Cmd(USART1,ENABLE);
}void Serial_SendByte(uint8_t Byte)
{USART_SendData(USART1, Byte);		//将字节数据写入数据寄存器,写入后USART自动生成时序波形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');}
}
//fputc为printf的底层,printf在打印的时候不断调用fputc函数
int fputc(int ch,FILE *f)
{Serial_SendByte(ch);//在这里我们把fputc函数重定向到串口,那printf自然输出到串口return ch;
}//将printf打印的内容输出到串口
//将可变参数发送出去
void Serial_Printf(char *format,...)//format参数用来接收格式化字符串,...用来接收后面的可变参数列表
{char String[100];va_list arg;//定义一个参数列表变量va_start(arg,format);//从format位置开始接收参数表,放在arg里vsprintf(String,format,arg);va_end(arg);//释放参数列表Serial_SendString(String);
}//实现读后自动清除
uint8_t Serial_GetRxFlag(void)
{if(Serial_RxFlag==1)//接受数据标志位置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){//接收数据包的状态机RxData=USART_ReceiveData(USART1);if(RxState==0){if(RxData=='@' && Serial_RxFlag == 0){RxState=1;pRxPacket=0;}}else if(RxState==1){if(RxData=='\r'){RxState=2;}else{Serial_RxPacket[pRxPacket]=RxData;pRxPacket++;}}else if(RxState==2){if(RxData=='\n'){RxState=0;Serial_RxPacket[pRxPacket]='\0';Serial_RxFlag=1;}}USART_ClearITPendingBit(USART1,USART_IT_RXNE);//清除标志位}
}	

3.3Serial.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

3.4main.c函数

#include "stm32f10x.h"                  // Device header
#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_ShowString(3, 1, "RxPacket");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();										//点亮LEDSerial_SendString("LED_ON_OK\r\n");				//串口回传一个字符串LED_ON_OKOLED_ShowString(2, 1, "                ");OLED_ShowString(2, 1, "LED_ON_OK");				//OLED清除指定位置,并显示LED_ON_OK}else if (strcmp(Serial_RxPacket, "LED_OFF") == 0)	//如果收到LED_OFF指令{LED1_OFF();										//熄灭LEDSerial_SendString("LED_OFF_OK\r\n");			//串口回传一个字符串LED_OFF_OKOLED_ShowString(2, 1, "                ");OLED_ShowString(2, 1, "LED_OFF_OK");			//OLED清除指定位置,并显示LED_OFF_OK}else						//上述所有条件均不满足,即收到了未知指令{Serial_SendString("ERROR_COMMAND\r\n");			//串口回传一个字符串ERROR_COMMANDOLED_ShowString(2, 1, "                ");OLED_ShowString(2, 1, "ERROR_COMMAND");			//OLED清除指定位置,并显示ERROR_COMMAND}Serial_RxFlag = 0;			//处理完成后,需要将接收数据包标志位清零,否则将无法接收后续数据包}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/22872.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

fun()const->Iterator

先看一个函数定义如下&#xff1a; template <typename T> auto Blocker<T>::ObservedEnd() const -> Iterator {return observed_msg_queue_.end(); } 1 迭代器&#xff1a;Iterator 2 C auto 返回类型推导&#xff1a;-> Iterator 3 函数体限定不能修改…

【C语言】详解函数(上)(庖丁解牛版)

文章目录 1. 前言2. 函数的概念3.库函数3.1 标准库和头文件3.2 库函数的使用3.2.1 头文件的包含3.2.2 实践 4. 自定义函数4.1 自定义函数的语法形式4.2 函数的举例 5. 形参和实参5.1 实参5.2 形参5.3 实参和形参的关系 6. return 语句6. 总结 1. 前言 一讲到函数这块&#xff…

栈排序00

题目链接 栈排序 题目描述 注意点 对栈进行排序使最小元素位于栈顶最多只能使用一个其他的临时栈存放数据不得将元素复制到别的数据结构&#xff08;如数组&#xff09;中栈中的元素数目在[0, 5000]范围内 解答思路 本题是要实现一个小顶堆&#xff0c;可以直接使用Priori…

上位机图像处理和嵌入式模块部署(f407 mcu中的udp server开发)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 既然lwip已经port到407上面了&#xff0c;接下来其实就可以做一些测试了。本身lwip支持tcp、udp&#xff0c;也支持client和server&#xff0c;既然…

【数据分享】中国第三产业统计年鉴(1991-2022)

大家好&#xff01;今天我要向大家介绍一份重要的中国第三产业统计数据资源——《中国第三产业统计年鉴》。这份年鉴涵盖了从1991年到2022年中国第三产业统计全面数据&#xff0c;并提供限时免费下载。&#xff08;无需分享朋友圈即可获取&#xff09; 数据介绍 每年的《中国…

LeetCode.55 跳跃游戏

LeetCode.55 跳跃游戏 题目描述解题思路错误的解题思路解题思路 代码 题目描述 解题思路 错误的解题思路 我一开始的思路是累加可跳范围内的最大值sum&#xff0c;如果最终sum > nums.size()那么就返回true&#xff0c;这种思路是错误的&#xff0c;因为在你选择最大值的…

2004NOIP普及组真题 3. FBI树

线上OJ 地址&#xff1a; [04NOIP普及组] FBI树 本题的意思是&#xff1a;给定一个 01字符串 &#xff08;对应一棵完全二叉树的最后一层叶子节点&#xff09;&#xff0c;将树的每一个节点的值用字母“F、B、I”表示。规则&#xff08;如下图所示&#xff09;为&#xff1a; 1…

Spring AI 第二讲 之 Chat Model API 第二节Ollama Chat

通过 Ollama&#xff0c;您可以在本地运行各种大型语言模型 (LLM)&#xff0c;并从中生成文本。Spring AI 通过 OllamaChatModel 支持 Ollama 文本生成。 先决条件 首先需要在本地计算机上运行 Ollama。请参阅官方 Ollama 项目 README&#xff0c;开始在本地计算机上运行模型…

curl 92 HTTP/2 stream 5 was not closed cleanly: CANCEL

source ~/.bash_profile flutter clean Command exited with code 128: git fetch --tags Standard error: 错误&#xff1a;RPC 失败。curl 92 HTTP/2 stream 5 was not closed cleanly: CANCEL (err 8) 错误&#xff1a;预期仍然需要 2737 个字节的正文 fetch-pack: unexpec…

GPT革命:AI如何重塑我们的未来!

GPT革命&#xff1a;AI如何重塑我们的未来&#xff01; &#x1f604;生命不息&#xff0c;写作不止 &#x1f525; 继续踏上学习之路&#xff0c;学之分享笔记 &#x1f44a; 总有一天我也能像各位大佬一样 &#x1f3c6; 博客首页 怒放吧德德 To记录领地 &#x1f31d;分享…

普通人也能弄的 16 个AI搞钱副业,门槛低,易上手!

大家好&#xff0c;我是灵魂画师向阳 本期给大家分享的是利用AI 做副业的一些方法&#xff0c;大家可以挑选适合自己的赛道去搞钱 现在是人工智能时代&#xff0c;利用好AI 工具&#xff0c;可以降低普通人做副业的门槛&#xff0c;同时也能提高工作效率&#xff0c; 因此AI …

【微机原理与汇编语言】循环程序设计

一、实验目的 1.熟练掌握8086/8088常用汇编指令的使用方法 2.熟练掌握循环结构程序编程技巧 3.熟练掌握汇编语言程序运行调试方法 二、实验要求 认真分析实验题目&#xff0c;设计程序流程图&#xff0c;独立完成代码编写及运行调试。 三、实验题目 给出不大于255的十个…

图片裁剪与上传处理方案 —— 基于阿里云 OSS 处理用户资料

目录 01: 通用组件&#xff1a;input 构建方案分析 02: 通用组件&#xff1a;input 构建方案 03: 构建用户资料基础样式 04: 用户基本资料修改方案 05: 处理不保存时的同步问题 06: 头像修改方案流程分析 07: 通用组件&#xff1a;Dialog 构建方案分析 08: 通用组件&…

计算机组成原理·考点知识点整理

根据往年考试题&#xff0c;对考点和知识点的一个整理。 校验编码 码距 一种编码的最小码距&#xff0c;其实就是指这种编码的码距。码距有两种定义&#xff1a; 码距所描述的对象含义 2 2 2 个特定的码其二进制表示中不同位的个数一种编码这种编码中任意 2 2 2 个合法编码的…

【linux进程控制(三)】进程程序替换--如何自己实现一个bash解释器?

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:Linux从入门到精通⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学更多操作系统知识   &#x1f51d;&#x1f51d; 进程程序替换 1. 前言2. exec…

【JMeter接口自动化】第8讲 Fiddler抓包Jmeter

1&#xff09;配置好Fiddler 设置Fiddler-Tools-Options-HTTPS 设置Fiddler-Tools-Options-Connections&#xff0c;设置端口为8888 2&#xff09;查看IP 在CMD中输入ipconfig 查看IP地址 3&#xff09;配置Jmeter Http请求——基本&#xff0c;设置Http请求&#xff0c;使用…

轻量管理内核复杂级别的项目

在嵌入式开发中&#xff0c;管理大型项目&#xff08;例如Linux内核&#xff09;往往是一个复杂的过程。常规的版本控制系统如Git在处理小型项目时非常高效&#xff0c;但面对庞大的代码库时可能会显得笨重且占用大量存储空间。本文将介绍几种轻量级的方法来管理内核级别的项目…

Python 快速入门

1. 语言基础 1.1 数据类型与变量 Python 是一门动态类型语言&#xff0c;这意味着你不需要显式声明变量的类型。Python 解释器会根据你赋予变量的值自动推断其类型。这使得 Python 代码简洁易懂&#xff0c;但同时也需要注意一些潜在的问题。 1.1.1 Python 数据类型概述 Py…

408链表的创建和初始化

首先第一个头文件&#xff0c;定义结构体类型 typedef struct LNode {int data;struct LNode* next; }LNode,*LinkList; //可能作为第一次写c语言的小伙伴看不懂这一段typedef是如何定义的 //基本的解释如下所示 //typedef struct LNode LNode; //typedef struct LNode* LinkL…

apex代码发送邮件时进行抄送

在 Salesforce 中使用 Apex 代码发送电子邮件时&#xff0c;可以通过 ccAddresses 属性来添加抄送&#xff08;CC&#xff09;收件人。以下是一个示例代码&#xff0c;展示了如何使用 Messaging.SingleEmailMessage 类来发送带有抄送的电子邮件。 示例代码 public class Emai…