[PICO]Swich-Case

Raspberry Pi Pico 2 Switch Case 多分支选择语句

在编程中,switch case 语句是一种多分支选择结构,用于根据变量的值执行不同的代码块。与 if-else 语句相比,switch case 在处理多个离散条件时更加简洁和易读。在 Raspberry Pi Pico 2 编程中,switch case 常用于处理菜单选择、状态机、按键识别等场景。

本文将分别使用 Arduino 风格(基于 Arduino-Pico 核心)和 C/C++ 风格(基于官方 Pico SDK)来介绍 switch case 语句的用法,并提供实际案例。


1. 什么是 switch case 语句?

switch case 语句的基本结构如下:

1
2
3
4
5
6
7
8
9
10
11
switch (variable) {
case value1:
// 当 variable 等于 value1 时执行的代码
break;
case value2:
// 当 variable 等于 value2 时执行的代码
break;
// ... 可以有更多 case
default:
// 当 variable 不等于任何 case 值时执行的代码
}
  • variable:要比较的变量(必须是整型、字符型或枚举类型)。
  • case:后面跟着一个常量值,如果 variable 等于这个值,则执行对应的代码块。
  • break:用于退出 switch 语句,防止继续执行后续的 case 代码块。
  • default:(可选)当 variable 不等于任何 case 值时,执行 default 代码块。

提示:每个 case 块通常以 break 结束。如果省略 break,程序会继续执行下一个 case 的代码(称为“穿透”),这在某些特殊场景下有用,但多数情况下应避免。


2. 代码示例:按钮状态控制 LED

以下是一个简单的示例,使用 switch case 语句根据按钮的状态控制板载 LED(GP25)的开关。

硬件连接

  • 按钮:连接到 GP0GND(使用内部上拉电阻)。
  • LED:使用板载 LED(GP25),无需额外接线。

2.1 Arduino 风格

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const int LED_PIN = 25;      // 板载 LED 连接到 GP25
const int BUTTON_PIN = 0; // 按钮连接到 GP0

void setup() {
pinMode(LED_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP); // 启用内部上拉电阻
}

void loop() {
int buttonState = digitalRead(BUTTON_PIN); // 读取按钮状态(LOW 表示按下)

switch (buttonState) {
case LOW: // 按钮按下
digitalWrite(LED_PIN, HIGH);
break;
case HIGH: // 按钮松开
digitalWrite(LED_PIN, LOW);
break;
default:
// 理论上不会执行到这里
break;
}
}

2.2 C/C++ 风格

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include "pico/stdlib.h"

#define LED_PIN 25
#define BUTTON_PIN 0

int main() {
stdio_init_all();
gpio_init(LED_PIN);
gpio_set_dir(LED_PIN, GPIO_OUT);
gpio_init(BUTTON_PIN);
gpio_set_dir(BUTTON_PIN, GPIO_IN);
gpio_pull_up(BUTTON_PIN); // 启用内部上拉电阻

while (true) {
int buttonState = gpio_get(BUTTON_PIN); // 读取按钮状态(0 表示按下)

switch (buttonState) {
case 0: // 按钮按下
gpio_put(LED_PIN, 1);
break;
case 1: // 按钮松开
gpio_put(LED_PIN, 0);
break;
default:
break;
}
sleep_ms(10); // 简单防抖
}
return 0;
}

代码讲解

  1. 变量定义buttonState 存储按钮的当前状态(LOW/HIGH0/1)。
  2. switch 结构:根据 buttonState 的值选择执行哪个 case
  3. case LOW / case 0:当按钮按下时,点亮 LED。
  4. case HIGH / case 1:当按钮松开时,熄灭 LED。
  5. break:每个 case 后都有 break,确保执行完当前分支后退出 switch

3. 实际应用场景

switch case 语句在实际应用中非常有用,尤其是在需要根据多个离散值执行不同操作的情况下。以下是一些常见场景:

  • 菜单系统:根据用户输入的数字选择执行不同功能。
  • 按键识别:识别多个按键(如矩阵键盘)并执行对应操作。
  • 状态机:根据当前状态执行不同的处理逻辑。
  • 命令解析:解析串口接收的命令字符并执行相应操作。

3.1 案例1:串口命令解析

假设我们通过串口发送字符命令来控制板载 LED:

  • 输入 'o''O':打开 LED
  • 输入 'f''F':关闭 LED
  • 输入其他字符:输出错误提示

Arduino 风格

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
const int LED_PIN = 25;

void setup() {
pinMode(LED_PIN, OUTPUT);
Serial.begin(115200);
Serial.println("Enter command: o (on), f (off)");
}

void loop() {
if (Serial.available() > 0) {
char cmd = Serial.read(); // 读取一个字符

switch (cmd) {
case 'o':
case 'O': // 多个 case 共享同一代码块
digitalWrite(LED_PIN, HIGH);
Serial.println("LED ON");
break;
case 'f':
case 'F':
digitalWrite(LED_PIN, LOW);
Serial.println("LED OFF");
break;
default:
Serial.print("Unknown command: ");
Serial.println(cmd);
break;
}
}
}

C/C++ 风格

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include "pico/stdlib.h"

#define LED_PIN 25

int main() {
stdio_init_all();
gpio_init(LED_PIN);
gpio_set_dir(LED_PIN, GPIO_OUT);
printf("Enter command: o (on), f (off)\n");

while (true) {
int ch = getchar_timeout_us(0); // 非阻塞读取
if (ch != PICO_ERROR_TIMEOUT) {
char cmd = (char)ch;

switch (cmd) {
case 'o':
case 'O':
gpio_put(LED_PIN, 1);
printf("LED ON\n");
break;
case 'f':
case 'F':
gpio_put(LED_PIN, 0);
printf("LED OFF\n");
break;
default:
printf("Unknown command: %c\n", cmd);
break;
}
}
sleep_ms(10);
}
return 0;
}

