对于程序员来说,数据结构真的很重要,但是对于单片机程序员来说,很多人可能都是非计算机科班出生,数据结构都是自学的。至少我自动化本科的课程是没有数据结构的课程的,如果说有的话,便是我已经还给老师了,哈哈哈。
队列,链表,类,结构体,联合体,二叉树等等都是嵌入式常用的数据结构。
在毕业后的工作岗位上,我也get到了一个非常好用的数据结构使用方法:联合体+结构体的方式,具体定义如下。
#define SIZE (28U)
typedef union
{
INT8U buf[SIZE];
struct
{
INT32U a[3];
INT16S b[3];
INT8U res[8];
INT16U cs;
}bits;
}MY_PARM;
这么定义的好处是,如果我想一次性赋值给所有变量,可以直接MY_PARM.buf,如果单独修改某一个参数,可以MY_PARM.bits. a[2],可以说是超级方便。大家说说这么定义还有什么好处?
另外,在单片机程序开发中经常使用的数据结构还有环形队列。这个网上资料也超多,这里不多说,索性这里学以致用,写一个使用联合体+结构体实现的环形队列。
#define EVENT_SIZE (12U)
typedef union
{
INT8U val8[EVENT_SIZE];
struct
{
INT8U type;
INT8U idxL;
INT8U idxH;
INT8U value;
INT8U time[8];
}bits;
}RECORD;
#define MaxBufferSize 64
typedef struct
{
RECORD record[MaxBufferSize];
INT8U Put;
INT8U Get;
}RECORD _BUFF;
RECORD _BUFF record_buff;
RECORD info[MAX_CHANNEL];
/**********************************************/
/*判断缓冲区是否为空*/
//参数:无
//返回值:空返回TRUE,非空返回FALSE
/**********************************************/
INT8U BufferEmpty( void )
{
RECORD _BUFF *buff;
buff = record_buff;
if( buff->Put==buff->Get )
{
return TRUE;
}
return FALSE;
}
/**********************************************/
/*判断缓冲区是否为满*/
//采用牺牲一个元素空间的方式
//参数:无
//返回值:满返回TRUE,未满则返回FALSE
/**********************************************/
INT8U BufferFull(void)
{
RECORD _BUFF *buff;
buff = record_buff;
if( ( buff->Put+1 )%MaxBufferSize==buff->Get )
{
return TRUE;
}
return FALSE;
}
/**********************************************/
/*从缓冲区中读信息函数*/
//参数:无
/* 从环形缓冲区中取元素 */
/* 有几个元素取几个元素 */
//返回值:无
/**********************************************/
void ReadBuffer(void)
{
RECORD _BUFF *buff;
buff = & record_buff;
if( FALSE==BufferEmpty( ) )
{
memcpy( &data,&buff->record[buff->Get], 12U );
buff->Get=( INT8U ) ( ( buff->Get+1 )%MaxBufferSize );//读指针后移
}
}
/**********************************************/
/*把ID号为i的信息写到缓存里面*/
//参数:ID号
/* 向环形缓冲区buff中放入一个元素*/
//返回值:无
/**********************************************/
void WriteBuffer(INT8U i)
{
RECORD _BUFF *buff;
RECORD *temp;
buff = & record_buff;
temp = & info[i];
memcpy( &buff->record[buff->Put], temp, 12U );//
buff->Put=( INT8U ) ( ( buff->Put+1 )%MaxBufferSize );
}