STM32 USART串口通信

目录

USART串口

串口发送

串口发送+接收

串口收发HEX数据包

串口收发文本数据包


USART串口

串口发送

Serial.c

#include "stm32f10x.h"                  // Device header
#include "stdio.h"
#include "stdarg.h"/*** @brief  初始化串口以及引脚配置* @param  无* @retval 无*/
void Serial_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//TX引脚配置GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//为什么?查表手册推荐GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);//串口配置USART_InitTypeDef USART_InitStructrue;USART_InitStructrue.USART_BaudRate = 9600;//波特率配置USART_InitStructrue.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//硬件流控制(无)USART_InitStructrue.USART_Mode = USART_Mode_Tx;//串口模式(发送)USART_InitStructrue.USART_Parity = USART_Parity_No;//校验位(无)USART_InitStructrue.USART_StopBits = USART_StopBits_1;//停止位(1位)USART_InitStructrue.USART_WordLength = USART_WordLength_8b;//字长(8位)USART_Init(USART1,&USART_InitStructrue);USART_Cmd(USART1,ENABLE);//开启USART1
}/*** @brief  发送一个字节* @param  Byte 发送的字节* @retval 无*/
void Serial_SendByte(uint8_t Byte)
{USART_SendData(USART1,Byte);while (USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);//完成传输之前进行空循环//TXE位置一后,会自动清除标志位,详看手册
}/*** @brief  发送一个数组* @param  Array:发送的数组* @param  Length:发送数组的长度* @retval 无*/
void Serial_SendArray(uint8_t *Array,uint16_t Length)
{uint16_t i;for(i = 0; i < Length; i ++){Serial_SendByte(Array[i]);}
}/*** @brief  发送一个字符串* @param  String:发送的字符串* @retval 无*/
void Serial_SendString(char *String)
{uint8_t i;for(i = 0; String[i] != '\0'; i ++)//判断是否为结束标志位{Serial_SendByte(String[i]);}
}/*** @brief  计算X^Y* @param  X:底数    Y:幂次* @retval Res:X^Y的结果*/
uint32_t Serial_Pow(uint32_t X,uint32_t Y)
{uint32_t Res = 1;while(Y --){Res *= X;}return Res;
}/*** @brief  发送一个无符号数字* @param  Number:发送的数字* @param  Length:数字的长度* @retval 无*/
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 + 0x30);//从最高位开始获取各位数字Serial_SendByte(Number / Serial_Pow(10,Length - i - 1) % 10 + '0');}
}int fputc(int ch,FILE *f)//重写fputc函数,将fputc重定向到串口
{Serial_SendByte(ch);return ch;
}/*** @brief  封装vsprintf可变参数* @param  可变参数* @retval 无*/
void Serial_Printf(char *format,...)
{char String[100];va_list arg;//定义参数列表变量va_start(arg , format);//从format位置接收参数表,放入arg中vsprintf(String, format ,arg);//打印位置     格式化字符串     参数表//sprintf只能接收直接写的参数,封装格式需要vsprintfva_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();uint8_t MyArray[4] = {0x42, 0x43, 0x44, 0x45};Serial_SendByte(0x41);Serial_SendArray(MyArray,4);Serial_Printf("\r\n");Serial_SendString("Hello\r\n");//\r回车 \n换行Serial_SendNumber(1234,4);Serial_Printf("\r\n");//移植printf函数://1.重写fputc函数,将fputc重定向到串口(printf此时只有一个)printf("Num = %d\r\n",666);//2.使用sprintf函数char String[100];sprintf(String,"Num = %d\r\n",666);//sptintf可以指定打印位置,不涉及重定向Serial_SendString(String);//3.封装sprintf函数Serial_Printf("Num = %d\r\n",666);//输出汉字Serial_Printf("你好,世界");//utf8   --no-multibyte-charswhile(1){}}
串口发送+接收

Serial.c

#include "stm32f10x.h"                  // Device header
#include "stdio.h"
#include "stdarg.h"uint8_t Serial_RxData;//数据存放位置
uint8_t Serial_RxFlag;//数据是否读到标志位/*** @brief  串口,引脚以及中断初始化* @param  无* @retval 无*/
void Serial_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//TX引脚配置GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//为什么?查表手册推荐GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);//RX引脚配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//为什么?查表手册推荐(上拉输入)GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);//串口配置USART_InitTypeDef USART_InitStructrue;USART_InitStructrue.USART_BaudRate = 9600;//波特率配置USART_InitStructrue.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//硬件流控制(无)USART_InitStructrue.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;//串口模式(发送接收)USART_InitStructrue.USART_Parity = USART_Parity_No;//校验位(无)USART_InitStructrue.USART_StopBits = USART_StopBits_1;//停止位(1位)USART_InitStructrue.USART_WordLength = USART_WordLength_8b;//字长(8位)USART_Init(USART1,&USART_InitStructrue);//中断方式接收USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//当接收到字节时触发中断//配置NVICNVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//相应优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能通道NVIC_Init(&NVIC_InitStructure);USART_Cmd(USART1,ENABLE);//开启USART1}/*** @brief  发送一个字节* @param  Byte 发送的字节* @retval 无*/
void Serial_SendByte(uint8_t Byte)
{USART_SendData(USART1,Byte);while (USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);//完成传输之前进行空循环//TXE位置一后,会自动清除标志位,详看手册
}/*** @brief  发送一个数组* @param  Array:发送的数组* @param  Length:发送数组的长度* @retval 无*/
void Serial_SendArray(uint8_t *Array,uint16_t Length)
{uint16_t i;for(i = 0; i < Length; i ++){Serial_SendByte(Array[i]);}
}/*** @brief  发送一个字符串* @param  String:发送的字符串* @retval 无*/
void Serial_SendString(char *String)
{uint8_t i;for(i = 0; String[i] != '\0'; i ++)//判断是否为结束标志位{Serial_SendByte(String[i]);}
}/*** @brief  计算X^Y* @param  X:底数    Y:幂次* @retval Res:X^Y的结果*/
uint32_t Serial_Pow(uint32_t X,uint32_t Y)
{uint32_t Res = 1;while(Y --){Res *= X;}return Res;
}/*** @brief  发送一个无符号数字* @param  Number:发送的数字* @param  Length:数字的长度* @retval 无*/
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 + 0x30);//从最高位开始获取各位数字Serial_SendByte(Number / Serial_Pow(10,Length - i - 1) % 10 + '0');}
}int fputc(int ch,FILE *f)//重写fputc函数,将fputc重定向到串口
{Serial_SendByte(ch);return ch;
}/*** @brief  封装vsprintf可变参数* @param  * @retval 无*/
void Serial_Printf(char *format,...)
{char String[100];va_list arg;//定义参数列表变量va_start(arg , format);//从format位置接收参数表,放入arg中vsprintf(String, format ,arg);//打印位置     格式化字符串     参数表//sprintf只能接收直接写的参数,封装格式需要vsprintfva_end(arg);//释放参数表Serial_SendString(String);
}/*** @brief  获取读取完成标志位* @param  无* @retval 0:未读到数据* @retval 1:成功读到数据*/
uint8_t Serial_GetRxFlag(void)
{if(Serial_RxFlag == 1){Serial_RxFlag  = 0;//将其重新置零,并返回1return 1;}return 0;
}/*** @brief  获取接收到的数据* @param  无* @retval 接收到的数据*/
uint8_t Serial_GetRxData(void)
{return Serial_RxData;
}/*** @brief  串口1中断函数* @param  无* @retval 无*/
void USART1_IRQHandler(void)
{if(USART_GetITStatus(USART1,USART_IT_RXNE) == SET)//说明已经接收到数据{Serial_RxData = USART_ReceiveData(USART1);//转存Serial_RxFlag = 1;//读完后将自己设置标志位置一//如果此时没有读取DR,则需要手动清除标志位USART_ClearITPendingBit(USART1,USART_IT_RXNE);      }
}

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_ShowString(1,1,"RxData:");Serial_Init();while(1)    {//查询方式接收
//        while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == SET)//表示接收到数据
//        {
//            RxData = USART_ReceiveData(USART1);//当读完DR寄存器时,会自动将标志位清除
//            OLED_ShowHexNum(1,1,RxData,2);
//        }//中断方式接收if(Serial_GetRxFlag() == 1){RxData = Serial_GetRxData();OLED_ShowHexNum(1,8,RxData,2);Serial_SendByte(RxData);//数据回传}}}

串口收发HEX数据包

Serial.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;/*** @brief  串口,引脚以及中断初始化* @param  无* @retval 无*/
void Serial_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//TX引脚配置GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//为什么?查表手册推荐GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);//RX引脚配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//为什么?查表手册推荐(上拉输入)GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);//串口配置USART_InitTypeDef USART_InitStructrue;USART_InitStructrue.USART_BaudRate = 9600;//波特率配置USART_InitStructrue.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//硬件流控制(无)USART_InitStructrue.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;//串口模式(发送接收)USART_InitStructrue.USART_Parity = USART_Parity_No;//校验位(无)USART_InitStructrue.USART_StopBits = USART_StopBits_1;//停止位(1位)USART_InitStructrue.USART_WordLength = USART_WordLength_8b;//字长(8位)USART_Init(USART1,&USART_InitStructrue);//中断方式接收USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//当接收到字节时触发中断//配置NVICNVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//相应优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能通道NVIC_Init(&NVIC_InitStructure);USART_Cmd(USART1,ENABLE);//开启USART1}/*** @brief  发送一个字节* @param  Byte 发送的字节* @retval 无*/
void Serial_SendByte(uint8_t Byte)
{USART_SendData(USART1,Byte);while (USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);//完成传输之前进行空循环//TXE位置一后,会自动清除标志位,详看手册
}/*** @brief  发送一个数组* @param  Array:发送的数组* @param  Length:发送数组的长度* @retval 无*/
void Serial_SendArray(uint8_t *Array,uint16_t Length)
{uint16_t i;for(i = 0; i < Length; i ++){Serial_SendByte(Array[i]);}
}/*** @brief  发送一个字符串* @param  String:发送的字符串* @retval 无*/
void Serial_SendString(char *String)
{uint8_t i;for(i = 0; String[i] != '\0'; i ++)//判断是否为结束标志位{Serial_SendByte(String[i]);}
}/*** @brief  计算X^Y* @param  X:底数    Y:幂次* @retval Res:X^Y的结果*/
uint32_t Serial_Pow(uint32_t X,uint32_t Y)
{uint32_t Res = 1;while(Y --){Res *= X;}return Res;
}/*** @brief  发送一个无符号数字* @param  Number:发送的数字* @param  Length:数字的长度* @retval 无*/
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 + 0x30);//从最高位开始获取各位数字Serial_SendByte(Number / Serial_Pow(10,Length - i - 1) % 10 + '0');}
}int fputc(int ch,FILE *f)//重写fputc函数,将fputc重定向到串口
{Serial_SendByte(ch);return ch;
}/*** @brief  封装vsprintf可变参数* @param  * @retval 无*/
void Serial_Printf(char *format,...)
{char String[100];va_list arg;//定义参数列表变量va_start(arg , format);//从format位置接收参数表,放入arg中vsprintf(String, format ,arg);//打印位置     格式化字符串     参数表//sprintf只能接收直接写的参数,封装格式需要vsprintfva_end(arg);//释放参数表Serial_SendString(String);
}/*** @brief  将载荷数据加上包头与包尾并发送一个数据包* @param  无* @retval 无*/
void Serial_SendPacket(void)
{Serial_SendByte(0xFF);//发送包头Serial_SendArray(Serial_TxPacket,4);//发送载荷数据Serial_SendByte(0xFE);//发送包尾
}/*** @brief  读取是否接收到数据包标志位* @param  无* @retval 0:未读到数据包* @retval 1:成功读到数据包*/
uint8_t Serial_GetRxFlag(void)
{if(Serial_RxFlag == 1){Serial_RxFlag  = 0;//将其重新置零,并返回1return 1;}return 0;
}/*** @brief  串口1中断函数* @param  无* @retval 无*/
void USART1_IRQHandler(void)
{static uint8_t Rx_State = 0;static uint8_t pRx_Packet = 0;if(USART_GetITStatus(USART1,USART_IT_RXNE) == SET)//说明已经接收到数据{uint8_t Rx_Data = USART_ReceiveData(USART1);//获取读到的数据if(Rx_State == 0){if(Rx_Data == 0xFF)//接收到包头{Rx_State = 1;//转至下一状态pRx_Packet = 0;//将指针清零,为接收做准备}}else if(Rx_State == 1){Serial_RxPacket[pRx_Packet] = Rx_Data;//将接收到的数据放入缓冲区pRx_Packet ++;//指针加一if(pRx_Packet >= 4)//4个载荷数据收完{Rx_State = 2;//转至下一状态}}else if(Rx_State == 2){if(Rx_Data == 0xFE)//判断是否为包尾{Rx_State = 0;//清零,为下次做准备Serial_RxFlag= 1;//将接收一个数据包标志位置一}}USART_ClearITPendingBit(USART1,USART_IT_RXNE);//清除标志位      }
}

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();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){    Serial_TxPacket[0] ++;Serial_TxPacket[1] ++;Serial_TxPacket[2] ++;Serial_TxPacket[3] ++;  Serial_SendPacket(); 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_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);}}}
串口收发文本数据包

