基于HAL库的STM32笔记-13

轮询/阻塞/DMA

轮询模式是阻塞模式,程序等待所有的数据发送/接收完成才会接着向下执行;
而中断与DMA模式是非阻塞模式,它们将任务交给外设后就会接着向下执行,并不会等待数据的发送/接收完成,整个通信流程都交给外设与中断进行控制,通信完成后,再通过中断来通知CPU

什么是extern

在 C 语言中,extern 是一个关键字,主要用于声明一个变量或函数​​在其他文件(或同一文件的其他位置)中已定义​​,从而允许在当前文件中使用它。

1. ​​跨文件访问全局变量​

// file1.c
int global_var = 42;  // 定义全局变量(分配内存)

// file2.c
extern int global_var; // 声明变量(不分配内存)
void func() {
    printf("%d", global_var); // 正确访问
}

2. ​​跨文件调用函数​​

函数默认是 extern 的(可省略),但显式声明可以增强可读性:​

// file1.c
void func() { /* ... */ } // 定义函数

// file2.c
extern void func(); // 声明函数(可省略 extern)

3. ​​使用场景​​

​​头文件中声明全局变量​​
在头文件中用 extern 声明变量,源文件中定义变量:

// globals.h
extern int global_var; // 声明

// globals.c
#include "globals.h"
int global_var = 42;   // 定义

// main.c
#include "globals.h"
int main() {
    printf("%d", global_var); // 正确访问
}

避免重复定义​

如果多个文件都包含同一个头文件,且头文件中直接定义变量(如 int var;),会导致链接错误(重复定义)。通过 extern 声明可避免此问题。

4. ​​声明vs定义​​

extern 是声明(告诉编译器“变量/函数存在,但别处定义”),不是定义(不分配内存)。
未初始化的 extern 变量是声明,初始化的 extern 变量是定义:

extern int a; // 声明
extern int b = 10; // 定义(等价于 int b = 10;)

11:34时提到:i2c.c调用main.c中定义的aht20State变量,需要将此变量在main.h中进行extern声明

原因:i2c.c中#include了i2c.h,i2c.h中#include了main.h,而main.h中声明了aht20State,层层套娃就相当于在i2c.c中已经声明了aht20State。所以i2c.c中的TxCpltCallback/RxCpltCallback函数能够正确调用aht20State变量。

static的作用

在 C 语言中,static 关键字的作用取决于它修饰的对象类型(变量或函数),主要用途如下:

1. ​​修饰局部变量(在函数内部)

​​​​作用​​:将局部变量的生命周期​​延长至整个程序运行期间​​(但作用域仍限制在函数内部)。
​​特点​​:
变量只初始化一次,函数多次调用时保留上一次的值。
默认初始化为 0(普通局部变量默认是垃圾值)。

void counter() {
    static int count = 0;  // 仅初始化一次
    count++;
    printf("Count: %d\n", count);
}

int main() {
    counter();  // 输出 "Count: 1"
    counter();  // 输出 "Count: 2"
    return 0;
}

2. ​​修饰全局变量(在函数外部)​​

​​​​​作用​​:将全局变量的作用域​​限制在当前文件​​(默认全局变量可被其他文件通过 extern 访问)。
​​特点​​:
避免与其他文件中的同名全局变量冲突。
实现“文件级封装”,隐藏变量。

// file1.c
static int hidden_var = 42;  // 仅当前文件可见

// file2.c
extern int hidden_var;  // 编译错误!无法访问其他文件的 static 全局变量

3.修饰函数​​
​​作用​​:将函数的作用域​​限制在当前文件​​(默认函数是 extern 的,可被其他文件调用)。
​​特点​​:
实现“文件级封装”,隐藏函数实现。
避免与其他文件中的同名函数冲突

// file1.c
static void private_func() {  // 仅当前文件可见
    // ...
}

// file2.c
extern void private_func();  // 编译错误!无法访问其他文件的 static 函数
修饰对象作用
​局部变量​延长生命周期(函数多次调用保留值),作用域仍为函数内。
​全局变量​限制作用域到当前文件,避免命名冲突。
​函数​​限制作用域到当前文件,隐藏实现细节。

作用域的类型

1. ​​全局作用域(Global Scope)​

  • ​定义​​:在函数外定义的变量或函数。
  • ​特点​​:
    • 从定义位置开始,到文件末尾均可访问。
    • 默认可被其他文件通过 extern 访问。
    • 生命周期为整个程序运行期间。
int global_var = 10; // 全局变量,全局作用域

void global_func() { // 全局函数,全局作用域
    // ...
}

2. ​​局部作用域(Local Scope / Function Scope)​

  • ​定义​​:在函数内部定义的变量或函数参数。
  • ​特点​​:
    • 仅在函数内部可见,函数外无法访问。
    • 生命周期为函数调用期间(函数结束时销毁)。
void func() {
    int local_var = 20; // 局部变量,局部作用域
}

3. ​​块作用域(Block Scope)​

  • ​定义​​:在代码块(如 {} 包裹的循环、条件语句等)内部定义的变量。
  • ​特点​​:
    • 仅在代码块内可见。
    • C 语言中需使用 {} 明确声明块(C99 标准支持块内变量)。
void example() {
    if (1) {
        int block_var = 30; // 块作用域变量,仅在 if 块内可见
    }
    // 此处无法访问 block_var
}

4. ​​文件作用域(File Scope)​

  • ​定义​​:用 static 修饰的全局变量或函数。
  • ​特点​​:
    • 仅在当前文件内可见,其他文件无法通过 extern 访问。
    • 生命周期为整个程序运行期间。
static int file_scope_var = 40; // 文件作用域变量
static void file_scope_func() {  // 文件作用域函数
    // ...
}

作用域的核心规则​

1.就近原则(Shadowing)​​:
内层作用域的变量会覆盖外层同名变量。

int x = 10; // 全局变量

void func() {
    int x = 20; // 局部变量覆盖全局变量
    printf("%d", x); // 输出 20
}

​​2.访问权限​​:
外层作用域无法访问内层作用域的变量。
内层作用域可以访问外层作用域的变量(如全局变量)。
​​3.生命周期与作用域分离​​:
​​作用域​​决定可见性(哪里能访问)。
​​生命周期​​决定存在时间(何时创建/销毁)。
例如:static 局部变量的作用域是函数内,但生命周期是程序全程。

函数参数传递方式​

1. ​​值传递(C语言默认方式)​

特点​​:将实参的​​值​​复制给形参,函数内修改形参不影响实参。

void swap(int a, int b) {
    int temp = a;
    a = b;
    b = temp;
}

int main() {
    int x = 3, y = 5;
    swap(x, y);     // 实参 x 和 y 的值被复制给形参 a 和 b
    // x 仍为 3,y 仍为 5(未被交换)
}

2. ​​引用传递(通过指针模拟)​

特点​​:传递实参的​​地址​​,函数内通过指针直接操作实参的内存。

void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main() {
    int x = 3, y = 5;
    swap(&x, &y);   // 传递 x 和 y 的地址
    // x 变为 5,y 变为 3
}
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