2024.1.21随堂笔记 LED驱动

Copyright (c) 2024 by Jsir2022, All Rights Reserved.

堆跟栈有什么区别?(确实常考)
Pasted image 20240121141504.png
这有文章嵌入式软件常见的 8 种数据结构说了一下,而ChatGPT4给出的具体区别如下:
堆(Heap)和栈(Stack)是程序在运行时用来存储数据的内存区域,它们在管理内存和数据存储方面有各自的特点和用途。以下是堆和栈的详细区别,分不同方面进行讲解:

  1. 管理方式:

    • 栈:由操作系统自动管理,无需程序员手动控制。它通常用于存放局部变量和函数调用的上下文信息。栈有严格的先入后出(LIFO)的数据结构,即最后压入栈的元素必须第一个出栈。
    • 堆:通常由程序员分配释放,若使用垃圾回收语言,则可能由垃圾回收器管理。堆用于存放动态分配的内存,大小不定且不会自动释放。
  2. 存储内容:

    • 栈:存储函数的参数值、局部变量的值等。这些数据通常只在函数的执行期间存在。
    • 堆:主要存储动态分配的内存数据,如用new、malloc等语句分配的内存块。
  3. 存储空间大小:

    • 栈:栈的大小通常由操作系统预设,空间较小。超出栈的容量会引发栈溢出错误(Stack Overflow)。
    • 堆:堆的大小受到可用系统内存的限制,理论上远大于栈,能够分配的内存空间更大。
  4. 访问速度:

    • 栈:栈具有固定的访问模式,且数据通常存储在连续的内存地址中,因此访问速度快。
    • 堆:堆上的数据分布可能比较杂乱,且由于涉及动态内存分配,可能会有较大的开销,访问速度相对较慢。
  5. 分配方式:

    • 栈:内存分配由程序自动进行,当函数被调用时会自动在栈上创建局部变量。
    • 堆:内存分配由程序员通过代码显式进行,需要使用专门的内存分配函数。
  6. 生命周期:

    • 栈:栈内存的生命周期通常随着函数的执行而开始,函数结束时局部变量也随之销毁。
    • 堆:堆内存的生命周期则不受特定函数的影响,它由程序员控制,不正确的管理可能导致内存泄露。
  7. 碎片问题:

    • 栈:由于栈的LIFO特性,栈不会有碎片问题,内存分配和释放的顺序非常有序。
    • 堆:堆分配和释放内存可能导致碎片,即小块的未使用内存散落在分配过的内存间,这可能会导致内存的使用效率降低。
  8. 线程安全性:

    • 栈:每个线程通常都有自己的栈,因此栈空间在多线程环境下是线程安全的。
    • 堆:由于堆是由所有线程共享的,因此在多线程环境下对堆的操作需要考虑同步机制,以避免竞态条件。

了解这些区别有助于程序员更好地管理内存使用,提高程序的效率和稳定性。在实际编程中,合理使用堆和栈可以避免内存泄露、栈溢出等问题。

02 CubeMX配置引脚是想一次性配好引脚节省时间。引脚的默认电平设置LED为高电平,锁存为低电平,所以开机不会闪灯。
Pasted image 20240121150935.png

查HAL库直接看头文件
Pasted image 20240121151252.png

避免魔鬼数字,用宏定义或枚举设置别名
Pasted image 20240121154023.png

有不同设备但函数相同的工程上常用方法:用#ifdef和#endif,此时利用宏定义#define就能让这个设备使能或者失能。我曾在第十八届智能车省赛决赛中,疏忽了被屏蔽的陀螺仪代码,与国赛失之交臂。如果你的代码能用上宏定义和对应的设备自检提示,上场前就能发现问题及时解决。

做比赛应该跟做工程一样,大体框架搭好后面顺顺利利。你的框架可以有针对性的,比如稳定性要多点还是敏捷开发多点。当然,蓝桥杯不需要这么麻烦。
Pasted image 20240121162127.png

我自己写直接s_unLED_data.stLED.bLED1=ON或者OFF完事,老师这么写相当于模块偏向工程,放C++中就是对应变量有对应的操作函数,而不是直接操作寄存器那样直接。当然,蓝桥杯不需要这么麻烦。
Pasted image 20240121163727.png