嵌入式常见的C语言处理代码

以下为未调试代码,使用时候,请注意调试

循环队列(Circular Buffer):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
#include <stdint.h>
#include <string.h>

#define RX_BUFF 500
#define TX_BUFF 500


typedef struct _CircularBuffer__
{
uint8_t RXbuffer[RX_BUFF]; /* 接收缓冲区 */
uint8_t TXbuffer[TX_BUFF]; /* 发送缓冲区 */
uint32_t RXhead; /* 接收数据头 */
uint32_t RXtail; /* 接收数据尾部 */
uint32_t RXlen; /* 本次接收数据的长度 */
uint32_t RXbuffersize; /* 接收数据缓冲区大小 */
uint32_t TXhead; /* 发送数据头 */
uint32_t TXtail; /* 发送数据尾部 */
uint32_t TXlen; /* 本次发送数据的长度 */
uint32_t TXbuffersize; /* 发送数据缓冲区大小 */
} CircularBuffer;

CircularBuffer XXDeviceData;

/**
* @brief 循环器对象初始化
*
* @param Circularobject 循环器对象
* @param RXbuffersize 循环器接收数据缓冲区大小
* @param TXbuffersize 循环器发送数据缓冲区大小
*/
void Circular_Init(CircularBuffer *Circularobject,uint32_t RXbuffersize,uint32_t TXbuffersize)
{
memset(Circularobject,0,sizeof(Circularobject));
Circularobject->RXbuffersize = RXbuffersize;
Circularobject->TXbuffersize = TXbuffersize;
}

/**
* @brief 循环器接收区域读取数据
* 数据量多时候使用该函数
* @param Circularobject 循环器对象
* @param ReadNData 读取数据个数
* @param Dst_data 读取数据存入目标
* @return uint8_t 1 读取成功 0读取失败
*/
uint8_t Circular_ReadData(CircularBuffer *Circularobject,uint32_t ReadNData,uint8_t * Dst_data)
{
uint32_t i = 0;
uint32_t temp_ReadNData = (Circularobject->RXlen > ReadNData)? ReadNData:Circularobject->RXlen; /* 当读取数据小于现有数据长度时候,读取指定长度数据,当读取数据大于现有数据时候,读取现有数据长度 */
uint8_t * src_data = Circularobject->RXbuffer + Circularobject->RXhead; /* 读取数据起始地址 */
uint32_t CircularData_len1 = Circularobject->RXhead + temp_ReadNData; /* 读取完数据后,起始地址位置到哪了 */
uint32_t CircularData_len2 = (Circularobject->RXbuffersize > CircularData_len1)?CircularData_len1:Circularobject->RXbuffersize; /* 判断当前读取的数据是否超过了缓冲区最大的长度 */

if((!temp_ReadNData)||(!Dst_data)) /* 无数据 */
{
return 0;
}

Circularobject->RXlen -= temp_ReadNData;

if(CircularData_len1 != CircularData_len2) /* 是否到了结束地址 */
{
for(i = Circularobject->RXhead;i<CircularData_len2;i++)
{
*Dst_data++ = *src_data++;
}
CircularData_len1 -= CircularData_len2;
Circularobject->RXhead = 0;
}

for(i = Circularobject->RXhead;i<CircularData_len1;i++)
{
*Dst_data++ = *src_data++;
}

Circularobject->RXhead = i;
Circularobject->RXhead %= Circularobject->RXbuffersize;
return 1;
}

/**
* @brief 读取循环器接收区域前面第一个数据
*
* @param Circularobject 循环器对象
* @return uint8_t 返回数据
*/
uint8_t Circular_popfront(CircularBuffer *Circularobject)
{
uint8_t data = 0;
if(Circularobject->RXlen)
{
Circularobject->RXlen--;
Circularobject->RXhead %= Circularobject->RXbuffersize;
data =Circularobject->RXbuffer[Circularobject->RXhead++];
return data;
}
return 0;
}