Serial.c

#include "stm32f10x.h"                  // Device header
#include "stdio.h"
#include "stdarg.h"char Serial_RxPacket[100];//接收缓存区
uint8_t Serial_RxFlag;/*** @brief  串口,引脚以及中断初始化* @param  无* @retval 无*/
void Serial_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//TX引脚配置GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//为什么?查表手册推荐GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);//RX引脚配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//为什么?查表手册推荐(上拉输入)GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);//串口配置USART_InitTypeDef USART_InitStructrue;USART_InitStructrue.USART_BaudRate = 9600;//波特率配置USART_InitStructrue.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//硬件流控制(无)USART_InitStructrue.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;//串口模式(发送接收)USART_InitStructrue.USART_Parity = USART_Parity_No;//校验位(无)USART_InitStructrue.USART_StopBits = USART_StopBits_1;//停止位(1位)USART_InitStructrue.USART_WordLength = USART_WordLength_8b;//字长(8位)USART_Init(USART1,&USART_InitStructrue);//中断方式接收USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//当接收到字节时触发中断//配置NVICNVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//相应优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能通道NVIC_Init(&NVIC_InitStructure);USART_Cmd(USART1,ENABLE);//开启USART1}/*** @brief  发送一个字节* @param  Byte 发送的字节* @retval 无*/
void Serial_SendByte(uint8_t Byte)
{USART_SendData(USART1,Byte);while (USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);//完成传输之前进行空循环//TXE位置一后,会自动清除标志位,详看手册
}/*** @brief  发送一个数组* @param  Array:发送的数组* @param  Length:发送数组的长度* @retval 无*/
void Serial_SendArray(uint8_t *Array,uint16_t Length)
{uint16_t i;for(i = 0; i < Length; i ++){Serial_SendByte(Array[i]);}
}/*** @brief  发送一个字符串* @param  String:发送的字符串* @retval 无*/
void Serial_SendString(char *String)
{uint8_t i;for(i = 0; String[i] != '\0'; i ++)//判断是否为结束标志位{Serial_SendByte(String[i]);}
}/*** @brief  计算X^Y* @param  X:底数    Y:幂次* @retval Res:X^Y的结果*/
uint32_t Serial_Pow(uint32_t X,uint32_t Y)
{uint32_t Res = 1;while(Y --){Res *= X;}return Res;
}/*** @brief  发送一个无符号数字* @param  Number:发送的数字* @param  Length:数字的长度* @retval 无*/
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 + 0x30);//从最高位开始获取各位数字Serial_SendByte(Number / Serial_Pow(10,Length - i - 1) % 10 + '0');}
}int fputc(int ch,FILE *f)//重写fputc函数,将fputc重定向到串口
{Serial_SendByte(ch);return ch;
}/*** @brief  封装vsprintf可变参数* @param  * @retval 无*/
void Serial_Printf(char *format,...)
{char String[100];va_list arg;//定义参数列表变量va_start(arg , format);//从format位置接收参数表,放入arg中vsprintf(String, format ,arg);//打印位置     格式化字符串     参数表//sprintf只能接收直接写的参数,封装格式需要vsprintfva_end(arg);//释放参数表Serial_SendString(String);
}/*** @brief  串口1中断函数* @param  无* @retval 无*/
void USART1_IRQHandler(void)
{static uint8_t Rx_State = 0;static uint8_t pRx_Packet = 0;//状态机if(USART_GetITStatus(USART1,USART_IT_RXNE) == SET)//说明已经接收到数据{uint8_t Rx_Data = USART_ReceiveData(USART1);//获取读到的数据if(Rx_State == 0)//接收数据包头{if(Rx_Data == '@' && Serial_RxFlag == 0)//接收到包头并且标志位为零才进行读取  {Rx_State = 1;//转至下一状态pRx_Packet = 0;//将指针清零,为接收做准备}}else if(Rx_State == 1)//接收第一包尾{if(Rx_Data == '\r')//判断是否为第一包尾{Rx_State = 2;//跳转至下一状态}else{Serial_RxPacket[pRx_Packet] = Rx_Data;//将接收到的数据放入缓冲区pRx_Packet ++;//指针加一}}else if(Rx_State == 2)//接收第二包尾{if(Rx_Data == '\n')//判断是否为第二包尾{Rx_State = 0;//清零,为下次做准备Serial_RxPacket[pRx_Packet] = '\0';//在末尾加上结束标志位Serial_RxFlag= 1;//接收一个数据包后标志位置一}}USART_ClearITPendingBit(USART1,USART_IT_RXNE);//清除接收寄存器非空标志位      }
}

