0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

手把手教你如何写单片机的结构体

GReq_mcu168 来源:玩转单片机 作者:玩转单片机 2021-05-13 11:29 次阅读

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

大家知道指针和结构体是单片机的难点,所以就去学习C语言,找视频看书......

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

其实这不是你的错,也不是单片机的错,而是在C语言和单片机之间需要一个过渡!这个需要过渡的点在很多单片机视频教程中并没有去讲解。因为教育机构默认你是知道的,所以在讲流水灯时他们并不会讲解GPIO初始化这个结构体,因为默认你是知道如何操作的。

68637578-b328-11eb-bf61-12bb97331649.png

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

1、为什么需要结构体

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

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

先来看一个实际的问题

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

一般都是这样写

#include"sys.h" #include"delay.h" #include"usart.h" /*记录传感器的数值*/ floattemperature;//温度 charhumidity;//湿度 charalcohol;//酒精浓度 intillumination;//光照强度 /*记录传感器高低阈值*/ floattemperature_threshold[2]; floathumidity_threshold[2]; floatalcohol_threshold[2]; floatillumination_threshold[2]; intmain(void) { uart_init(115200);//串口初始化 delay_init(); while(1) { } }

689da6d0-b328-11eb-bf61-12bb97331649.png

当然你做一个项目肯定还定义了很多其他的变量,还需要记录其它变量

68ee5a30-b328-11eb-bf61-12bb97331649.png

然后过了几天又增加了个一氧化碳传感器

69037834-b328-11eb-bf61-12bb97331649.png

然后过了几天,每个传感器还需要加个是否正常工作的标志位

6937d84a-b328-11eb-bf61-12bb97331649.png

因为项目的需要,然后又增加了4个相同的传感器:温湿度、光照强度、烟雾浓度、酒精浓度。

69868738-b328-11eb-bf61-12bb97331649.png

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

截图截不开了....

6a41ebf4-b328-11eb-bf61-12bb97331649.png

满屏的变量......

满屏的变量......

满屏的变量......

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

满屏的变量...

满屏的变量...

2、结构体闪亮登场

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

1、结构体就是可以把变量包含到里面的东西

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

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

6a619c4c-b328-11eb-bf61-12bb97331649.png

怎么使用里面的变量呢?

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

既然是一种数据类型,那么就可以用这个数据类型定义变量

定义一个该结构体的变量

6a76f736-b328-11eb-bf61-12bb97331649.png

为啥要那样子定义啊?

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

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

6a8758ba-b328-11eb-bf61-12bb97331649.png

6ae1c0c0-b328-11eb-bf61-12bb97331649.png

6af1166a-b328-11eb-bf61-12bb97331649.png

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

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

2、其实定义结构体变量可以下面这样子

6b01f70a-b328-11eb-bf61-12bb97331649.png

也可以定义多个

6b2acea0-b328-11eb-bf61-12bb97331649.png

6b3b3128-b328-11eb-bf61-12bb97331649.png

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

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

使用结构体的话只需要再定义一个结构体变量即可。

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

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

6b6a32fc-b328-11eb-bf61-12bb97331649.png

3、typedef关键字

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

6baee910-b328-11eb-bf61-12bb97331649.png

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

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

#include"sys.h" #include"delay.h" #include"usart.h" typedefintzhjiguoxin;//zhjiguoxin就是int zhjiguoxinvalue=0; intmain(void) { uart_init(115200);//串口初始化 delay_init(); printf("value=%d ",value); while(1) { } }

6bc32d3a-b328-11eb-bf61-12bb97331649.png

6bcfbb9a-b328-11eb-bf61-12bb97331649.png

虽然typedef可以给变量取别名,但是没有谁会像上面那样取名字,我这里只是举一个例子。

4、结构体的精髓

注意下:

1、下面的代表了这个结构体数据类型

6c0e7718-b328-11eb-bf61-12bb97331649.png

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

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

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

6c1cefaa-b328-11eb-bf61-12bb97331649.png

3、以后定义结构体变量的时候就不需要像最开始那样struct sensors sen;这样的定义结构体变量了,只需要sensor sen;即可。

6c73958a-b328-11eb-bf61-12bb97331649.png

