当前位置: 首页 > news >正文

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;			//处理完成后,需要将接收数据包标志位清零,否则将无法接收后续数据包}}
}

相关文章:

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

涉及三个实验&#xff1a; 1.USART串口发送和接收数据 我们使用的是将串口封装成为一个Serial.c模块.其中包含了 void Serial_Init(void);//串口初始化 void Serial_SendByte(uint8_t Byte);//串口发送一个字节 void Serial_SendArray(uint8_t *Array,uint16_t Length);//…...

网关(Gateway)- 内置过滤器工厂

官方文档&#xff1a;Spring Cloud Gateway 内置过滤器工厂 AddRequestHeaderGatewayFilterFactory 为请求添加Header Header的名称及值 配置说明 server:port: 8088 spring:application:name: api-gatewaycloud:nacos:discovery:server-addr: 127.0.0.1:8847username: nacos…...

电风扇如何实现跌倒断电保护功能

电风扇作为日常生活中常用的家电产品&#xff0c;为了提升安全性能&#xff0c;在设计上通常会考虑加入跌倒断电保护功能。其中&#xff0c;光电倾倒开关是实现跌倒断电保护功能的关键组件之一。 光电倾倒开关内置红外发光二极管和光敏接收器&#xff0c;其工作原理非常巧妙。…...

编译原理总结

编译器构成 1. 前端分析部分 1.1 词法分析 确定词性&#xff0c;输出为token序列 1.2 语法分析 识别短语 1.3 语义分析 分析短语在句子中的成分 IR中间代码生成 2. 机器无关代码优化 3. 后端综合部分 目标代码生成 机器相关代码优化 4. 其他 全局信息表 异常输出...

JavaScript:从基础到进阶的全面介绍

JavaScript&#xff1a;从基础到进阶的全面介绍 JavaScript&#xff08;简称JS&#xff09;是一种广泛用于Web开发的编程语言。它是一种轻量级的、解释型或即时编译的语言&#xff0c;具有函数优先的特点。JS最初是为了实现网页的动态效果而设计的&#xff0c;如今已发展成为前…...

linux指令-sed

sed 是一个流编辑器&#xff0c;用于对输入流&#xff08;或文件&#xff09;进行基本的文本转换。以下是 sed 命令的详细输出说明文档&#xff1a; 1. 基本语法 sed [OPTIONS]... [SCRIPT] [INPUTFILE...] OPTIONS&#xff1a;可选的命令行选项&#xff0c;如 -i 用于直接修…...

Docker部署青龙面板

青龙面板 文章目录 青龙面板介绍资源列表基础环境一、安装Docker二、安装Docker-Compose三、安装青龙面板3.1、拉取青龙&#xff08;whyour/qinglong&#xff09;镜像3.2、编写docker-compose文件3.3、检查语法启动容器 四、访问青龙面板五、映射本地部署的青龙面板至公网5.1、…...

【LeetCode】每日一题 2024_6_4 将元素分配到两个数组中 II(二分、离散化、树状数组)

文章目录 LeetCode&#xff1f;启动&#xff01;&#xff01;&#xff01;题目&#xff1a;将元素分配到两个数组中 II题目描述代码与解题思路 每天进步一点点 LeetCode&#xff1f;启动&#xff01;&#xff01;&#xff01; 又有段时间没写每日一题的分享了&#xff0c;原本今…...

JAVA小案例-break练习,随机数,到88停止

JAVA小案例-break练习&#xff0c;随机数&#xff0c;到88停止 代码如下&#xff1a; public class Break {/*** break练习&#xff0c;随机数&#xff0c;到88停止* param args*/public static void main(String[] args) {int count0;//计数器System.out.println("Begi…...

C++第三方库【httplib】断点续传

什么是断点续传 上图是我们平时在浏览器下载文件的场景&#xff0c;下载的本质是数据的传输。当出现网络异常&#xff0c;浏览器异常&#xff0c;或者文件源的服务器异常&#xff0c;下载都可能会终止。而当异常解除后&#xff0c;重新下载文件&#xff0c;我们希望从上一次下载…...

[SaaS] AI+数据,tiktok选品,找达人,看广告数据

TK观察专访丨前阿里“鲁班”创始人用AIGC赋能TikTok获千万融资用AI数据做TikTokhttps://mp.weixin.qq.com/s/xp5UM3ROo48DK4jS9UBMuQ主要还是爬虫做数据的。 商家做内容&#xff1a;1.找达人拍内容&#xff0c;2.商家自己做原生自制内容&#xff0c;3.广告内容。 短视频&…...

A股冲高回落,金属、地产板块领跌,新股N汇成真首日暴涨753%

行情概述 AH股有色金属、教育及地产板块领跌&#xff0c;军工航天及半导体板块逆势走强&#xff1b;锂电池、创新药概念股也走强。创业板新股N汇成真首日暴涨753%&#xff0c;触发二次临停。 周三A股冲高回落&#xff0c;上证指数收跌0.83%&#xff0c;深成指跌0.8%&#xff…...