备注:示例中 case 'o'case 'O' 共用一个代码块,展示了多个 case 对应同一处理逻辑的用法。

3.2 案例2:温度区间控制(多级风扇)

假设我们有一个模拟温度传感器连接到 GP26(ADC0),根据温度区间控制风扇转速:

  • 温度 < 20℃:风扇关闭
  • 20℃ ≤ 温度 < 28℃:低速(PWM 占空比 30%)
  • 28℃ ≤ 温度 < 35℃:中速(PWM 占空比 70%)
  • 温度 ≥ 35℃:高速(PWM 占空比 100%)

Arduino 风格

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
const int TEMP_SENSOR_PIN = 26;
const int FAN_PWM_PIN = 0; // 使用 PWM 引脚

void setup() {
pinMode(FAN_PWM_PIN, OUTPUT);
Serial.begin(115200);
}

void loop() {
int raw = analogRead(TEMP_SENSOR_PIN);
float voltage = raw * 3.3 / 4095.0;
float temperature = voltage * 100.0; // LM35: 10mV/℃

// 将温度转换为整数区间(用于 switch case)
int tempRange;
if (temperature < 20) tempRange = 0;
else if (temperature < 28) tempRange = 1;
else if (temperature < 35) tempRange = 2;
else tempRange = 3;

switch (tempRange) {
case 0:
analogWrite(FAN_PWM_PIN, 0); // 关闭
Serial.println("Fan: OFF");
break;
case 1:
analogWrite(FAN_PWM_PIN, 77); // 30% of 255 ≈ 77
Serial.println("Fan: LOW");
break;
case 2:
analogWrite(FAN_PWM_PIN, 179); // 70% of 255 ≈ 179
Serial.println("Fan: MEDIUM");
break;
case 3:
analogWrite(FAN_PWM_PIN, 255); // 100%
Serial.println("Fan: HIGH");
break;
}
delay(1000);
}

C/C++ 风格

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include "pico/stdlib.h"
#include "hardware/adc.h"
#include "hardware/pwm.h"

#define TEMP_SENSOR_PIN 26
#define FAN_PWM_PIN 0

int main() {
stdio_init_all();

// 初始化 PWM
gpio_set_function(FAN_PWM_PIN, GPIO_FUNC_PWM);
uint slice = pwm_gpio_to_slice_num(FAN_PWM_PIN);
pwm_set_wrap(slice, 255);
pwm_set_enabled(slice, true);

// 初始化 ADC
adc_init();
adc_gpio_init(TEMP_SENSOR_PIN);
adc_select_input(0);

while (true) {
uint16_t raw = adc_read();
float voltage = raw * 3.3f / 4095.0f;
float temperature = voltage * 100.0f;

int tempRange;
if (temperature < 20) tempRange = 0;
else if (temperature < 28) tempRange = 1;
else if (temperature < 35) tempRange = 2;
else tempRange = 3;

switch (tempRange) {
case 0:
pwm_set_chan_level(slice, pwm_gpio_to_channel(FAN_PWM_PIN), 0);
printf("Fan: OFF\n");
break;
case 1:
pwm_set_chan_level(slice, pwm_gpio_to_channel(FAN_PWM_PIN), 77);
printf("Fan: LOW\n");
break;
case 2:
pwm_set_chan_level(slice, pwm_gpio_to_channel(FAN_PWM_PIN), 179);
printf("Fan: MEDIUM\n");
break;
case 3:
pwm_set_chan_level(slice, pwm_gpio_to_channel(FAN_PWM_PIN), 255);
printf("Fan: HIGH\n");
break;
}
sleep_ms(1000);
}
return 0;
}

提示:由于 switchcase 只能匹配离散常量,这里先用 if-else 将温度映射到区间索引,再使用 switch 进行处理。这种组合方式既清晰又高效。


4. 总结

switch case 语句是 Raspberry Pi Pico 2 编程中非常有用的工具,特别适合处理多个离散条件分支的情况。通过本文的学习,你应该已经掌握了:

  • switch case 的基本语法(两种编程风格)。
  • 按钮状态控制 LED 的完整示例。
  • 串口命令解析温度区间控制等实际应用场景。
特性 说明
适用场景 变量值为有限离散常量(整数、字符、枚举)
优点 结构清晰,比多个 if-else 更易读
注意事项 每个 case 通常需要 break,否则会发生“穿透”

提示:在使用 switch case 时,确保每个 case 块都以 break 语句结束(除非故意需要穿透),以防止意外的代码执行。


5. 附加资源与练习

为了巩固所学知识,建议尝试以下练习:

  • 练习 1:修改按钮控制 LED 的示例,使用 switch case 实现单击点亮 LED、双击闪烁 LED 的功能(需要结合状态机或计时器)。
  • 练习 2:创建一个简单的菜单系统,通过串口输入数字(0-3)选择不同功能,使用 switch case 执行对应操作(如读取传感器、控制 LED 等)。
  • 练习 3:结合矩阵键盘(如 4x4 键盘),使用 switch case 识别按下的按键并输出对应的字符。

通过完成这些练习,你将更深入地理解 switch case 语句的使用方法,并能够将其灵活应用到更复杂的 Pico 2 项目中。


[PICO]Swich-Case
https://ka5fxt.cn/2026/03/30/PICO-Swich-Case/
发布于
2026年3月30日
许可协议