专栏首页行走的机械人【通信专栏】附录一:单片机C语言基础/逻辑运算/按位运算/结构体/宏定义

【通信专栏】附录一:单片机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_XPID_Y

此外还可以在声明结构体时直接定义结构体变量:

struct 结构体名

{

成员表列

} 变量名表列;

结构体的初始化与引用

在结构体定义完后,可以采用两种方式进行初始化:

方法一:在声明时直接初始化

struct PID

{

float P;

float I;

float D;

} PID_X={1.1,2.0,3.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

那么程序中 a*a是什么呢?是 3+3*3+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 = lot t a b i t s & - b i t ; 该语句关闭相应的位,而不管它以前的状态如何。首先,运算符〜bit将 原來为1的位设置为0, 原来为0的位设置为1。对0和任意值执行AND操作都将得到0 , 因此关闭相应的位。lottabits中其他所有位都保持不变,这是因为对 1和任意值执行AND操作时,该位的值将保持不变。下面足一种更简洁的方法:

lottabits & = - b i t ;

好啦,本文到此便结束了,仅是罗列了一些基本的知识点,而且并不全面,因为一旦篇幅过长,相信大家也将没有耐心把它们记住了,不如一点一点的来。微信公众号(行走的机械人)最近一段时间将持续更新【通信专栏】,欢迎关注哦。

本文分享自微信公众号 - Opencv视觉实践(gh_31e12b1be0e0),作者:周旋

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-01-17

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 【电工与电子技术A】一:电路及其基本物理量

    一类电路用以实现电能的生产,传输,转换和分配,如店里供电设备与各用电设备组成的电力系统。

    周旋
  • 【通信专栏】STM32单片机/I2C通信(上篇)

    想来单片机这块儿除了USART串口通信外,常见的便是I2C通信了,因为I2C通信 硬件连接简单,可扩展性强,但是这种硬件连线的简洁,是以协议的复杂来弥补的。I2...

    周旋
  • 图像处理的回眸女郎是何方神圣?

    我以前没对她产生过太多的疑问,感觉人们都用这个图,肯定和我平时丧心病狂的图像处理一定要用二次元图片一个心理。

    周旋
  • Python学习笔记2——Python概

          执行:由翻译官(Python解释器)把命令(Code)翻译给机器,同事把机器结果翻译给我们

    py3study
  • C#基础知识系列四(运算符汇总)

       本节主要来讲C#中的各种运算符。主要包括is运算符、as运算符、checked和unchecked运算符、sizeof运算符、空接合运算符(??)、&和&...

    aehyok
  • 数据结构与数据类型的区别,联系,本质?

    数据结构与数据类型相信我们并不陌生,在日常开发中天天都能接触到,但如果要让你解释一下它们的本质区别和联系,你是否能准确的描述呢?

    我是攻城师
  • 第二章--第四节:运算符(二)

    位运算符就是将数字转换为二进制进行计算,位运算符包括:按位与(&)、按位或(|)、按位异或(^)、按位取反(~)、左移动(<<)、右移动(>>)。解释见下表: ...

    喵叔
  • 6. 简单又复杂的“运算符”,建议你看一哈

    昨天的《5. 很“迷”的字符与字符串》初稿本来很短的,但是我觉得内容太少了,就加了一些,结果好像就变得特别多〒▽〒。

    谭庆波
  • PUPU激萌表情设计故事

    ? 腾讯ISUX isux.tencent.com 社交用户体验设计 ? ? ? 关于这个项目 在IP形象建设中,将角色的故事和个性很好的传达给用户是非常重...

    腾讯ISUX
  • 【编程基础】零基础学习Java之运算符

    学习计算机编程语言都会遇到运算符这一知识点,运算符这个知识点是教怎么运用编程语言进行最基本的数据处理,下面就讲一下在Java语言中运算符是怎么回事。 1、算术运...

    程序员互动联盟

扫码关注云+社区

领取腾讯云代金券