干货|手把手教你写单片机的结构体

摘要:据说还有好多学单片机的小伙伴不会用结构体?指针和结构体是学单片机必需要掌握的,若是你C语言掌握的不牢,单片机根本学不到精髓,只能完成一些低级的项目。看得懂结构体而且可以灵活运用结构体才能说你入门了单片机。本篇将以最通俗的方式结合STM32单片来说讲结构体的运用。解决你学完C语言、考过了计算机二级仍是看不懂单片机结构体的苦恼。宝藏文章,记得点赞转发收藏。markdown

你们知道指针和结构体是单片机的难点,因此就去学习C语言,找视频看书......函数

这里面每个视频的播放量都很是高。对于单纯的学习C语言,这里讲的很清楚。看完你不由在下面评论一句:哇!讲的真的太清楚了吧!可是等你真正的学单片机的时候,你会发现我不是学过C语言吗?计算机二级我也过了啊!怎么这个指针和结构体都不懂啊?难道我学了一个假的C语言?学习

其实这不是你的错,也不是单片机的错,而是在C语言和单片机之间须要一个过渡!这个须要过渡的点在不少单片机视频教程中并无去讲解。由于教育机构默认你是知道的,因此在讲流水灯时他们并不会讲解GPIO初始化这个结构体,由于默认你是知道如何操做的。ui

申明一个GPIO_InitTypeDef的结构体,而后在LED_Init(void)函数中定义一个GPIO_InitStructure的变量GPIO_InitStructure,那么这个变量就能够设置这个GPIO_InitTypeDef的结构体中的成员。这里先作了解,请接着往下看。spa

一、为何须要结构体

这里先不说什么是结构体,说说为何须要结构体?只有知道为何须要,才能按照你的须要去学习,这样效率才会高。你才知道在什么状况下咱们须要写一个结构体,怎么样去用结构体。设计

这里咱们以一个智能家居的项目为例。3d

先来看一个实际的问题指针

话说有一个项目上有4个传感器:光照传感器、烟雾传感器、酒精传感器、湿度传感器。而后这四个各个传感器还有设置报警的阈值范围。code

通常都是这样写orm

#include "sys.h"
#include "delay.h"
#include "usart.h"

/*记录传感器的数值*/
float temperature;	//温度
char  humidity;		//湿度
char  alcohol;		//酒精浓度
int   illumination;	//光照强度

/*记录传感器高低阈值*/
float temperature_threshold[2];
float humidity_threshold[2];
float alcohol_threshold[2];
float illumination_threshold[2];

int main(void) {	
	uart_init(115200);//串口初始化
	delay_init();
    while(1)
	{	
	}	
}
复制代码

固然你作一个项目确定还定义了不少其余的变量,还须要记录其它变量

而后过了几天又增长了个一氧化碳传感器

而后过了几天,每一个传感器还须要加个是否正常工做的标志位

由于项目的须要,而后又增长了4个相同的传感器:温湿度、光照强度、烟雾浓度、酒精浓度。

而后又增长了4个相同的传感器 温湿度、光照强度、烟雾浓度、酒精浓度。

截图截不开了....

满屏的变量......

满屏的变量......

满屏的变量......

在项目刚开始作的时候若是不能未雨绸缪,接着干下去整个程序代码别说维护了,就是接着写都让人头疼!

满屏的变量...

满屏的变量...

二、结构体闪亮登场

而后搞C语言那帮家伙就造了个功能struct

一、结构体就是能够把变量包含到里面的东西

struct就表明要定义一个结构体 sensors是这个结构体的名字 而后是一个大括号 { }

大括号里面就随意定义变量啦~

怎么使用里面的变量呢?

注意结构体是一个数据类型 就像是int和char同样的这种类型

既然是一种数据类型

那么就能够用这个数据类型定义变量

定义一个该结构体的变量

为啥要那样子定义啊?

答:你去问造C语言的那帮家伙去!问问他们为啥要设计成这样子!

而后操做结构体变量里面的成员变量。当咱们定义好结构体变量后,在初始化变量里面的成员变量时就会自动出现结构体里面的成员变量,若是这个代码是你一个一个敲出来的话,你就会感叹结构体在单片机中是那么的奇妙!

有人会问为啥是结构体变量中间加个点?

答:你去问造C语言的那帮家伙去!问问他们为啥要设计成这样子。

二、其实定义结构体变量能够下面这样子

也能够定义多个

发现了没,每一个结构体变量都是单独拥有结构体里面的所有成员变量。

就像是最开始说的,若是再增长一套传感器:温湿度、光照强度、烟雾浓度、酒精浓度。

使用结构体的话只须要再定义一个结构体变量便可

可是不少时候咱们在单片机中见到的结构体并非上面那样定义的,而是在前面加了一个typedef关键字。

这样的例子在库函数的头文件中咱们常常会看到以下结构体

三、typedef关键字

先看一下百度百科对typedef的定义

