电子产业一站式赋能平台

PCB联盟网

搜索
查看: 133|回复: 0
收起左侧

嵌入式C语言编程,一些非常有用的代码片段合集!

[复制链接]

568

主题

568

帖子

4221

积分

四级会员

Rank: 4

积分
4221
发表于 2025-3-25 08:00:00 | 显示全部楼层 |阅读模式
我是老温,一名热爱学习的嵌入式工程师; D% l3 A8 m4 q' L2 s) c
关注我,一起变得更加优秀!嵌入式软件开发过程中,为了提升工作效率,避免重复造轮子浪费时间,经常会复用一些C语言代码片段。
# m. O0 [& J; V8 u) P) S; i3 v; ]以下是一些利剑级别的C语言工具代码示例,以及它们的简要讲解,分享给各位老铁,大家按需使用。
* k  \7 m6 {& x% M5 E9 w1、循环队列(Circular Buffer)
' f7 D) P2 O* m% ?9 [typedef struct {
0 b) o& ?6 }1 A5 Z3 ~    int buffer[SIZE];
  H- G) y: s5 D+ s$ E  U    int head;8 j; p' e( X% i) m% |4 t* P
    int tail;
  q: [9 R. n- p6 q9 j    int count;3 U0 @7 b- R5 \8 B. \
} CircularBuffer;% m5 L( Z; _+ U
void push(CircularBuffer *cb, int data) {
1 p! X  i' t) Z! D* e' Z5 G7 I    if (cb->count  SIZE) {; }8 \3 e/ Z: B( m7 J, f$ `5 `$ W
        cb->buffer[cb->head] = data;
6 E7 X+ V/ ~3 W; V        cb->head = (cb->head +1) % SIZE;# f* t/ I% ~6 P- G
        cb->count++;
/ J. o7 N7 j# i& v% w1 w    }
* L9 D! ^2 e0 D. r  o}
; n: d- `) Z! b% P  zint pop(CircularBuffer *cb) {
4 \1 C4 P2 O) l. J- k# p    if (cb->count >0) {) B: Z. x1 s9 d1 z6 w6 Y' a
        int data = cb->buffer[cb->tail];. H6 e) U# E' p* n7 e9 m* V
        cb->tail = (cb->tail +1) % SIZE;1 m4 C# e/ O6 v! K
        cb->count--;
- j) s* w4 B* P1 \+ G6 C( s        return data;
* k  v8 l7 \, V% ^$ J" Y9 `" {2 z    }; ~0 v; p8 S3 L: D, P
    return-1; // Buffer is empty/ h' D' ~7 B/ r# ^( j4 g0 L" n6 K1 p
}4 G, I* O. J+ a3 S% j; C
循环队列是一种高效的数据结构,适用于缓冲区和数据流应用,例如串口通信接收缓冲。2 J6 z2 m  ]" D( k
2、断言(Assertion)
7 L4 }0 l+ M% O: {9 o#define assert(expression) ((void)0); Q+ m+ t* S1 U9 y
#ifndef NDEBUG8 t7 j: ~. x6 t# Z
#undef assert3 v4 A- t* {3 |3 Z1 O
#define assert(expression) ((expression) ? (void)0 : assert_failed(__FILE__, __LINE__))7 Z) M0 K/ X& d) Z" k
#endif
5 A3 @0 f, X; H- Avoid assert_failed(const char *file, int line) {
% B$ Q5 z' C2 r7 k& D7 ^    printf("Assertion failed at %s:%d- ^1 k, P0 k6 K$ t7 }5 N# I! I5 t
", file, line);) P! C/ [, V$ R
    // Additional error handling or logging can be added here
- k( _' V* |, ]! O}
$ v# ^; v. }# T3 a& I断言用于在程序中检查特定条件是否满足,如果条件为假,会触发断言失败,并输出相关信息
: m: l5 }8 P+ c( b5 e+ t3、位域反转(Bit Reversal)* m' i, l3 G5 }6 D) K0 }( h
unsigned int reverse_bits(unsignedint num) {( ^% c# h4 G( c# k
    unsignedint numOfBits =sizeof(num) *8;+ {* m( v% R7 h! s8 Z0 L2 z  }
    unsignedint reverseNum =0;
4 @8 b; K/ x/ {    for (unsignedint i =0; i  numOfBits; i++) {
8 z' V" U0 H: `% j* g9 h        if (num & (1 i)) {  Z* t1 F. N  K* Z+ e6 r
            reverseNum |= (1 ((numOfBits -1) - i));6 f0 ?% ^$ I: l, W# w9 T4 ?3 w. z
        }
2 D/ }2 ?- W  s2 m& p$ V- j7 k# W    }) s* [/ s& o9 ^' q3 v- k! P
    return reverseNum;
& x" e; \" N- L- x9 Q}
7 F) x7 F* X% `5 t3 u8 F5 I该函数将给定的无符号整数的位进行反转,可以用于某些嵌入式系统中的位级操作需求。
  i9 E+ n% h' }3 A4、固定点数运算(Fixed-Poin Arithmetic): Q1 ?& M- C; I
typedef int16_t fixed_t;' p/ |% |, z9 N; }) N5 r
#define FIXED_SHIFT 8
4 `0 X# A, q" s! L#define FLOAT_TO_FIXED(f) ((fixed_t)((f) * (1 + p1 j; h% V6 l2 j7 O' m/ U- a; E+ a
#define FIXED_TO_FLOAT(f) ((float)(f) / (1 : x$ Q: @2 E! Y
fixed_t fixed_multiply(fixed_t a, fixed_t b) {: s6 r4 a5 f; e3 N  z& D( S) C2 N0 d
    return (fixed_t)(((int32_t)a * (int32_t)b) >> FIXED_SHIFT);
9 v# a/ U0 I7 A. _5 y% y3 J}
; y& r- x( q' |, F( K2 G$ f# J在某些嵌入式系统中,浮点运算会较慢或不被支持。因此,使用固定点数运算可以提供一种有效的浮点数近似解决方案。
6 ~+ p% n! j9 n3 a# ^5、字节序转换(Endianness Conversion)3 w3 A. T, R% k% t% q! u: u
uint16_t swap_bytes(uint16_t value) { return (value >> 8) | (value  8); }用于在大端(Big-Endian)和小端(Little-Endian)字节序之间进行转换的函数。
4 d& @# r: B% E3 ]" q6、位掩码(Bit Masks)
- t4 H) |, g  |( ]7 W#define BIT_MASK(bit) (1
' ]. q* F' s( {. r/ i0 U  M用于创建一个只有指定位被置位的位掩码,可用于位操作。$ {" z2 Q. z  Q
7、计数器计数(Timer Counting)
/ W1 H& y  `! a6 C/ B8 D#include
' z/ Y  S5 W4 ]+ E+ ?4 zvoid setup_timer() {0 Z& O. R' V  t7 \- Z% }
    // Configure timer settings: a# c, M- j& f, F8 T1 ?. I
}% g; w) S8 K- _# s* @
uint16_t read_timer() {
+ G1 I! I! z3 b$ C* ^    return TCNT1;
; \1 x. Z( m! n9 q3 E  P}, J3 a) D0 s) ^* |5 _# W3 }
在AVR嵌入式系统中,使用计时器(Timer)来实现时间测量和定时任务。
; s+ l! B/ b  q6 e% ]8、二进制查找(Binary Search)# m, s- W, f$ X0 s. v6 u
int binary_search(int arr[], int size, int target) {4 i4 m; n: j2 M. b# S  P
    int left =0, right = size -1;
2 [' L% k/ D6 ^2 F    while (left  right) {
; n: s% d. S/ `0 ~" ^- Y( Z& @4 O! q9 }        int mid = left + (right - left) /2;
6 c7 p% _1 `4 u        if (arr[mid] == target) {
; Z: }, ~" p9 `8 E% S% m! H            return mid;
8 L8 C6 a1 @" S        } elseif (arr[mid]  target) {
: H5 f0 T2 l" b7 s( o( C' W+ S* h            left = mid +1;2 K; R& s4 F" G  H8 \
        } else {2 q( b( X' n9 b
            right = mid -1;9 g$ n% @( }0 P! Y# _" V
        }
0 @: T4 F1 }4 i8 T    }* X0 A0 ^% A, k) Q3 b& r5 P
    return-1; // Not found
% v2 \. I9 P0 S% r}
5 Q5 U- S- h  G5 u* p用于在已排序的数组中执行二进制查找的函数。
: j! x% \9 F% K2 v, f. m% L9、位集合(Bitset)
3 c1 d5 F" I2 f( O8 T! E) J( U1 N#include ' [8 ~' R5 v9 b
typedefstruct {
. M' E9 C7 a6 ]% ]    uint32_t bits;( L; |  ^5 ^$ L1 b5 A
} Bitset;
1 p  h1 q4 V. v7 A" u6 F! tvoid set_bit(Bitset *bitset, int bit) {6 x- f2 A8 f  D1 x- M
    bitset->bits |= (1U bit);8 j: j8 ^' f4 `! s
}
4 e6 d& `: n& z6 S' mint get_bit(Bitset *bitset, int bit) {
6 T% u8 a  v# d/ {    return (bitset->bits >> bit) &1U;
5 k- f' e7 S" u; y4 I}
; j2 g( e& \/ K4 p7 U0 b5 @实现简单的位集合数据结构,用于管理一组位的状态。- ?: v/ ^' e# j. y' V5 G: u" [
这些代码示例代表了嵌入式开发中常用的一些利剑级别的C语言工具代码。它们在嵌入式系统开发中具有广泛的应用,有助于优化性能、节省资源并提高代码的可维护性。: n: Z' j8 p1 Z2 L% p6 ^
来源 | 知乎-晓亮Albert6 E0 J0 d0 Y3 u4 t
-END-& D* Z+ n& _1 A
往期推荐:点击图片即可跳转阅读9 G& v! p* P" p8 q( L

phbos4l5rwh64014340709.jpg

phbos4l5rwh64014340709.jpg

/ V9 w: t, s/ J7 I2 k最近在画图,电源稳定性对嵌入式硬件设备来说,实在是太重要了!1 }+ b: `! }1 H9 A. H- C

shb5rn5ppue64014340809.jpg

shb5rn5ppue64014340809.jpg

  ~4 J  R: |/ P嵌入式设备能在LCD屏幕上显示中文,是基于什么原理?
; u% X# \6 T9 K( B3 e( Q' X

5kfpsuosmv164014340909.jpg

5kfpsuosmv164014340909.jpg
# W  C( j0 v. d% N5 j
嵌入式软件,代码的可读性与可运行性,哪个更重要?" g, d7 |2 I' O: d, h% J
我是老温,一名热爱学习的嵌入式工程师* d% Q8 P# o% d2 Y6 I' W: T1 N' @
关注我,一起变得更加优秀!
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


联系客服 关注微信 下载APP 返回顶部 返回列表