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.mzph.cn/news/680363.shtml

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

相关文章

HTML 超文本标记语言

超文本标记语言 HTML 在一个客户程序主窗口上显示出的万维网文档称为页面 (page)。 页面制作的标准语言&#xff1a;HTML。 超文本标记语言 HTML (HyperText Markup Language) 是一种制作万维网页面的标准语言&#xff0c;它消除了不同计算机之间信息交流的障碍&#xff0c…

SQLyog安装配置(注册码)连接MySQL

下载资源 博主给你打包好了安装包&#xff0c;在网盘里&#xff0c;只有几Mb&#xff0c;防止你下载到钓鱼软件 快说谢谢博主&#xff08;然后心甘情愿的点个赞~&#x1f60a;&#xff09; SQLyog.zip 安装流程 ①下载好压缩包后并解压 ②打开文件夹&#xff0c;双击安装包 ③…

GPT 3.5 真的比 4.0聪明吗?

GPT 3.5 真的比 4.0聪明吗&#xff1f; DeepGo 计算机杂谈及深度学习记录&分享 在大语言模型大杀四方的今天 无论是哪个行业的工作人员 都用上了各种各样的模型 其中的佼佼者就是 ChatGPT! 众所周知 ChatGPT是有氪金的Plus4.0版本 那3.5真的不如4.0吗&#xff1f; 今天 我们…

【51单片机】DS18B20(江科大)

一、DS18B20温度传感器 1.DS18B20介绍 DS18B20是一种常见的数字温度传感器,其控制命令和数据都是以数字信号的方式输入输出,相比较于模拟温度传感器,具有功能强大、硬件简单、易扩展、抗干扰性强等特点 测温范围 :- 55℃到125℃ 通信接口:1-Wire(单总线) 其它特征:可形成…

【MySQL进阶之路】亿级数据量表SQL调优实战

欢迎关注公众号&#xff08;通过文章导读关注&#xff1a;【11来了】&#xff09;&#xff0c;及时收到 AI 前沿项目工具及新技术的推送&#xff01; 在我后台回复 「资料」 可领取编程高频电子书&#xff01; 在我后台回复「面试」可领取硬核面试笔记&#xff01; 文章导读地址…

Swift Combine 发布者订阅者操作者 从入门到精通二

Combine 系列 Swift Combine 从入门到精通一 1. Combine核心概念 你只需要了解几个核心概念&#xff0c;就能使用好 Combine&#xff0c;但理解它们非常重要。 这些概念中的每一个都通过通用协议反映在框架中&#xff0c;以将概念转化为预期的功能。 这些核心概念是&#x…

通过增加缓存优化斐波那契递归的冗余计算

一、python 斐波那契数列的递归实现存在大量的冗余计算。例如&#xff0c;为了计算fib(n)&#xff0c;我们需要计算fib(n-1)和fib(n-2)&#xff0c;但是在计算fib(n-1)的过程中&#xff0c;我们又会重复计算fib(n-2)。当n的值很大时&#xff0c;这种冗余计算会消耗大量的计算资…

肿瘤微环境异质性对治疗反应的影响(综述)

Influence of tumour micro-environment heterogeneity on therapeutic response | Nature 肿瘤的形成涉及肿瘤细胞与细胞外基质、肿瘤血管和免疫细胞的共同进化。肿瘤的成功生长和最终转移并不完全取决于肿瘤细胞的基因改变&#xff0c;还取决于这种突变在特定环境中带来的适…

AMD FPGA设计优化宝典笔记(3)控制集

控制集 1 控制集的个数要求 控制集 control set&#xff1a;因为 7 系列 FPGA&#xff0c;一个 slice 只能有一种控制集&#xff08;触发器的使用方式 比如有复位/有时钟使能等等&#xff09;&#xff0c;多了就会分布到不同的 slice 里&#xff0c; 所以代码尽量统一触发器的…

2.12 分支、循环练习

1、选择题 1.1、以下程序的输出结果是 A 。 main() { int k11,k22,k33,x15; if(!k1) x--; else if(k2) if(k3) x4; else x3; printf(“x%d\n”,x); } A x4 B x15 C x14 D x3 解析&#xff1a;if(!k1) x--; 检查 k1 是否为0。因为 k1 的值为1&#xff0c;所…

嵌入式Qt Qt Creator安装与工程介绍

一.Qt概述 什么是Qt&#xff1a;Qt是一个跨平台的C图形用户界面应用程序框架。它为应用程序开发者提供建立图形界面所需的所有功能。它是完全面向对象的&#xff0c;很容易扩展&#xff0c;并且允许真正的组件编程。 二.Qt Creator下载安装 下载地址&#xff1a;Index of /a…

如何编译zlib?

学习文章&#xff1a;windows zlib库编译步骤_nmake 编译 zlib-CSDN博客 记录关键步骤&#xff1a; 打开 执行&#xff1a; 先cd到该目录&#xff1a; C:\Users\xxx\Downloads\zlib-1.2.11\contrib\masmx86 (这是我的zlib源码的下载路径&#xff09; 执行bld_ml32.bat 再…

【每日一题】03 不同路径Ⅱ(DP2)

问题描述 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish”&#xff09;。 现在考虑网格中有障碍物。那么从左上…

LeetCode.145. 二叉树的后序遍历

题目 145. 二叉树的后序遍历 分析 上篇文章我们讲了前序遍历&#xff0c;这道题目是后序遍历。 首先要知道二叉树的后序遍历是什么&#xff1f;【左 右 根】 然后利用递归的思想&#xff0c;就可以得到这道题的答案&#xff0c;任何的递归都可以采用 栈 的结构来实现&#…

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

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

【Tauri】(2):使用Tauri应用开发,使用开源的Chatgpt-web应用做前端,使用rust 的candle做后端,本地运行小模型桌面应用

视频演示地址 https://www.bilibili.com/video/BV17j421X7Zc/ 【Tauri】&#xff08;2&#xff09;&#xff1a;使用Tauri应用开发&#xff0c;使用开源的Chatgpt-web应用做前端&#xff0c;使用rust 的candle做后端&#xff0c;本地运行小模型桌面应用 1&#xff0c;做一个免…

ClickHouse--03--数据类型

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 数据类型1. Int2.FloattoFloat32(...) 用来将字符串转换成 Float32 类型的函数toFloat64(...) 用来将字符串转换成 Float64 类型的函数 3.DecimaltoDecimal32(value…

视觉开发板—K210自学笔记(五)

本期我们来遵循其他单片机的学习路线开始去用板子上的按键控制点亮LED。那么第一步还是先知道K210里面的硬件电路是怎么连接的&#xff0c;需要查看第二节的文档&#xff0c;看看开发板原理图到底是按键是跟哪个IO连在一起。然后再建立输入按键和GPIO的映射就可以开始变成了。 …

Linux第48步_编译正点原子的出厂Linux内核源码

编译正点原子的出厂 Linux 内核源码&#xff0c;为后面移植linux做准备。研究对象如下&#xff1a; 1)、linux内核镜像文件“uImage” 路径为“arch/arm/boot”&#xff1b; 2)、设备树文件“stm32mp157d-atk.dtb” 路径为“arch/arm/boot/dts” 3)、默认配置文件“stm32m…

C++入门篇——类与对象重点解析(中篇)

1. 类的6个默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为空类。 空类中真的什么都没有吗&#xff1f;并不是&#xff0c;任何类在什么都不写时&#xff0c;编译器会自动生成以下6个默认成员函数。 class Date {}; 默认成员函数&#xff1a;用户没有显式实现&a…