dns域名解析服务和bond网卡

目录 dns域名解析服务 一、DNS 1、定义 2、以www.baidu.com为例 3、域名体系结构 4、DNS解析使用的协议和端口 5、dns域名解析的过程 6、dns解析的优先级 二、如何实现域名解析 1、域名解析 2、bind配置文件位置 &#xff08;一&#xff09;正向解析 &#xff08;…...

视频生成框架EasyAnimate正式开源!

近期&#xff0c;Sora模型的热度持续上涨&#xff0c;社区中涌现了一些类Sora的开源项目&#xff0c;这些项目均基于Diffusion Transformer结构&#xff0c;使用Transformer结构取代了UNet作为扩散模型的基线&#xff0c;旨在生成更长、更高分辨率、且效果更好的视频。EasyAnim…...

【微机原理与汇编语言】并行接口8255实验

一、实验目的 掌握可编程并行接口芯片8255的工作原理及初始化方法掌握8255在实际应用中的硬件连接及编程应用 二、实验要求 根据实验室现有条件&#xff0c;针对实验任务&#xff0c;设计实验方案并进行实现。 三、实验内容 启动0#计数器&#xff0c;每计5个数&#xff08…...

Oracle表分区的基本使用

什么是表空间 是一个或多个数据文件的集合&#xff0c;所有的数据对象都存放在指定的表空间中&#xff0c;但主要存放的是表&#xff0c;所以称为表空间 什么是表分区 表分区就是把一张大数据的表&#xff0c;根据分区策略进行分区&#xff0c;分区设置完成之后&#xff0c;…...

6月5号作业

设计一个Per类&#xff0c;类中包含私有成员:姓名、年龄、指针成员身高、体重&#xff0c;再设计一个Stu类&#xff0c;类中包含私有成员:成绩、Per类对象p1&#xff0c;设计这两个类的构造函数、析构函数 ​ #include <iostream>using namespace std; class Slu { priv…...

中继器、集线器、网桥、交换机、路由器和网关

目录 前言一、中继器、集线器1.1 中继器1.2 集线器 二、网桥、交换机2.1 网桥2.1.1 认识网桥2.1.2 网桥的工作原理2.1.3 生成树网桥 2.2 交换机2.2.1 交换机的特征2.2.2 交换机的交换模式2.2.3 交换机的功能 三、路由器、网关3.1 路由器的介绍3.2 路由器的工作过程3.2.1 前置知…...

揭秘相似矩阵:机器学习算法中的隐形“纽带”

在机器学习领域&#xff0c;数据的处理和分析至关重要。如何有效地从复杂的数据集中提取有价值的信息&#xff0c;是每一个机器学习研究者都在努力探索的问题。相似矩阵&#xff0c;作为衡量数据之间相似性的数学工具&#xff0c;在机器学习算法中扮演着不可或缺的角色。 相似矩…...

攻防世界—webbaby详解

1.ssrf注入漏洞 ssrf&#xff08;服务端请求伪造&#xff09;是一种安全漏洞&#xff0c;攻击者通过该漏洞向受害服务器发出伪造的请求&#xff0c;从而访问并获取服务器上的资源&#xff0c;常见的ssrf攻击场景包括访问内部网络的服务&#xff0c;执行本地文件系统命令&#…...

MySQL中:cmd下输入命令mysql -uroot -p 连接数据库错误

目录 问题cmd下输入命令mysql -uroot -p错误 待续、更新中 问题 cmd下输入命令mysql -uroot -p错误 解决 配置环境变量&#xff1a;高级系统设置——环境变量——系统变量——path编辑——新建——MySQL.exe文件路径&#xff08;如下图所示&#xff09; phpstudy2018软件下&am…...

【开发利器】使用OpenCV算子工作流高效开发

学习《人工智能应用软件开发》&#xff0c;学会所有OpenCV技能就这么简单&#xff01; 做真正的OpenCV开发者&#xff0c;从入门到入职&#xff0c;一步到位&#xff01; OpenCV实验大师Python SDK 基于OpenCV实验大师v1.02版本提供的Python SDK 实现工作流导出与第三方应用集…...

基础数学-求平方根(easy)

一、问题描述 二、实现思路 1.题目不能直接调用Math.sqrt(x) 2.这个题目可以使用二分法来缩小返回值范围 所以我们在left<right时 使 mid (leftright)/21 当mid*mid>x时&#xff0c;说明right范围过大&#xff0c;rightright-1 当mid*mid<x时&#xff0c;说明left范…...

c语言项目-贪吃蛇项目2-游戏的设计与分析