4、结构体名字可以省略

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

6ca8e294-b328-11eb-bf61-12bb97331649.png

5、结构体的变量可以放任何变量

1、结构体变量可以放任何变量(int型指针)

#include"sys.h" #include"delay.h" #include"usart.h" typedefstruct { floattemperature;//温度 charhumidity;//湿度 charalcohol;//酒精浓度 intillumination;//光照强度 charCO;//一氧化碳浓度 int*p;//int型的指针变量 }sensor; sensorsen; intvalue=0; intmain(void) { uart_init(115200);//串口初始化 delay_init(); sen.p=&value;//把value的地址赋值 //打印p代表的地址里面的值(其实就是打印value的值) printf("value=%d ",*(sen.p)); while(1) { } }

既然是指针变量,所以给指针变量赋值时当然是赋值的是一个地址。

6cb5b578-b328-11eb-bf61-12bb97331649.png

6cc2d51e-b328-11eb-bf61-12bb97331649.png

2、结构体变量可以放任何变量(函数指针)

#include"sys.h" #include"delay.h" #include"usart.h" typedefstruct { floattemperature;//温度 charhumidity;//湿度 charalcohol;//酒精浓度 intillumination;//光照强度 charCO;//一氧化碳浓度 int*p;//int型的指针变量 void(*fun)(); }sensor; sensorsen; voidfunction() { printf("zhiguoxin "); } intvalue=0; intmain(void) { uart_init(115200);//串口初始化 delay_init(); sen.fun=function; sen.fun(); while(1) { } }

既然是函数指针变量,所以给函数指针变量赋值时当然是赋值的也是地址,并且还要是一个函数的地址,而一个函数的函数名就是该函数的地址。所以才会有下面的把函数function();的地址function赋值给函数指针fun。这样大家是不是很清楚了。如果不清楚建议看个3遍以上!

6ccde88c-b328-11eb-bf61-12bb97331649.png

6cd93b42-b328-11eb-bf61-12bb97331649.png

3、结构体变量可以放任何变量(结构体变量)

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

#include"sys.h" #include"delay.h" #include"usart.h" typedefstruct { inti; }zhiguoxin; typedefstruct { floattemperature;//温度 charhumidity;//湿度 charalcohol;//酒精浓度 intillumination;//光照强度 charCO;//一氧化碳浓度 int*p;//int型的指针变量 void(*fun)(); zhiguoxinguougo; }sensor; sensorsen; intmain(void) { uart_init(115200);//串口初始化 delay_init(); sen.guougo.i=100; printf("i=%d ",sen.guougo.i); while(1) { } }

6d0fb5b4-b328-11eb-bf61-12bb97331649.png

6d42530c-b328-11eb-bf61-12bb97331649.png

4、结构体变量可以放任何变量(结构体指针)

结构体是一个数据类型。数据类型当然也可以定义对应的指针变量啦。

就像是int 类型可以定义 int *p; 一样

6d583df2-b328-11eb-bf61-12bb97331649.png

所以当大家如果发现你的代码中结构体是通过—>访问的话,那么这个结构体变量一定是指针类型的变量。同理如果代码中结构体是通过.访问的话,那么这个结构体变量就不是指针变量,而是一般的变量。

6d7a2dae-b328-11eb-bf61-12bb97331649.png

6e08bc4a-b328-11eb-bf61-12bb97331649.png

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

编辑:jq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 单片机
    +关注

    关注

    5990

    文章

    43904

    浏览量

    619599
  • C语言
    +关注

    关注

    180

    文章

    7513

    浏览量

    124061
  • 智能家居
    +关注

    关注

    1907

    文章

    9102

    浏览量

    178824
  • GPIO
    +关注

    关注

    16

    文章

    1124

    浏览量

    50414

原文标题:干货|手把手教你写单片机的结构体