总结一句就是:typedef能够把一个数据类型取一个别的名字

typedef {数据类型} {别的名字}

#include "sys.h"
#include "delay.h"
#include "usart.h"

typedef int zhjiguoxin;//zhjiguoxin就是int

zhjiguoxin value = 0;

int main(void) {	
	uart_init(115200);//串口初始化
	delay_init();	

	printf("value=%d\r\n",value);
	
    while(1)
	{	
	}	
}
复制代码

虽然typedef能够给变量取别名,可是没有谁回像上面那样取名字,我这里知识举一个例子。

四、结构体的精髓

注意下:

一、下面的表明了这个结构体数据类型

二、给这个数据类型起一个别名

注意是三部分, typedef {数据类型} {别的名字}。因此sensor就表明了这个结构体了。

建议初学者把下面这张图保存到你的电脑,这样你就永远也不会忘记typedef在结构体中的用法了,也能很快的记住结构体这个东东。

三、之后定义结构体变量的时候就不须要像最开始那样struct sensors sen;这样的定义结构体变量了,只须要sensors sen;便可

四、结构体名字能够省略

注意结构体定义能够不写结构体名,对C语言来讲,那个sensors不叫结构体名,而是叫标签(tag)。C语言结构体名是struct关键字 + tag。因此为了简便咱们看到的单片机中的结构体都是写成以下的形式。

五、结构体的变量能够听任何变量

一、结构体变量能够听任何变量(int型指针)

#include "sys.h"
#include "delay.h"
#include "usart.h"
typedef struct {
	float temperature; //温度
	char  humidity;	   //湿度
	char  alcohol;	   //酒精浓度
	int   illumination;//光照强度
	char  CO;	 //一氧化碳浓度
	int   *p;  //int型的指针变量
} sensor;
sensor sen;
int value =0;
int main(void) {
	uart_init(115200);//串口初始化
	delay_init();	
	sen.p=&value;//把value的地址赋值 
	//打印p表明的地址里面的值(其实就是打印value的值)
	printf("value=%d\r\n",*(sen.p));	
    while(1)
	{	
	}	
}
复制代码

既然是指针变量,因此给指针变量赋值时固然是赋值的是一个地址。

二、结构体变量能够听任何变量(函数指针)

#include "sys.h"
#include "delay.h"
#include "usart.h"
typedef struct {
	float temperature; //温度
	char  humidity;	   //湿度
	char  alcohol;	   //酒精浓度
	int   illumination;//光照强度
	char  CO;  //一氧化碳浓度
	int   *p;  //int型的指针变量
	void (*fun)();
} sensor;
sensor sen;
void function() {
	printf("zhiguoxin\r\n");
}
int value =0;
int main(void) {	
	uart_init(115200);//串口初始化
	delay_init();	
	sen.fun=function;	
	sen.fun();	
    while(1)
	{	
	}	
}
复制代码

既然是函数指针变量,因此给函数指针变量赋值时固然是赋值的是的也是地址,而且还要是一个函数的地址,而一个函数的函数名就是该函数的地址。因此才会有下面的把函数function();的地址function赋值给函数指针fun。这样你们是否是很清楚了。若是不清楚建议看个3遍以上!

三、结构体变量能够听任何变量(结构体变量)

这就是结构体嵌套,在一个结构体内包含了另外一个结构体做为其成员。当出现结构体嵌套时,必须以级联方式访问结构体成员,即经过成员选择运算符逐级找到最底层的成员时再引用。

#include "sys.h"
#include "delay.h"
#include "usart.h"

typedef struct {
  int i;
}zhiguoxin;

typedef struct {
	float temperature; //温度
	char  humidity;	   //湿度
	char  alcohol;	   //酒精浓度
	int   illumination;//光照强度
	char  CO;  //一氧化碳浓度
	int   *p;  //int型的指针变量
	void (*fun)();	
	zhiguoxin guougo;	
}sensor;

sensor sen;

int main(void) {	
	uart_init(115200);//串口初始化
	delay_init();
	
	sen.guougo.i=100;
	printf("i=%d\r\n",sen.guougo.i);
		
    while(1)
	{	
	}	
}
复制代码

四、结构体变量能够听任何变量(结构体指针)

结构体是一个数据类型。数据类型固然也能够定义对应的指针变量啦。

就像是int 类型能够定义 int *p; 同样

因此当你们若是发现你的代码中结构体是经过—>访问的话,那么这个结构体变量必定是指针类型的变量。同理若是代码中结构体是经过.访问的话,那么这个结构体变量就不是指针变量,而是通常的变量。

总结:到这里结构体在单片机中的应用你已经掌握的差很少了,你们可能感受本期讲的内容太简单了,不过只有你把这个简单的基础性知识打牢,你就会进步的更快。不然你总感受你的代码差点意思。

默认标题_横版二维码_2021-05-29-0.png

相关文章
相关标签/搜索