0%

C语言在单片机中的应用

Main Takeaway

最近学习stm32时发现单片机代码中很多移位运算符,以及fp32,uint8_t等的使用,在此总结回顾一下。

我数据结构的课没选上,可能只有看网课来自学了,笔记也会发出来

位运算

C语言提供了六种位运算符:

运算符&|^~<<>>
说明按位与按位或按位异或取反左移右移

内存中以补码的形式存储数据!!!

  • 按位与运算(&)

&是根据内存中的二进制位进行运算的,而不是数据的二进制形式;其他位运算符也一样。以 -9&5 = 5

按位与运算通常用来对某些位清 0,或者保留某些位

  • 按位或运算(|)

按位或运算可以用来将某些位置 1,或者保留某些位

  • 按位异或运算(^)

按位异或运算可以用来将某些二进制位反转

  • 取反运算(~)

取反运算符~为单目运算符,右结合性,作用是对参与运算的二进制位取反。例如~1为0,~0为1,这和逻辑运算中的!非常类似。

  • 左移运算(<<)

左移运算符<<用来把操作数的各个二进制位全部左移若干位,高位丢弃,低位补0。

如果数据较小,被丢弃的高位不包含 1,那么左移 n 位相当于乘以 2 的 n 次方。

  • 右移运算(>>)

右移运算符>>用来把操作数的各个二进制位全部右移若干位,低位丢弃,高位补 0 或 1。如果数据的最高位是 0,那么就补 0;如果最高位是 1,那么就补 1。

如果被丢弃的低位不包含 1,那么右移 n 位相当于除以 2 的 n 次方(但被移除的位中经常会包含 1

FP32、FP16和INT8

INT8、FP16和FP32是不同的数据类型用于表示数字的精度和存储方式。

  • INT8是指八位整型数据类型,占用1个字节,用8位二进制表示一个数字,它是一种定点计算方式,适用于对整数进行运算,虽然精度较低,但数据量小、能耗低,计算速度相对更快,适合在移动终端进行AI计算。

  • FP16(float,半精度)是指半精度浮点数数据类型,占用2个字节,用16位二进制表示一个数字,其中1位为符号位,5位为指数位,10位为有效数字位。与FP32相比,FP16的访存消耗仅为1/2,因此在一些GPU中可以加速计算速度,但也容易造成溢出。

  • FP32(full precise float 32,单精度)是指单精度浮点数数据类型,占用4个字节,用32位二进制表示一个数字,其中1位为符号位,8位为指数位,23位为尾数位。FP32精度相对较高,但相应地需要更多的存储空间和计算资源。

因此,INT8适用于对整数进行计算的场景,FP16适用于移动终端等资源受限的场景,而FP32适用于需要较高精度的计算场景

intx_t and uintx_t

在C语言中有6种基本数据类型:short、int、long、float、double、char

**uint8_t_16_t_t_t**

1、这些类型的来源:这些数据类型中都带有**_t, _t** 表示这些数据类型是通过typedef定义的,而不是新的数据类型。也就是说,它们其实是我们已知的类型的别名。

2、使用这些类型的原因:方便代码的维护。比如,在C中没有bool型,于是在一个软件中,一个程序员使用int,一个程序员使用short,会比较混乱。最好用一个typedef来定义一个统一的bool

1
typedef char bool;

在C99标准中定义了这些数据类型,具体定义在:/usr/include/stdint.h:

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
#ifndef __int8_t_defined  
# define __int8_t_defined
typedef signed char int8_t;
typedef short int int16_t;
typedef int int32_t;
# if __WORDSIZE == 64
typedef long int int64_t;
# else
__extension__
typedef long long int int64_t;
# endif
#endif


typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
#ifndef __uint32_t_defined
typedef unsigned int uint32_t;
# define __uint32_t_defined
#endif
#if __WORDSIZE == 64
typedef unsigned long int uint64_t;
#else
__extension__
typedef unsigned long long int uint64_t;
#endif

References