60、UART任意时间缓冲打印信息--解决写代码调试时中断中打印信息问题
2023-12-23 20:52:02
/**********************************************************************
*file:UART任意时间缓冲打印信息–解决写代码调试时中断中打印信息问题
*author:残梦
*versions:V1.0
*date:2023.12.23
note:
方案:创建一个缓冲区,任意时间添加数据至缓冲区保存,空闲时自动发送数据;
此方案有个弊端,中断过快会导致丢失数据,两个中断优先级不同的任务都添加数据时会出现乱码,因为缓冲区只有一个。
使用方法:
1、修改缓冲区大小+内存分配方式
#define dSendBuffer_BufferSize (10245)//缓冲区大小
#define dMemoryType //定义–静态分配;屏蔽–动态分配
2、初始化缓冲区
int32_t SendBuffer_init(uint32_t size)
3、需要的发送数据添加至缓冲区
int32_t SendBuffer_add(uint8_t *pdata);
4、空闲处发送数据
void SendBuffer_IdleSend(void);
5、动态分配时,销毁资源(不再使用这个方案)
void SendBuffer_free(void);
**********************************************************************/
SendBuffer.h
#ifndef _SendBuffer_H_
#define _SendBuffer_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "main.h"
#define dSendBuffer_BufferSize (1024*5)//缓冲区大小:不得低于64字节;建议随发送数据的频率适当增加,避免掉数据
//#define dMemoryType //定义--静态分配;屏蔽--动态分配
int32_t SendBuffer_init(uint32_t size);
int32_t SendBuffer_add(uint8_t *pdata);
void SendBuffer_IdleSend(void);
void SendBuffer_free(void);
#ifdef __cplusplus
}
#endif
#endif
SendBuffer.c
/**********************************************************************
*file:UART任意时间缓冲打印信息--解决写代码调试时中断中打印信息问题
*author:残梦
*versions:V1.0
*date:2023.12.23
*note:
方案:创建一个缓冲区,任意时间添加数据至缓冲区保存,空闲时自动发送数据;
此方案有个弊端,中断过快会导致丢失数据,两个中断优先级不同的任务都添加数据时会出现乱码,因为缓冲区只有一个。
使用方法:
1、修改缓冲区大小+内存分配方式
#define dSendBuffer_BufferSize (1024*5)//缓冲区大小
#define dMemoryType //定义--静态分配;屏蔽--动态分配
2、初始化缓冲区
int32_t SendBuffer_init(uint32_t size)
3、需要的发送数据添加至缓冲区
int32_t SendBuffer_add(uint8_t *pdata);
4、空闲处发送数据
void SendBuffer_IdleSend(void);
5、动态分配时,销毁资源(不再使用这个方案)
void SendBuffer_free(void);
7、修改接口#define dUART_DMA_TX(pData,size)
**********************************************************************/
#include "SendBuffer.h"
#include "usart.h"
#define dSOURCE_LIST 6//资源列表种类个数
#define dUART_DMA_TX(pData,size) {\
while(huart1.gState != HAL_UART_STATE_READY)HAL_Delay(1);\
HAL_UART_Transmit_DMA(&huart1,pData,size);\
}
#define dMemoryConversion_Unit_String(x) ((x < 1024)?"Bytes":((x < 1024*1024)?"KB":"MB"))
#define dMemoryConversion_Unit_Value(x) ((x < 1024)?(float)x:((x < 1024*1024)?(x/1024.0f):(x/1024.0f/1024.0f)))
typedef struct
{
uint8_t *pbuf;
uint32_t size;
uint32_t pos_write;
uint32_t pos_read;
}DataPacket_StructDef;
static DataPacket_StructDef DataPacket = {.pbuf = NULL,.size = 0,.pos_write = 0,.pos_read = 0};
#ifdef dMemoryType
static uint8_t xDataBuffer[dSendBuffer_BufferSize] = {0};
#endif
/****************************************
@function:发送缓冲初始化
@param:void
@return:-1--失败,0--成功
@note:
****************************************/
int32_t SendBuffer_init(uint32_t size)
{
if(size < 64)return -1;
printf("%s:Buffer:%.3f %s\n",__func__,dMemoryConversion_Unit_Value(size),dMemoryConversion_Unit_String(size));
#ifdef dMemoryType
DataPacket.pbuf = xDataBuffer;
#else
DataPacket.pbuf = (uint8_t *)malloc(size);
#endif
if(DataPacket.pbuf == NULL)
{
printf("%s:memory allocation failure\n",__func__);
return -1;
}
memset(DataPacket.pbuf,0,size);
DataPacket.size = size;
DataPacket.pos_write = 0;
DataPacket.pos_read = 0;
return 0;
}
/****************************************
@function:添加数据至发送缓冲
@param:void
@return:-1--失败,0--成功
@note:
****************************************/
int32_t SendBuffer_add(uint8_t *pdata)
{
uint32_t len = 0,w = 0,pos = 0;
if((pdata == NULL) || (DataPacket.size == 0))return -1;
len = strlen((char *)pdata);
if(len == 0)return -1;
w = 0;
pos = DataPacket.pos_write;
while(w < len)
{
DataPacket.pbuf[pos++] = pdata[w++];
if(pos >= DataPacket.size)pos = 0;
}
DataPacket.pos_write = pos;
return 0;
}
/****************************************
@function:空闲时发送缓冲区数据
@param:void
@return:void
@note:
****************************************/
void SendBuffer_IdleSend(void)
{
uint32_t pos = 0;
pos = DataPacket.pos_write;
if(pos == DataPacket.pos_read)return;//缓冲区空
if(pos > DataPacket.pos_read)
{
dUART_DMA_TX(&DataPacket.pbuf[DataPacket.pos_read],(pos - DataPacket.pos_read));
DataPacket.pos_read = pos;
}
else
{
if(DataPacket.pos_read < (DataPacket.size - 1)) dUART_DMA_TX(&DataPacket.pbuf[DataPacket.pos_read],(DataPacket.size - DataPacket.pos_read));
dUART_DMA_TX(&DataPacket.pbuf[0],pos);
DataPacket.pos_read = pos;
}
}
/****************************************
@function:发送缓冲释放销毁
@param:void
@return:void
@note:
****************************************/
void SendBuffer_free(void)
{
#ifndef dMemoryType
if(DataPacket.pbuf == NULL)return;
DataPacket.size = 0;
DataPacket.pos_write = 0;
DataPacket.pos_read = 0;
free(DataPacket.pbuf);
#endif
}
使用宏的方式配合使用更佳:
#define dLOGG(str) {\
sprintf((char *)Tx_Buffer_DMA,"%s\n%c",str,'\0');\
SendBuffer_add(Tx_Buffer_DMA);\
}
#define dLOGG_FUN_LINE() {\
sprintf((char *)Tx_Buffer_DMA,"%s--%d\n%c",__func__,__LINE__,'\0');\
SendBuffer_add(Tx_Buffer_DMA);\
}
#define dLOGG_FUN_LINE_String(str) {\
sprintf((char *)Tx_Buffer_DMA,"%s--%d:%s\n%c",__func__,__LINE__,str,'\0');\
SendBuffer_add(Tx_Buffer_DMA);\
}
实现printf函数
int fputc(int ch,FILE *f)
{
unsigned char temp[1] = {ch};
HAL_UART_Transmit(&huart1,temp,1,2);
return(ch);
}
测试:
#define dSendBuffer_BufferSize (100)//缓冲区大小:不得低于64字节;建议随发送数据的频率适当增加,避免掉数据
//#define dMemoryType //定义--静态分配;屏蔽--动态分配
if(SendBuffer_init(dSendBuffer_BufferSize) < 0)Error_Handler();
uint32_t i = 0;
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
SendBuffer_add("012345678\n");
SendBuffer_IdleSend();
HAL_Delay(1);
if(++i >= 10000)
while(1);
}
测试验证正常情况下没有丢数据现象,但是小心中断同时输入数据会数据错乱问题
文章来源:https://blog.csdn.net/qq_36561846/article/details/135168818
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!