/**
* @brief 循环器接收区域写入数据
* 数据量多时候使用该函数
* @param Circularobject 循环器对象
* @param WriteNData 写入N个数据
* @param src_data 数据源
* @return uint8_t 1 写入成功 0写入失败
*/
uint8_t Circular_WriteData(CircularBuffer *Circularobject,uint32_t WriteNData,uint8_t * src_data)
{
uint32_t i = 0;
uint32_t temp_WriteNData = (Circularobject->RXbuffersize > WriteNData)?WriteNData:Circularobject->RXbuffersize;
uint8_t * Dst_data = Circularobject->RXbuffer + Circularobject->RXtail; /* 写入数据起始地址 */
uint32_t CircularData_len1 = Circularobject->RXtail + temp_WriteNData; /* 写入数据后,起始地址位置到哪了 */
uint32_t CircularData_len2 = (Circularobject->RXbuffersize > CircularData_len1)?CircularData_len1:Circularobject->RXbuffersize; /* 判断当前写入的数据是否超过了缓冲区最大的长度 */

if((!temp_WriteNData)||(!src_data)) /* 无数据 */
{
return 0;
}

Circularobject->RXlen = temp_WriteNData;

if(CircularData_len1 != CircularData_len2)
{
for (i = Circularobject->RXtail; i < CircularData_len2; i++)
{
*Dst_data++ =*src_data++;
}
CircularData_len1 -= CircularData_len2;
Circularobject->RXtail = 0;
}

for(i = Circularobject->RXtail;i<CircularData_len1;i++)
{
*Dst_data++ = *src_data++;
}

Circularobject->RXtail = i;
Circularobject->RXtail %= Circularobject->RXbuffersize;
return 1;
}

/**
* @brief 写入循环器接收区域下一个位置数据
*
* @param Circularobject 循环器对象
* @param src_data 待写入数据
*/

/**
* @brief 写入循环器接收区域下一个位置数据
*
* @param Circularobject 循环器对象
* @param src_data 待写入数据
* @return uint8_t 写入是否成功
*/
uint8_t Circular_pushback(CircularBuffer *Circularobject,uint8_t src_data)
{
if(Circularobject->RXlen < Circularobject->RXbuffersize)
{
Circularobject->RXtail %= Circularobject->RXbuffersize;
Circularobject->RXbuffer[Circularobject->RXtail++] = src_data;
Circularobject->RXlen++;
return 1;
}
return 0;
}

/**
* @brief 循环器接收缓冲区是否为空
*
* @param Circularobject 循环器对象
* @return uint8_t 1 空 0非空
*/
uint8_t Circular_is_Empty(CircularBuffer *Circularobject)
{
if(!Circularobject->RXlen)
{
return 1;
}
else
{
return 0;
}
}

void ddd(CircularBuffer *Circularobject)
{
Circularobject->RXtail = Circularobject->RXbuffersize - NUMBER(某个设备传过来数据的长度,那个设备数据直接到缓冲区了);
if(Circularobject->RXtail >= Circularobject->RXhead)
{
Circularobject->RXlen = Circularobject->RXtail - Circularobject->RXhead;
}
else
{
Circularobject->RXlen = Circularobject->RXtail + Circularobject->RXbuffersize - Circularobject->RXhead;
}

if( Circularobject->RXlen >= Circularobject->RXbuffer )
{
Circularobject->RXlen = 0;
}
}

断言(Assertion):

1
2
3
4
5
6
7
8
9
10
11
#ifdef DEBUG
#define assert(expression) ((expression) ? (void)0 : assert_failed(__FILE__, __LINE__))
#elif
#define assert(expression) ((void)0)
#endif

void assert_failed(const char *file, int line) {
printf("Assertion failed at %s:%d\n", file, line);
// Additional error handling or logging can be added here
}

断言用于在程序中检查特定条件是否满足,如果条件为假,会触发断言失败,并输出相关信息

位域反转(Bit Reversal):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdint.h>

uint32_t reverse_bits(uint32_t num)
{
uint32_t numOfBits = sizeof(num) * 8;
uint32_t reverseNum = 0;
uint32_t i = 0;

for (i = 0; i < numOfBits; i++)
{
if (num & (1 << i))
{
reverseNum |= (1 << ((numOfBits - 1) - i));
}
}
return reverseNum;
}

该函数将给定的无符号整数的位进行反转,可以用于某些嵌入式系统中的位级操作需求。

字节序转换(Endianness Conversion):

1

用于在大端(Big-Endian)和小端(Little-Endian)字节序之间进行转换的函数。按照字节排序即可

位掩码(Bit Masks):

1

用于创建一个只有指定位被置位的位掩码,可用于位操作。

二进制查找(Binary Search):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int binary_search(int arr[], int size, int target) {
int left = 0, right = size - 1;

while (left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid] == target) {
return mid;
} else if (arr[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1; // Not found
}

用于在已排序的数组中执行二进制查找的函数。

位集合(Bitset):

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdint.h>

typedef struct {
uint32_t bits;
} Bitset;

void set_bit(Bitset *bitset, int bit) {
bitset->bits |= (1U << bit);
}

int get_bit(Bitset *bitset, int bit) {
return (bitset->bits >> bit) & 1U;
}

实现简单的位集合数据结构,用于管理一组位的状态。