main.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();LED_Init();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);if(strcmp(Serial_RxPacket,"LED_ON") == 0){LED1_On();Serial_SendString("LED_ON_OK\r\n");OLED_ShowString(2,1,"                ");OLED_ShowString(2,1,"LED_ON_OK");    }else if(strcmp(Serial_RxPacket,"LED_OFF") == 0){LED1_Off();Serial_SendString("LED_OFF_OK\r\n");OLED_ShowString(2,1,"                ");OLED_ShowString(2,1,"LED_OFF_OK");  }else{Serial_SendString("COMMAND_ERRO\r\n");OLED_ShowString(2,1,"                ");OLED_ShowString(2,1,"COMMAND_ERRO");  }Serial_RxFlag = 0;//准备接收下一个数据包}}}

注意该实验的PA^1脚起始电平需要给高电平,不然会引起你的疑惑,为何上电就亮

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

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

相关文章

车载诊断协议DoIP系列 —— OSI模型DoIP参考

车载诊断协议DoIP系列 —— OSI模型DoIP参考 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师(Wechat:gongkenan2013)。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 本就是小人物,输了就是输了,不要在意别人怎么看自己。江湖一碗茶,喝完再…

蓝桥杯-X图形

问题描述 给定一个字母矩阵。一个 X 图形由中心点和由中心点向四个 45度斜线方向引出的直线段组成&#xff0c;四条线段的长度相同&#xff0c;而且四条线段上的字母和中心点的字母相同。 一个 X 图形可以使用三个整数 r,c,L 来描述&#xff0c;其中 r,c 表示中心点位于第 r 行…

