|
我是老温,一名热爱学习的嵌入式工程师) ~. |5 Q3 R- h; m+ A) V" M9 P
关注我,一起变得更加优秀!嵌入式软件开发过程中,为了提升工作效率,避免重复造轮子浪费时间,经常会复用一些C语言代码片段。
( d! b; ?# S* h- v, L O$ s以下是一些利剑级别的C语言工具代码示例,以及它们的简要讲解,分享给各位老铁,大家按需使用。
! f i) Q% ?" f3 f) x1、循环队列(Circular Buffer)# B2 L, U. ]( c. r- S7 E5 m
typedef struct {
, y1 a7 h6 _9 A) S/ E; b int buffer[SIZE];
1 W" s( X+ a6 Z; @ int head;! {; n' h- H0 w% z R
int tail;
6 I9 \/ z3 _9 j) r5 ^$ a" \3 ?; T# N5 \ int count;
7 B( Z1 \7 f) ~0 c" N# ?1 J} CircularBuffer;: x- V# ^9 r' u% P; ~9 l, w
void push(CircularBuffer *cb, int data) {
8 K, k" q/ R( A j2 i) C0 }3 F if (cb->count SIZE) {
; B( J" Q! f5 u7 T2 Z7 Z! l cb->buffer[cb->head] = data;5 e( J7 C- S. [- r
cb->head = (cb->head +1) % SIZE; {' S9 s. y2 q- f# z
cb->count++;; x/ { J4 D5 {% A9 a
}
5 |6 G8 C3 x) a ^: }: B}
4 J, D$ \) ?/ P3 G# t& Xint pop(CircularBuffer *cb) {7 z0 Z8 A. R& S; `1 v" J T* Z r
if (cb->count >0) { @* }8 B4 }3 b! D0 Q
int data = cb->buffer[cb->tail];! a( C! E( L2 ~$ C% t
cb->tail = (cb->tail +1) % SIZE;
6 R& H9 s7 Z, Z& } cb->count--;0 Z. j0 H0 k7 M$ X7 w" c, W
return data;
% R3 E; P* b1 B# I( m; r8 |! ? } P$ O! z; _; _. z/ q
return-1; // Buffer is empty
( O3 i2 n' |7 l c4 c# Q}
5 X. o; x5 @" C- B1 Q9 ]1 H2 @循环队列是一种高效的数据结构,适用于缓冲区和数据流应用,例如串口通信接收缓冲。: J* D+ \) {3 f; z
2、断言(Assertion)3 r, u& {" M9 ^! f- o
#define assert(expression) ((void)0)
, e0 A( z7 q$ A! }; d h+ A#ifndef NDEBUG
( b5 S- A# M; @; h7 u: M) \#undef assert1 a& U/ z6 b5 O' e) z
#define assert(expression) ((expression) ? (void)0 : assert_failed(__FILE__, __LINE__))& \6 j( W7 x9 y! F7 |+ o) ]; f& N
#endif# t( d h) E; D- T8 J, |8 I
void assert_failed(const char *file, int line) {. l1 m: m V4 p3 u# |$ |; Q
printf("Assertion failed at %s:%d
9 |. p( n7 c4 z", file, line);
' T" L2 P- W, V* ` // Additional error handling or logging can be added here+ J( k9 ]4 t1 S2 F) C, T8 `
}( s1 s) ~( `! M1 H( ]6 \0 ^9 X
断言用于在程序中检查特定条件是否满足,如果条件为假,会触发断言失败,并输出相关信息
9 q# M7 Z+ i5 C; A n: T9 E. d: E3、位域反转(Bit Reversal)
+ ]+ @* b! [* c' d* u/ `unsigned int reverse_bits(unsignedint num) {& L, T1 `+ Q% \5 ]" W
unsignedint numOfBits =sizeof(num) *8;
& ^6 P5 {4 N0 C% o' w' a$ J unsignedint reverseNum =0;
, j! {8 x# o, l for (unsignedint i =0; i numOfBits; i++) {6 f& A8 @- D" L0 q" G$ Y, @- ~
if (num & (1 i)) {- ^& L, t: s2 D7 [2 Y1 h2 z7 k
reverseNum |= (1 ((numOfBits -1) - i));* K4 ?$ N4 d) i6 H
}
: e: h9 h$ A, S& \ }# O; i) I: p, n# n' [2 c- J6 i
return reverseNum; x }: F9 E# Q/ I% M% }
}" F6 j q7 v o
该函数将给定的无符号整数的位进行反转,可以用于某些嵌入式系统中的位级操作需求。# ?' v) ^# i6 |' z2 d5 m! ~/ h
4、固定点数运算(Fixed-Poin Arithmetic)( m$ j, I7 ~ {6 T) z1 I
typedef int16_t fixed_t;
6 z+ j' K6 ^& n- L9 V- E. m6 L7 U% l#define FIXED_SHIFT 8
5 @; m. [" u, i" j#define FLOAT_TO_FIXED(f) ((fixed_t)((f) * (1 0 B4 I3 i6 E* S/ ]5 \" ]
#define FIXED_TO_FLOAT(f) ((float)(f) / (1 1 j! }. q8 T7 o& v
fixed_t fixed_multiply(fixed_t a, fixed_t b) {
. |; k* e) d% N1 y2 t. U return (fixed_t)(((int32_t)a * (int32_t)b) >> FIXED_SHIFT);! y4 p+ q: c- E- \0 U" \
}: C1 m' |( T7 S J5 H* ~0 K9 ~ e
在某些嵌入式系统中,浮点运算会较慢或不被支持。因此,使用固定点数运算可以提供一种有效的浮点数近似解决方案。
) F. h2 ?: `4 V5、字节序转换(Endianness Conversion)8 `* O5 D2 \9 T- C2 C( y& h7 i/ v
uint16_t swap_bytes(uint16_t value) { return (value >> 8) | (value 8); }用于在大端(Big-Endian)和小端(Little-Endian)字节序之间进行转换的函数。
( |$ k1 H$ ?; d# l a- V6、位掩码(Bit Masks)
0 c% q0 X$ B$ ~6 c' p#define BIT_MASK(bit) (1 1 Z o% n& a7 A9 x
用于创建一个只有指定位被置位的位掩码,可用于位操作。
& l5 R) N. T) x1 x7、计数器计数(Timer Counting)
: L$ r1 ^ i# E( r#include
( a& S5 d4 u/ Evoid setup_timer() {
v+ O8 E$ ]$ Q. @' r // Configure timer settings
* M F% K0 y9 \6 ^8 B}
' h$ G$ _' Y) z& [uint16_t read_timer() {
6 M# h9 @" ~4 [8 c0 Q% x" X return TCNT1;5 b3 I: T8 b Z5 J8 {. y6 w9 s
}, s" X2 }2 [4 ~1 G1 ^5 a2 {
在AVR嵌入式系统中,使用计时器(Timer)来实现时间测量和定时任务。5 o+ S" C; R( b$ x2 y6 B
8、二进制查找(Binary Search)% Y- F( L/ b7 \) b, J' ~
int binary_search(int arr[], int size, int target) {1 b3 k2 k: K6 ^/ Q
int left =0, right = size -1;( z$ U3 j) l2 |' A
while (left right) { s' B# l! _' G# F, q. c0 \
int mid = left + (right - left) /2;
1 Q, n" e# T) b+ F if (arr[mid] == target) {
1 z) W( F: C) C* v return mid;
; h: b6 B, T9 m2 z } elseif (arr[mid] target) {
" M7 m; \2 T* K left = mid +1;
: w, y+ D6 k/ L } else {* L5 ?5 o" v0 d- B
right = mid -1;
3 B# K$ c# W# ?2 [5 i- f) F }& O& \4 U7 k; n0 J! g
}( C& T9 U+ O% X! [0 _6 K; B0 e; w, x
return-1; // Not found
+ t- Y( m" s5 @5 b; \6 @$ K( s, K}2 `- b( J" u3 D7 z7 j# J6 C9 I9 _
用于在已排序的数组中执行二进制查找的函数。+ q; ?. [8 K1 K9 K, p
9、位集合(Bitset)
& I: B; ?! p( Q+ d3 b1 {" I( O#include # I' ], g' v# ^* B- y
typedefstruct {
i; c4 y" [" R4 e uint32_t bits;
/ t- l: J. y1 o; [- Q, Z% A} Bitset;
( F9 i1 H2 C2 e$ p6 |$ v8 w6 g) jvoid set_bit(Bitset *bitset, int bit) {
% T: m7 N0 h, Q o( | bitset->bits |= (1U bit);8 I: e. ?& a4 B- b+ }
}3 n% J" i [2 U4 {5 P( U& x
int get_bit(Bitset *bitset, int bit) {! }+ x) }% [3 T* u) O# A2 L
return (bitset->bits >> bit) &1U;/ m1 S) h ]' a8 v' S, N
}
; F8 y% }9 H( I2 B实现简单的位集合数据结构,用于管理一组位的状态。/ @1 g, c7 m! G/ |' _
这些代码示例代表了嵌入式开发中常用的一些利剑级别的C语言工具代码。它们在嵌入式系统开发中具有广泛的应用,有助于优化性能、节省资源并提高代码的可维护性。
$ z& y9 j4 o" ]2 t& [来源 | 知乎-晓亮Albert0 S! P4 h5 S; R
-END-9 d8 h( k* X& y+ }
往期推荐:点击图片即可跳转阅读( `. @! B! j( }
phbos4l5rwh64014340709.jpg
6 _0 d# A: ^8 I5 b( u; t7 U3 i1 z
最近在画图,电源稳定性对嵌入式硬件设备来说,实在是太重要了!
) L! D9 j$ X8 c( U6 R
shb5rn5ppue64014340809.jpg
$ X% M6 P" c, b4 F3 P$ G
嵌入式设备能在LCD屏幕上显示中文,是基于什么原理?! D+ ~6 _7 K/ H! ?/ c9 B
5kfpsuosmv164014340909.jpg
* }7 w+ A7 G. K嵌入式软件,代码的可读性与可运行性,哪个更重要? H; V; I" n/ h P! T* n, X
我是老温,一名热爱学习的嵌入式工程师
; S+ N. n# \6 ^. S$ R7 ~+ I9 V' f关注我,一起变得更加优秀! |
|