电子产业一站式赋能平台

PCB联盟网

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

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

[复制链接]

543

主题

543

帖子

3399

积分

四级会员

Rank: 4

积分
3399
发表于 昨天 08:00 | 显示全部楼层 |阅读模式
我是老温,一名热爱学习的嵌入式工程师+ W& V; B4 C: _9 [) C
关注我,一起变得更加优秀!嵌入式软件开发过程中,为了提升工作效率,避免重复造轮子浪费时间,经常会复用一些C语言代码片段。
/ H6 ?5 d* |6 |7 S/ M) p以下是一些利剑级别的C语言工具代码示例,以及它们的简要讲解,分享给各位老铁,大家按需使用。% B. a, L6 W) h
1、循环队列(Circular Buffer)
( \2 h" Z. G1 d8 |2 Z' a) ftypedef struct {
: e- B( T1 W5 I8 i$ k: c* C    int buffer[SIZE];
/ {4 |5 q6 T3 x! L    int head;( {9 r, o% e: V; o( ^. K
    int tail;
1 E) w" B+ t! C7 u1 N7 V    int count;
9 g5 f9 X2 I) C7 P# K8 y" f} CircularBuffer;1 ?* d0 u$ n8 m$ `
void push(CircularBuffer *cb, int data) {, p! T  q- q  a8 v' D
    if (cb->count  SIZE) {1 K  I) {( K# `: F: C4 }3 |
        cb->buffer[cb->head] = data;
) P0 A4 V/ M. p; W5 L        cb->head = (cb->head +1) % SIZE;; s$ E9 t& o( g& t' l# k' {: Y
        cb->count++;5 Z1 C1 d: s9 b7 _- o( V3 S5 E* i
    }
- K# A3 `8 |' S7 t$ E9 s& E$ d4 S}+ h+ D* G" S9 z7 Z
int pop(CircularBuffer *cb) {
) Y; l1 }8 j3 `& T  }; u: p7 |    if (cb->count >0) {
2 r. r) Q3 c; ]: l        int data = cb->buffer[cb->tail];
# A1 G1 v5 i  |        cb->tail = (cb->tail +1) % SIZE;' f' [) P+ f! d/ X" }  q) S0 }# ]
        cb->count--;' D  [5 v+ I7 v4 O$ w+ l! F6 C
        return data;( {8 M) b* q, V! A% E/ ]
    }
# {3 W3 z! R6 t1 [) Y- ^    return-1; // Buffer is empty
5 ~  C/ ]& S* J- D: G}
% H" f# H+ F. _3 s1 j循环队列是一种高效的数据结构,适用于缓冲区和数据流应用,例如串口通信接收缓冲。
6 v# @& R' r( C; }2、断言(Assertion)0 U5 O/ e5 K' q: I, T- E# J
#define assert(expression) ((void)0)8 [8 Y- r' Z5 g" q
#ifndef NDEBUG1 S# j3 Z& m5 {6 d
#undef assert& ]" M7 V# Q( _2 {" A
#define assert(expression) ((expression) ? (void)0 : assert_failed(__FILE__, __LINE__))
: u8 z! V0 h+ }! @#endif; Q5 v1 U3 d1 p4 Q5 x* s5 E
void assert_failed(const char *file, int line) {
& `" m+ j$ r  P4 L5 f/ K/ g    printf("Assertion failed at %s:%d
; g* v4 Y, [2 @8 ]0 q- s$ \; t", file, line);* y! \# F8 X) a$ z0 D1 X+ k
    // Additional error handling or logging can be added here5 y9 _. w* [( @
}; U9 L0 i6 k. s: G& p; w+ y
断言用于在程序中检查特定条件是否满足,如果条件为假,会触发断言失败,并输出相关信息; y& r+ N" }, J! i
3、位域反转(Bit Reversal)
# K1 v6 e: |, u/ H1 A& S( Gunsigned int reverse_bits(unsignedint num) {
' w% M+ U& t+ N# r1 |2 u    unsignedint numOfBits =sizeof(num) *8;
% O( Q  R: L& B    unsignedint reverseNum =0;9 s' j. i1 r; e9 ]: l- M
    for (unsignedint i =0; i  numOfBits; i++) {
' w9 }; \8 Q. Z4 J; S$ [- m) K        if (num & (1 i)) {3 d+ e$ j* j) M! j6 l9 K( Z) h: v/ t
            reverseNum |= (1 ((numOfBits -1) - i));
8 M% h5 ~- [% y2 S, x( O        }. u4 o! W# F5 B' ?% q: }; V
    }6 Y( u' j8 d' k* Y
    return reverseNum;' x3 y) X+ M' U; J, d0 }
}
9 j5 `" D  V5 }- ^5 t9 }% n( Q该函数将给定的无符号整数的位进行反转,可以用于某些嵌入式系统中的位级操作需求。5 F* z: g/ z  ?' q& g
4、固定点数运算(Fixed-Poin Arithmetic)1 u, i" S& W0 }* I
typedef int16_t fixed_t;% m8 Z# S! h6 y$ a- _7 C! F. E
#define FIXED_SHIFT 8
! j5 y6 }0 T7 }' m#define FLOAT_TO_FIXED(f) ((fixed_t)((f) * (1 ( e* D. @- ?7 h* z
#define FIXED_TO_FLOAT(f) ((float)(f) / (1 : l% A# k  W9 q& s+ d
fixed_t fixed_multiply(fixed_t a, fixed_t b) {
1 ~7 k, F* |$ P- c' N' r    return (fixed_t)(((int32_t)a * (int32_t)b) >> FIXED_SHIFT);
* E4 Z$ x3 S+ M& Y! k}$ E0 l& L% s+ ?* ?/ k6 U& K* Q* ]
在某些嵌入式系统中,浮点运算会较慢或不被支持。因此,使用固定点数运算可以提供一种有效的浮点数近似解决方案。6 s- _9 q& P6 Y  m# s
5、字节序转换(Endianness Conversion)& v' q& y2 e3 R9 L4 ?
uint16_t swap_bytes(uint16_t value) { return (value >> 8) | (value  8); }用于在大端(Big-Endian)和小端(Little-Endian)字节序之间进行转换的函数。
* F  m) T- K( X( e6、位掩码(Bit Masks)
1 c' o8 }+ w1 `9 {4 q, s#define BIT_MASK(bit) (1 0 e, ^+ j- H& b4 O
用于创建一个只有指定位被置位的位掩码,可用于位操作。5 y6 d9 E* ~& y' K+ Q  m
7、计数器计数(Timer Counting)
. F2 s9 V! `  V$ _: x#include ! b4 X( m5 o* Y
void setup_timer() {
! k/ m9 g5 r+ w9 g3 W    // Configure timer settings" C0 Q. F5 I4 ?. N3 x
}  G1 _+ i3 R" ^- M
uint16_t read_timer() {, |$ z9 N8 U" M) T
    return TCNT1;- c8 h8 y4 t5 r
}* `7 N1 p- d! v" `2 Q0 V) C7 K! s* q
在AVR嵌入式系统中,使用计时器(Timer)来实现时间测量和定时任务。
1 ^& M. E0 t4 h- O' o9 y8、二进制查找(Binary Search)4 B/ }: g: g% I; x) s
int binary_search(int arr[], int size, int target) {" E# Q. J) G/ g7 T( E
    int left =0, right = size -1;
( v: m% k3 w; H, k8 P1 N3 _0 v* L    while (left  right) {( N$ x; }' T6 I# p$ T- U
        int mid = left + (right - left) /2;
+ G' W1 U8 B% Q        if (arr[mid] == target) {
# b  R* v$ W4 ]% o0 p; z            return mid;" I7 t, v( V! }* T" G2 ?
        } elseif (arr[mid]  target) {, d! w' ]' }- J: Q3 P1 b
            left = mid +1;
- N  a. q' o; s' }6 i: \% V! n' M; f        } else {3 K; j/ l/ W' g/ E- O
            right = mid -1;
# w! U' ?, A4 m9 G+ I        }. `/ k: g1 r2 D3 }. Q) N) R) q
    }8 F0 l. K& w) g4 J; ?- n/ \; L) B, _
    return-1; // Not found: u- k! j+ d, U, H, H
}
9 a; J5 y) V) y. q2 U用于在已排序的数组中执行二进制查找的函数。
7 @5 l- i/ L( t# q3 X/ \9、位集合(Bitset)) H9 T" U' S/ Q( {$ s% ?. w$ Q
#include
; w: g. @  K' h; dtypedefstruct {
  ~4 y" I) b/ n! N- L    uint32_t bits;+ A5 |; L& S8 T$ I. I
} Bitset;
- z- H3 t1 }, f: |1 evoid set_bit(Bitset *bitset, int bit) {/ _5 p9 ?1 t2 t$ U
    bitset->bits |= (1U bit);
6 M* P7 {: w& K& \' F* n}
1 m- g9 A" y/ X* g( L! nint get_bit(Bitset *bitset, int bit) {/ L" b2 y4 J5 e
    return (bitset->bits >> bit) &1U;9 b0 c. V; \2 E0 B! x2 Y
}6 k( r7 |2 v$ U; S+ Q# I3 @& C' ^
实现简单的位集合数据结构,用于管理一组位的状态。
+ H% w! P+ k: @$ y$ P) B4 d( y; a这些代码示例代表了嵌入式开发中常用的一些利剑级别的C语言工具代码。它们在嵌入式系统开发中具有广泛的应用,有助于优化性能、节省资源并提高代码的可维护性。
  M, B  z3 z4 M# t" o来源 | 知乎-晓亮Albert
/ @& p  F1 ]/ x* a0 s$ B) y% ^- j-END-2 x; F4 R9 f) h4 b: R* @
往期推荐:点击图片即可跳转阅读
0 F6 d6 ^) u: ]$ n

phbos4l5rwh64014340709.jpg

phbos4l5rwh64014340709.jpg

) L  W) h3 A4 n( ]" Y1 o4 W最近在画图,电源稳定性对嵌入式硬件设备来说,实在是太重要了!7 M/ k8 Q! K* h

shb5rn5ppue64014340809.jpg

shb5rn5ppue64014340809.jpg

6 X6 W( G; _/ f* v( ?# l- j嵌入式设备能在LCD屏幕上显示中文,是基于什么原理?
. I! r  `  g% G3 ]. a2 E$ B1 x' N

5kfpsuosmv164014340909.jpg

5kfpsuosmv164014340909.jpg
4 G; X* D- m8 o9 e" O2 x' [: j
嵌入式软件,代码的可读性与可运行性,哪个更重要?
+ i- ~7 c6 l; m2 S( S$ U我是老温,一名热爱学习的嵌入式工程师' Y/ I9 }) ~) y/ Z6 w' w! O/ J! i6 C! w
关注我,一起变得更加优秀!
回复

使用道具 举报

发表回复

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

本版积分规则


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