发送方式1:自己的printf
#define DATA_MAX_SIZE 20
#define USING_USART USART3
void USART3_Printf(char* format,...)
{
char DataBuf[DATA_MAX_SIZE];
va_list start;
va_start(start,format);
vsprintf(DataBuf,format,start);
va_end(start);
uint8_t pDataBuf=0;
while (DataBuf[pDataBuf]!='\0')
{
USART_SendData(USING_USART,DataBuf[pDataBuf]);
while(USART_GetFlagStatus(USING_USART,USART_FLAG_TXE)==RESET);
pDataBuf++;
/* code */
}
}
发送方式2:重定向printf
#include "stdio.h"
#define USING_USART USART3
void Serial_SendByte(uint8_t Byte)
{
USART_SendData(USING_USART, Byte); //将字节数据写入数据寄存器,写入后USART自动生成时序波形
while (USART_GetFlagStatus(USING_USART, USART_FLAG_TXE) == RESET); //等待发送完成
/*下次写入数据寄存器会自动清除发送完成标志位,故此循环后,无需清除标志位*/
}
int fputc(int ch, FILE *f)
{
Serial_SendByte(ch); //将printf的底层重定向到自己的发送字节函数
return ch;
}
接受不定长数据方式1:利用中断和状态机
#define RxFlag_START '#'
#define RxFlag_END1 '\r'
#define RxFlag_END2 '\n'
uint8_t Serial_RxFlag=0;
char Data_Array[100];
void USART3_IRQHandler(void)
{
static uint8_t RxState=0;
static uint8_t pRxPacket=0;
if (USART_GetITStatus(USART3,USART_IT_RXNE)==SET)
{
char Data;
Data=USART_ReceiveData(USART3);
if (!Serial_RxFlag)
{
if (RxState==0)
{
if(Data==RxFlag_START)
{
RxState=1;
pRxPacket=0;
}
}
else if (RxState==1)
{
if (Data==RxFlag_END1)
{
RxState=2;
}
else
{
Data_Array[pRxPacket]=Data;
pRxPacket++;
}
}
else if (RxState==2)
{
if (Data==RxFlag_END2)
{
RxState=0;
Serial_RxFlag=1;
Data_Array[pRxPacket]='\0';
}
}
}
}
USART_ClearITPendingBit(USART3,USART_IT_RXNE);
}
FlagStatus Data_Deal(void)//数据的处理可以自定义,我这里仅仅返回了标志位而已
{
uint8_t temp;
temp=Serial_RxFlag;
Serial_RxFlag=0;
return temp;
}
接收不定长数据方式2:利用接收中断和空闲中断(RXNE和IDLE)
uint8_t Rxbuffer[64]={0};//接收缓冲
uint8_t pRxbuf=0;
uint8_t RxFlag=0;//接收标志
void USART1_IRQHandler(void)
{
if (USART_GetITStatus(USART1,USART_IT_RXNE)==SET)
{
Rxbuffer[pRxbuf++]=(uint8_t)USART1->DR;
}
if (USART_GetITStatus(USART1,USART_IT_IDLE)==SET)
{
RxFlag=1;
//下面两句清除IDLE标志位
USART_ReceiveData(USART1);
USART_ClearITPendingBit(USART1,USART_IT_IDLE);
}
}
uint8_t UART_Read(uint8_t *pbuf)//把数据放入传来的数组,并返回接收到的数据长度
{
if (RxFlag)
{
uint8_t size;
RxFlag=0;
for (uint8_t i = 0; i < pRxbuf; i++)
{
pbuf[i]=Rxbuffer[i];
}
size=pRxbuf;
pRxbuf=0;
return size;
}
else
return 0;
}
接收不定长数据方式3:利用FIFO缓冲,DMA中断和UART中断(这个方式也可以用作发送)
参考文章:一个严谨的STM32串口DMA发送&接收(1.5Mbps波特率)机制_一个严谨的串口dma-CSDN博客
代码数量较大,上文作者代码仓库有详细案例