Python||数据分析之pyecharts 绘图(词云、气泡)

1. echarts 和 Pyecharts 简介 1.1echarts 简介: • echarts 是一个使用 JavaScript 实现的开源可视化库,涵盖各行业图表,满足各种需求。 • echarts 遵循 Apache-2.0 开源协议,免费商用。 • ECharts 最初由百度团队开源,并于 2018 年初捐赠给 Apache 基金会,成为 AS…

nodejs学习计划--(十)会话控制及https补充

一、会话控制 1.介绍 所谓会话控制就是 对会话进行控制 HTTP 是一种无状态的协议&#xff0c;它没有办法区分多次的请求是否来自于同一个客户端&#xff0c; 无法区分用户 而产品中又大量存在的这样的需求&#xff0c;所以我们需要通过 会话控制 来解决该问题 常见的会话控制…

OpenCV-37 最小外接矩形和最大外接矩形

一、外接矩形 外接矩形分为最小外接矩形和最大外接矩形。 下图中红色矩形为最小外接矩形&#xff0c;绿色矩形为最大外接矩形。 1. 最小外接矩形 minAreaRect(points) --- 最小外接矩形 point为轮廓&#xff1b; 返回值为元组&#xff0c;内容是一个旋转矩形(RotatedRect…

【ES】--Elasticsearch的分词器深度研究

