电子产业一站式赋能平台

PCB联盟网

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

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

[复制链接]

556

主题

556

帖子

3836

积分

四级会员

Rank: 4

积分
3836
发表于 2025-3-25 08:00:00 | 显示全部楼层 |阅读模式
我是老温,一名热爱学习的嵌入式工程师
' U9 D, t; X5 _. }( L4 F/ U关注我,一起变得更加优秀!嵌入式软件开发过程中,为了提升工作效率,避免重复造轮子浪费时间,经常会复用一些C语言代码片段。4 T+ j$ ^; T8 p4 B" L
以下是一些利剑级别的C语言工具代码示例,以及它们的简要讲解,分享给各位老铁,大家按需使用。/ E& G! j6 j; C! E$ L
1、循环队列(Circular Buffer): S9 _. i& @% H: H* j
typedef struct {! F2 S5 W- y) t
    int buffer[SIZE];: Q$ K$ {6 k0 b' O* t, ]
    int head;0 v$ B) V) A- m: Z
    int tail;: w0 u8 r7 B' f& F$ p
    int count;. d; ^5 s" C* e) u; @3 K
} CircularBuffer;
+ e- c0 _7 N% g  f6 C3 p) g) a9 |' Ivoid push(CircularBuffer *cb, int data) {' k7 q9 P' S) s  o) d
    if (cb->count  SIZE) {
1 R# m! `& \2 f0 j9 D1 D0 `        cb->buffer[cb->head] = data;
# W- h) V/ r" N. E1 [' n( \- g9 |        cb->head = (cb->head +1) % SIZE;6 ^4 K* }6 u6 w. t3 k7 j
        cb->count++;
0 t( e& t( S. D' Z2 R- V  w    }
& c& ^; |# i, A: B# l! Z3 a}
& G8 k5 z( I* H# }( z& J6 @1 yint pop(CircularBuffer *cb) {
+ ?$ G2 Y7 m. t4 K    if (cb->count >0) {
% K/ I6 @; S6 m        int data = cb->buffer[cb->tail];
% a% G' i# f! X5 f# b/ |        cb->tail = (cb->tail +1) % SIZE;9 O3 K" |' F6 K! T
        cb->count--;
6 M  e+ X2 r6 E        return data;
$ r9 ^! |- b- r! X    }
. u" x6 L6 t  \/ ~$ B) m1 Y7 `    return-1; // Buffer is empty
" O5 H7 e$ s6 _1 i3 m. n}
3 c  ]4 ]3 ^; d) i; q6 [8 J  n循环队列是一种高效的数据结构,适用于缓冲区和数据流应用,例如串口通信接收缓冲。. P  F# m- ?; J1 d' D( O4 ~
2、断言(Assertion)
  L  i' U; }! M+ x5 G8 w#define assert(expression) ((void)0)
' l. _% |1 M/ O4 \#ifndef NDEBUG
" N; O% S  p5 e5 i. i- S#undef assert$ F7 S( c/ z% N( n
#define assert(expression) ((expression) ? (void)0 : assert_failed(__FILE__, __LINE__))
. K  N* Y+ Z) y5 \#endif
' Q/ j1 r4 m' |! ]void assert_failed(const char *file, int line) {
( N5 w! k6 I# v/ D, [3 ]/ q    printf("Assertion failed at %s:%d
& |$ a! C" y7 r/ w", file, line);
; I$ P( [( H% q3 ^4 c0 j1 w    // Additional error handling or logging can be added here
8 e, U( f  \+ G8 M5 u& X0 p" M9 x6 V}* \! v8 |; k) g5 p: y% t
断言用于在程序中检查特定条件是否满足,如果条件为假,会触发断言失败,并输出相关信息' s4 ]& }" b) s1 v/ \
3、位域反转(Bit Reversal)
: D) T  ]8 D1 u% kunsigned int reverse_bits(unsignedint num) {
) Y3 D) @" a9 U8 O5 A$ z2 k    unsignedint numOfBits =sizeof(num) *8;, B' @2 P1 h7 ]2 E/ s/ k' i
    unsignedint reverseNum =0;
% R' F+ x. `" x! v    for (unsignedint i =0; i  numOfBits; i++) {) `; @' M4 w1 _9 F1 n- V/ H8 n% w
        if (num & (1 i)) {
1 O2 q3 T) P- y' y/ }; y            reverseNum |= (1 ((numOfBits -1) - i));
! W( v. Q! @; r  P! q        }( J% |) z6 T$ f8 X
    }$ w$ E: d3 @9 _0 N
    return reverseNum;
. ]5 o, Y. [& \( g! B. a  n}: F+ I* \1 ~" F" v$ c4 p8 G* Q
该函数将给定的无符号整数的位进行反转,可以用于某些嵌入式系统中的位级操作需求。; e2 Q  N7 H5 G3 Q/ ^1 {, ]" G
4、固定点数运算(Fixed-Poin Arithmetic)8 Q- j8 K' p. A
typedef int16_t fixed_t;1 w* x+ N7 q$ X, T' J
#define FIXED_SHIFT 8/ W$ u% Q" s( q9 X) U( l, ?
#define FLOAT_TO_FIXED(f) ((fixed_t)((f) * (1 - u( u/ q1 P/ y$ k. Q
#define FIXED_TO_FLOAT(f) ((float)(f) / (1 1 M  n3 H7 D0 g3 E  n! g
fixed_t fixed_multiply(fixed_t a, fixed_t b) {) _, G2 `5 Z) L" W" B3 w# j  l' z
    return (fixed_t)(((int32_t)a * (int32_t)b) >> FIXED_SHIFT);
7 k3 B' H: q# ^( r}% p! a2 r2 W8 f- M, x7 W: W# Q
在某些嵌入式系统中,浮点运算会较慢或不被支持。因此,使用固定点数运算可以提供一种有效的浮点数近似解决方案。. o5 Q) f& X2 K0 N- E/ v  G! Y
5、字节序转换(Endianness Conversion)2 c4 o" C$ d' t: R& O/ ~
uint16_t swap_bytes(uint16_t value) { return (value >> 8) | (value  8); }用于在大端(Big-Endian)和小端(Little-Endian)字节序之间进行转换的函数。
( K/ {1 i4 s: P+ c6、位掩码(Bit Masks)8 d2 H: H8 V2 ]/ t% q) m
#define BIT_MASK(bit) (1 / Z# c0 G* f* }& a* T
用于创建一个只有指定位被置位的位掩码,可用于位操作。
1 P6 I$ y! K0 ~' }7、计数器计数(Timer Counting)5 N" R1 [- x: p0 X# R( A) J, T
#include
" M* Y& P9 O" L* a7 F4 u! N5 v2 r! Pvoid setup_timer() {& S% _8 `2 t( `; ~
    // Configure timer settings% }6 D7 m! ?  [' d' h
}
+ P2 G. \* Y% k, G3 [$ ruint16_t read_timer() {& a" B& w  W: c+ [$ Z& w. U6 \
    return TCNT1;
6 J; B& U0 D1 [  @}
" x- j! N! Z+ ^% ^, {2 a0 I在AVR嵌入式系统中,使用计时器(Timer)来实现时间测量和定时任务。& ?! r/ L1 P' F+ D, |3 D
8、二进制查找(Binary Search)
; r' ?1 |/ w3 U; A6 ^6 _$ \int binary_search(int arr[], int size, int target) {4 Z9 ?0 z# G+ Q5 t! @5 n1 D
    int left =0, right = size -1;, I+ @  Q- c& _2 t
    while (left  right) {3 ?# Q5 e8 u1 H$ q* m
        int mid = left + (right - left) /2;
+ T6 O( t* @1 s. {- H1 m# t        if (arr[mid] == target) {; S+ l! B3 R  R( W$ y7 J* |
            return mid;
3 }$ k- w. @  {        } elseif (arr[mid]  target) {
9 q" I# y) B& v8 Z# \9 t            left = mid +1;. |* y! A# N% R/ ?8 t
        } else {
( H- M. A( N  S8 \3 }3 ?) t            right = mid -1;/ a3 |2 y# j8 E: S2 C$ o
        }
* `+ m: o( H4 g3 C' S$ G    }
( W- V0 T0 W7 s- r8 R8 u. x    return-1; // Not found2 K! ]( o' j& S& b( A# K9 Q
}
+ A0 s, q& e6 g" K* }% i用于在已排序的数组中执行二进制查找的函数。
, D' o+ b) E2 \3 t9、位集合(Bitset)
0 u# U4 H, n4 u3 _/ ?' H#include ( j" @$ X* P( z. p
typedefstruct {9 L8 t" L3 M+ K$ i; M/ q
    uint32_t bits;
  l. N0 v6 m- D( a} Bitset;6 g% W' U& V4 c7 R4 |: p
void set_bit(Bitset *bitset, int bit) {) b! e& n8 b3 V" j
    bitset->bits |= (1U bit);
: N3 h$ v  O5 O" t$ d  f}
6 h6 R" E/ r9 o, O7 M- Wint get_bit(Bitset *bitset, int bit) {! R, C! K+ ]: |$ E# o5 X3 {; l+ V
    return (bitset->bits >> bit) &1U;. f, W1 y; c3 d
}. F" ~: p+ ^4 C! E$ x  u- \
实现简单的位集合数据结构,用于管理一组位的状态。
8 @. y; _2 _! W6 z这些代码示例代表了嵌入式开发中常用的一些利剑级别的C语言工具代码。它们在嵌入式系统开发中具有广泛的应用,有助于优化性能、节省资源并提高代码的可维护性。7 V  l, z+ G3 O& X$ P' M% j
来源 | 知乎-晓亮Albert
' ]! S. A( L, [0 r-END-" O; v7 G5 A7 Z! V
往期推荐:点击图片即可跳转阅读9 N! W' O! w: m

phbos4l5rwh64014340709.jpg

phbos4l5rwh64014340709.jpg
; P% F5 y4 g4 V$ d1 L2 b4 Z! V, G' V
最近在画图,电源稳定性对嵌入式硬件设备来说,实在是太重要了!9 c# ?0 g' K! r; ~* O+ B: ~: h: N

shb5rn5ppue64014340809.jpg

shb5rn5ppue64014340809.jpg
6 b5 a6 n5 G/ K+ d3 ?
嵌入式设备能在LCD屏幕上显示中文,是基于什么原理?7 u+ Z, q, H9 Q) _" x2 F

5kfpsuosmv164014340909.jpg

5kfpsuosmv164014340909.jpg

' I1 l6 o6 a8 I- S) I8 N嵌入式软件,代码的可读性与可运行性,哪个更重要?
; C! e7 X! c5 U8 k1 A我是老温,一名热爱学习的嵌入式工程师
; @4 M# h! N$ Y" T) ]2 o关注我,一起变得更加优秀!
回复

使用道具 举报

发表回复

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

本版积分规则


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