嵌入式 C 语言入门:分支结构(if/switch)的用法与硬件控制实践

前言

在上一篇笔记中,我们掌握了关系运算和逻辑运算,这些运算就像 “数字开关”,能帮助我们判断条件的真假。而在实际开发中,我们需要根据不同的条件执行不同的代码 —— 比如检测到按键按下时点亮 LED,或者根据传感器数据选择不同的处理方式。这就需要用到 C 语言中的分支结构:if 语句switch 语句。它们是代码 “智能决策” 的基础,也是控制硬件行为的关键工具。

🔀 if 语句:条件判断的基石
基础语法与执行逻辑

if 语句的基本形式如下:

if(条件表达式1){
	// 条件表达式1为真时执行的代码
} else if(条件表达式2){
	// 条件表达式2为真时执行的代码
} else{
	// 所有条件都不满足时执行的代码
}

我们通过一个 “判断数字位数” 的例子来理解:

#include <stdio.h>
#include <string.h>
int mymain(void)
{
	int num;
	printf("请输入一个正整数:\n\r");
	scanf("%d", &num);
	
	if(num >= 1000) {
		printf("这个数是四位及以上的数\n\r");
	}
	else if(num >= 100) {
		printf("这个数是三位数\n\r");
	}
	else if(num >= 10) {
		printf("这个数是两位数\n\r");
	}
	else if(num >= 1) {
		printf("这个数是一位数\n\r");
	}
	else {
		printf("这个数是负数\n\r");
	}
	return 0;
}

这里有个重要的隐含逻辑:当执行到else if(num >= 100)时,其实已经隐含了num < 1000的条件 —— 因为如果num >= 1000,就会执行第一个 if 分支并跳出整个 if 语句。因此,这个条件等价于num >= 100 && num < 1000,只是被隐含省略了。

在硬件控制中的应用:LED 状态翻转

在嵌入式开发中,if 语句常用于根据硬件状态执行相应操作。比如我们要实现 LED 状态的翻转:

有关点灯的基础知识可见我结构体(三)的笔记

#include <stdio.h>
#include <string.h>
int mymain(void)
{
	// 获取GPIO输出数据寄存器(ODR)的地址(不同开发板可能不同)
	volatile unsigned int *p = (volatile unsigned int *)0x40021414;
	
	// 判断LED当前状态并翻转
	if((*p & (1 << 9)) == 0) {  // 若LED当前为熄灭状态(bit9为0)
		*p |= (1 << 9);         // 点亮LED(将bit9置1)
	}
	else {                      // 若LED当前为点亮状态(bit9为1)
		*p &= ~(1 << 9);        // 熄灭LED(将bit9清0)
	}
	return 0;
}

这里的*p & (1 << 9)用于检测 ODR 寄存器的第 9 位是否为 1,结合按位与和逻辑判断,就能根据 LED 当前状态做出相反操作。这种 “检测 - 决策 - 执行” 的模式在硬件控制中非常常见。

🎛️ switch 语句:多分支选择的利器
语法结构与执行流程

当需要根据一个变量的多个可能值执行不同代码时,switch 语句比 if 更简洁:

switch(表达式){
	case1:
		// 执行代码块1
		break;
	case2:
		// 执行代码块2
		break;
	...
	default:
		// 表达式不匹配任何case时执行的代码
}

需要注意的是,break 语句决定了执行完当前 case 后是否继续执行后续 case。如果没有 break,会发生 “穿透” 现象 —— 继续执行下一个 case 的代码,直到遇到 break 或 switch 结束。
我们通过一个 “星期判断” 的例子验证:

#include <stdio.h>
#include <string.h>

int main(void)
{
	int day;
	printf("请输入一个1-7的整数:");
	scanf("%d", &day);
	
	switch(day)
	{
		case 1:
			printf("星期一\n\r");
		case 2:
			printf("星期二\n\r");
			break;
		case 3:
			printf("星期三\n\r");
			break;
		// 其余case省略...
		default:
			printf("输入错误\n\r");
			break;
	}
	return 0;
}

当输入 1 时,代码会输出 “星期一” 和 “星期二”—— 因为 case 1 没有 break,执行完后会继续执行 case 2,直到遇到 break 才跳出:
请添加图片描述
请添加图片描述

switch 在硬件控制中的应用

同样是 LED 状态翻转,我们用 switch 语句实现:

#include <stdio.h>
#include <string.h>
int mymain(void)
{
	volatile unsigned int *p = (volatile unsigned int *)0x40021414;
	
	// 根据LED当前状态选择操作
	switch((*p & (1 << 9)))
	{
		case 0:             // 若LED当前为熄灭状态
			*p |= (1 << 9);  // 点亮LED
			break;
		case (1 << 9):      // 若LED当前为点亮状态(注意这里是1<<9而非1)
			*p &= ~(1 << 9); // 熄灭LED
			break;
	}
	return 0;
}

这里有个细节:case (1 << 9)而非case 1—— 因为*p & (1 << 9)的结果是 “第 9 位为 1,其余位为 0” 的数值(即0x00000200),而不是简单的 1。直接点说,这里的 (1 << 9)甚至可以换成(0x00000200)

🔄 if vs switch:何时该用谁?
  • if 语句适合处理连续的范围判断(如数值区间),或逻辑复杂的条件组合;
  • switch 语句适合处理离散的固定值判断(如枚举值、状态码),代码更清晰;
  • 穿透特性可用于实现 “多个条件执行相同代码” 的场景(如多个按键触发同一操作)。
结尾

这篇笔记中,我们学习了 if 和 switch 两种分支结构,它们就像代码中的 “智能开关”,能根据不同条件控制程序走向。在嵌入式开发中,这些分支结构是实现硬件状态检测、事件响应的基础 —— 比如根据按键状态切换 LED 模式,或者根据传感器数据选择不同的处理策略。
下一篇,我们将学习循环结构,它能让代码 “重复做同一件事”,是实现定时任务、数据采集的关键工具。Hello_Embed 与你一起,步步深入嵌入式开发的核心。下篇见!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值