【通信专栏】附录一:STM32单片机C语言基础/逻辑运算/按位运算/结构体/宏定义

在单片机开发中,总有一些C语言基础知识是常常用到的而我们又不易掌握的,今天以STM32单片机为例,总结一下那些常用的C语言基础知识,例如逻辑运算符,结构体,宏定义以及按位运算符。

逻辑运算符

逻辑运算符包含三类:逻辑与(&&)逻辑或(||)以及逻辑非(!),它们的使用还是非常简单的,就不多做解释了,使用说明看下表:
在这里插入图片描述
需要注意的是,逻辑运算的结果只有0和1,并不能有其他臆想的使用方法。在STM32单片机开发中,最常用到的大概就是逻辑非了,例如在跑马灯实验中,我们可以应用逻辑非(!)反复置反LED0的状态,以达到使其闪烁的目的:
在这里插入图片描述

结构体

结构体是32单片机开发中最常用的数据结构了,整个库函数包都是以结构体为基石搭建起来的,因此熟练掌握结构体的使用非常有必要。这里我们就以单片机中最常见到的算法:PID算法来进行示例。

结构体的声明与定义

声明结构体的一般形式为:

struct 结构体名
    { 成员表列 }

例如声明一个包含PID成员变量的结构体:

struct  PID
{ 
float P;
float I;
float D;
};      全局变量

在声明完毕后,可以另行定义PID结构体变量,例如:

struct PID PID_X;
struct PID PID_Y;

这时便定义了两个PID结构体:PID_X和PID_Y 。
此外还可以在声明结构体时直接定义结构体变量:

struct 结构体名
  { 
        成员表列 
  } 变量名表列;

结构体的初始化与引用

在结构体定义完后,可以采用两种方式进行初始化:
方法一:在声明时直接初始化

struct  PID
{ 
     float P;
     float I;
     float D;
} PID_X={1.12.03.4},PID_Y={2.3,4.2,6.2}  ;  

方法二:在声明后进行额外初始化
在这里插入图片描述
至于结构体变量的引用,就用点(.)运算符就好了:

	PID_X . P = 1.1 ;

typedef声明

typedef声明可以定义新的类型名来取代已有的类型名,在STM32单片机开发时常用到的u8 , u16就是这么来的,我们可以双击u8 选中并查看它的定义:
在这里插入图片描述
我们可以看到是一个typedef声明的结构体,而里面的uint8_t其实就是无符号字符型,我们可以双击选中它并查看定义,如下图。同样u16,u32也是一个道理。
在这里插入图片描述
1:使用简单的类型名代替复杂的类型名:如上图中的
typedef unsigned char uint8_t ;
2:定义一个新的类型名来代替结构体类型:
例如当我们需要定义一个PID结构体时,按照上文,我们需要:
在这里插入图片描述
在上图中,结构体名字为***struct PID*** ,在声明时也需要写为:

	struct PID  PID_X;

但若使用typedef定义一个新的结构体名时,可以如下:
在这里插入图片描述

宏定义define

#开头的语句为 “ 编译预处理指令 ”。
定义一个宏:

#define  PI    3.1415926

在程序中用3.1415926 原封不动的替换掉 PI 。原封不动,就是直接替换,不会隐形的添加括号,例如语句:
#define a 3+3
那么程序中 aa是什么呢?是 3+33+3;而非(3+3)*(3+3)。

没有值的宏

#define _DEBUG

没有值的宏常常用来做条件编译宏,比如在程序中我们来检测是否存在该宏,若没有则执行某程序,若有则执行另外的程序。

按位运算符

C语言的按位运算符已经非常接近底层操作了,包含六个基本运算符号:

  • & 按位与
  • | 按位或
  • ~ 按位取反
  • ^ 按位异或
  • << 左移 >> 右移

在前三个里面呢,按位与,按位或,按位取反与本文开头的逻辑运算符相类似,只不过按位运算符是将一个数变为二进制之后对每一位进行计算。在STM32单片机开发中,我们最常用到按位与和按位或的地方便是初始化代码部分了:
在这里插入图片描述
上图中红框区域,大家可以这样理解:
将00000010 与00000001进行按位或操作,得到的为00000011,在寄存器中因为第七位和第八位(分别控制P6,P7引脚)变为1,则相应引脚被置高。上图红圈一行可以简化a = b | c ; ,在实际应用中,我们也会见到类似于 a |= b ( a=a | b ) 这样的式子。

按位取反便是将每一位上的数取反,1变0 0变1,

按位异或运算便是将两个数的二进制相对应的位比较,相同为0,不同为1,如下图:
在这里插入图片描述
左移运算符的语法如下:

value << shift

其 中 ,value是要被操作的整数值,shift是要移动的位数。例如,下 面 的 代码将值13的所有位都向左移 3 位 :

13<<3 ;

腾出的位置用0填充,超出边界的位被丢弃。
也可以和赋值运算符相结合:

int x = 13 ;
int y = x<<3 ;

在STM32单片机开发时,左移右移运算符更常用于寄存器开发方式。

常用按位运算符技术

1:打开位
下面两项操作打开lottabits中对应于bit表示的位:

lottabits = lottabits | bit;
lottabits |= bit ;

它们都将对应的位设为 1,而不管这一位以前的值是多少。这是因为对1和1 或者 0 和 1执行 或操作时,都将得到1。lottabits中其他所有位都保持不变,这是因为对0 和 0 做OR操作将得到 0,对1和做OR操作将生成 1。

2:切换位
下面两项操作切换lottabits中 对 应 于bit表 示 的 位 。也就是说,如果位是关闭的,则将被打 开;如果位是打开的,将被关闭 :

lottabits = lottabits A bit;
lottabits A= b i t ;

3 . 关闭位
下面的操作将关闭lottabits中对应于bit表示的位 :

lottabits = lottabits&-bit ;

该语句关闭相应的位,而不管它以前的状态如何。首先,运算符〜bit将 原來为1的位设置为0, 原来为0的位设置为1。对0和任意值执行AND操作都将得到0 , 因此关闭相应的位。lottabits中其他所有位都保持不变,这是因为对 1和任意值执行AND操作时,该位的值将保持不变。下面足一种更简洁的方法:

lottabits &=- bit ;

好啦,本文到此便结束了,仅是罗列了一些基本的知识点,而且并不全面,因为一旦篇幅过长,相信大家也将没有耐心把它们记住了,不如一点一点的来。

最近一段时间我将持续更新【通信专栏】,本人机械专业理科男一枚,爱好技术与生活,有着大大的梦想,有个小小的情怀,会在微信公众号【行走的机械人】分享我在电控,视觉,编程等方面的学习所得,欢迎关注哦。

发布了26 篇原创文章 · 获赞 40 · 访问量 3633

猜你喜欢

转载自blog.csdn.net/qq_43667130/article/details/104020398