文章出处:【微信号:mcu168,微信公众号:硬件攻城狮】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    最新ChatGPT详细注册图文解说教程 ChatGPT账号注册详细步骤分析

    2024年注册ChatGPT详细教程,手把手教你完成ChatGPT的注册
    的头像 发表于 12-04 17:18 2121次阅读
    最新ChatGPT详细注册图文解说教程  ChatGPT账号注册详细步骤分析

    手把手带您使用MCUXpresso Config Tools生成USB组合设备

    手把手带您使用MCUXpresso Config Tools生成USB组合设备
    的头像 发表于 10-31 16:55 649次阅读
    <b class='flag-5'>手把手</b>带您使用MCUXpresso Config Tools生成USB组合设备

    LOTO示波器_从零开始手把手测电源开环增益/电源环路频响曲线/PSM

    我们之前有篇文章从理论到实践演示了如何测量电源环路的开环增益曲线,不过偏重于理论和原理,没有很多细节的展现,所以这片文章从另外的角度,从零基础开始,手把手一步一步演示如果进行实操测试。
    的头像 发表于 10-26 16:08 396次阅读
    LOTO示波器_从零开始<b class='flag-5'>手把手</b>测电源开环增益/电源环路频响曲线/PSM

    手把手教你学FPGA仿真

    电子发烧友网站提供《手把手教你学FPGA仿真.pdf》资料免费下载
    发表于 10-19 09:17 1次下载
    <b class='flag-5'>手把手</b><b class='flag-5'>教你</b>学FPGA仿真

    手把手教你基于RT-Thread Studio使用STM32单片机的PWM外设

    目前我使用的是STM32L475系列单片机,是ali当时在PDD 50块钱卖的一个开发板,其他STM32单片机参考即可,这里会手把手教大家基于RTT Studio 来使用PWM。
    的头像 发表于 09-28 15:12 2343次阅读
    <b class='flag-5'>手把手</b><b class='flag-5'>教你</b>基于RT-Thread Studio使用STM32<b class='flag-5'>单片机</b>的PWM外设

    手把手教你制作无线充电器

    手把手教你制作无线充电器(无线充电原理+产品应用+DIY实例)
    发表于 09-28 07:48

    用51单片机DIY音乐频谱显示

    该资源是手把手教你用51单片机DIY音乐频谱显示
    发表于 09-27 07:42

    手把手教你pcb压合的整个流程,小白也能玩转电路板制作

    手把手教你pcb压合的整个流程,小白也能玩转电路板制作
    的头像 发表于 09-18 10:43 1407次阅读

    手把手教您家用路由器应该如何挑选

    手把手教您家用路由器应该如何挑选
    的头像 发表于 07-26 09:20 812次阅读
    <b class='flag-5'>手把手</b>教您家用路由器应该如何挑选

    专家手把手教您注册 COS 以及提交 Hardware Case

    Software Case  您可参考: (点击进入☞) 《专家手把手教您注册 COS 以及提交 Case》 。 如您想提交 Hardware Case,本篇将手把手教您,
    的头像 发表于 07-12 12:15 586次阅读
    专家<b class='flag-5'>手把手</b>教您注册 COS 以及提交 Hardware Case

    手把手分享做网线水晶头的技巧

    如今,随着网络技术的飞速发展,电脑已经成为家庭和工作的必备工具。电脑上网需要接入网线。你知道网线两端的插头是怎么做的吗?下面科兰小编手把手分享做网线水晶头的技巧。 做网线水晶头首先要知道网线的结构
    的头像 发表于 07-05 10:35 1207次阅读

    电子初学者必备:手把手教你单片机程序框架

    适合初学单片机的朋友
    发表于 05-31 18:34

    智能面板小程序如何实现跨端开发,并无缝引入ChatGPT?

    手把手教你开发智能面板小程序
    的头像 发表于 04-18 18:31 5204次阅读
    智能面板小程序如何实现跨端开发,并无缝引入ChatGPT?

    【正点原子STM32精英V2开发板体验】资料获取方式

    个,工程结构更加合理、编程风格更加规范化等。教程方面推出了一系列全新的视频!目前已经上架(并持续更新)的视频包括:手把手教你学STM32 HAL库开发教学视频(兼容全系列)、手把手
    发表于 04-13 09:13

    手把手教你学习Spyglass工具

    作为IC设计人员,熟练掌握数字前端语法检查工具Spyglass的重要性不言而喻,本文手把手教你学习Spyglass工具。
    的头像 发表于 04-03 10:46 1542次阅读