目录
USART串口
串口发送
串口发送+接收
串口收发HEX数据包
串口收发文本数据包
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只能接收直接写的参数,封装格式需要vsprintf
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();
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-chars
while(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);//当接收到字节时触发中断
//配置NVIC
NVIC_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只能接收直接写的参数,封装格式需要vsprintf
va_end(arg);//释放参数表
Serial_SendString(String);
}
/**
* @brief 获取读取完成标志位
* @param 无
* @retval 0:未读到数据
* @retval 1:成功读到数据
*/
uint8_t Serial_GetRxFlag(void)
{
if(Serial_RxFlag == 1)
{
Serial_RxFlag = 0;//将其重新置零,并返回1
return 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);//数据回传
}
}
}
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);//当接收到字节时触发中断
//配置NVIC
NVIC_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只能接收直接写的参数,封装格式需要vsprintf
va_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;//将其重新置零,并返回1
return 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);//当接收到字节时触发中断
//配置NVIC
NVIC_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只能接收直接写的参数,封装格式需要vsprintf
va_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脚起始电平需要给高电平,不然会引起你的疑惑,为何上电就亮