目录 一、问题描述及分析二、analyze分析器原理三、 multi-fields字段支持多场景搜索(如同时简繁体、拼音等)1、ts_match_analyzer配置分词2、ts_match_all_analyzer配置分词3、ts_match_1_analyzer配置分词4、ts_match_2_analyzer配置分词5、ts_match_3_analyzer配置分词6、ts…

题解13-18

32. 最长有效括号 - 力扣&#xff08;LeetCode&#xff09; 给你一个只包含 ( 和 ) 的字符串&#xff0c;找出最长有效&#xff08;格式正确且连续&#xff09;括号子串的长度。 示例 1&#xff1a; 输入&#xff1a;s "(()" 输出&#xff1a;2 解释&#xff1a;…

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Divider组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之Divider组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、Divider组件 提供分隔器组件&#xff0c;分隔不同内容块/内容元素。 子组件 …

GEE:CART(Classification and Regression Trees)回归教程(样本点、特征添加、训练、精度、参数优化)

作者:CSDN @ _养乐多_ 对于分类问题,这个输出通常是一个类别标签 ,而对于回归问题,输出通常是一个连续的数值。回归可以应用于多种场景,包括预测土壤PH值、土壤有机碳、土壤水分、碳密度、生物量、气温、海冰厚度、不透水面积百分比、植被覆盖度等。 本文将介绍在Google…

python-自动化篇-终极工具-用GUI自动控制键盘和鼠标-pyautogui

文章目录 用GUI自动控制键盘和鼠标pyautogui 模块鼠标屏幕位置——移动地图——pyautogui.size鼠标位置——自身定位——pyautogui.position()移动鼠标——pyautogui.moveTo拖动鼠标滚动鼠标 键盘按下键盘释放键盘 开始与结束通过注销关闭所有程序 用GUI自动控制键盘和鼠标 在…

数据分析基础之《pandas(8)—综合案例》

一、需求 1、现在我们有一组从2006年到2016年1000部最流行的电影数据 数据来源&#xff1a;https://www.kaggle.com/damianpanek/sunday-eda/data 2、问题1 想知道这些电影数据中评分的平均分&#xff0c;导演的人数等信息&#xff0c;我们应该怎么获取&#xff1f; 3、问题…

PE 特征码定位修改程序清单 uiAccess

requestedExecutionLevel level"asInvoker" uiAccess"false" 可以修改这一行来启用禁用原程序的盾牌图标&#xff0c;似乎作用不大。以前没事写的一个小玩意&#xff0c;记录一下。 等同于这里的设置&#xff1a; 截图 代码如下&#xff1a; #include …