文章目录 前言游戏的设计与分析地图&#xff1a;这里简述一下c语言的国际化特性相关的知识<locale.h> 本地化头文件类项setlocale函数 上面我们讲到需要打印★&#xff0c;●&#xff0c;□三个宽字符找到这三个字符打印的方式有两种&#xff1a; 控制台屏幕的长宽特性&a…...

力扣2831.找出最长等值子数组

力扣2831.找出最长等值子数组 思路&#xff1a;用二维数组存每个数字的出现下标 遍历所有数字求结果当前子数组大小&#xff1a;pos[i] - pos[j] 1;当前相同数个数&#xff1a;i - j 1;需要删去的数的个数&#xff1a;pos[i] - pos[j] - i j; class Solution {public:int…...

17K star,一款开源免费的手机电脑无缝同屏软件

导读&#xff1a;白茶清欢无别事&#xff0c;我在等风也等你。 作为程序员&#xff0c;在我们的工作中经常需要把手机投票到电脑进行调试工作&#xff0c;选择一款功能强大的投屏软件是一件很必要的事情。今天给大家介绍一款开源且免费的投屏软件&#xff0c;极限投屏&#xff…...

正则表达式二

修饰符 i&#xff1a;将匹配设置为不区分大小写&#xff0c;即A和a没有区别 var str"Google Runoob taobao runoob"; var n1str.match(/runoob/g); //runoob var n2str.match(/runoob/gi); //Runoob&#xff0c;runoobg&#xff1a;重找所有匹配项&#xff0…...

我的创作纪念日--我和CSDN一起走过的1825天

机缘 第一次在CSDN写文章&#xff0c;是自己在记录学习Java8新特性中Lambda表达式的内容过程中收获的学习心得。之前也有记录工作和生活中的心得体会、难点的解决办法、bug的排查处理过程等等。一直都用的有道笔记&#xff0c;没有去和大家区分享的想法&#xff0c;是一起的朋…...

递归书写树形图示例

大叫好&#xff0c;今天书写了一个扁型转换为树型的例子&#xff0c;使用的是递归&#xff0c;请大家食用&#xff0c;无毒 <!DOCTYPE html> <html lang"zh"><head><meta charset"UTF-8"><meta name"viewport" conte…...

【python】IndexError: Replacement index 1 out of range for positional args tuple

成功解决“IndexError: Replacement index 1 out of range for positional args tuple”错误的全面指南 一、引言 在Python编程中&#xff0c;IndexError: Replacement index 1 out of range for positional args tuple这个错误通常发生在使用str.format()方法或者f-string&am…...

高端模板网站建设公司/seo引擎搜索网站

模块的引入方式&#xff1a; 1.import 模块名&#xff1a;导入模块中的所有内容&#xff08;引入多个用逗号分隔&#xff09; import random,time 2.from 模块名 import 函数名1&#xff0c;函数名2... 导入部分模块 &#xff08;导入部分的话直接使用&#xff09; 3.from 模块…...

怎么做网站写书/网络推广一般怎么收费

文 | 草原骑士 来源 | 智能相对论&#xff08;aixdlun&#xff09; 最近AI圈发生了两件大事。第一件是DeepMind、Facebook等AI巨头对《星际争霸》研究兴趣浓厚&#xff0c;公开发布研究工具和数据&#xff1b;第二件是Open AI的机器人在Dota2比赛中战胜了人类顶级职业玩家。至…...

淘宝客网站建设/如何做网站推广私人

归并排序 定义 基本思路&#xff1a;一个待排序记录构成的文件&#xff0c;可以看作是由多个有序子文件组成的&#xff0c;对有序子文件通过若干次使用归并的方法&#xff0c;得到一个有序文件。 归并是指将两个&#xff08;或多个&#xff09;有序子表合并成一个有序表的过…...

做阿拉伯语的网站/关键词排名快照优化

题目 Java利用继承和多态来求矩形、正方形和圆形的面积与周长 import static java.lang.Math.PI;/*** Author Ziph* date 2020/2/20* Email mylifes1110163.com*/ public class Inherit {public static void main(String[] args) {Circle circle new Circle(10);Rect rect ne…...

做网站一定要自己搭建服务器吗/域名服务器ip查询网站

caffe执行draw.py的错误汇总 发表于2017/5/11 17:18:43 89人阅读 caffe执行draw.py的错误汇总 安装完caffe后&#xff0c;使用caffe时&#xff0c;有时候需要调用draw.py来画整个神经网络拓扑图&#xff0c;不过github上最新版本运行draw.py会报错&#xff0c;具体如下 错误1&…...

怎么做自己的音乐网站/微信营销推广公司

我试图在一行内的多行中显示芯片和长行文本 .我目前的代码&#xff1a;return new Column(mainAxisSize: MainAxisSize.max,children: [new Wrap(spacing: 8.0,runSpacing: 4.0,direction: Axis.horizontal,children: [new Tag(tagLabel: Chip1),new Text(This is a very, very…...