编写一个strlen函数(不用全局变量或局部变量)

本文介绍了一种不使用全局变量或局部变量实现字符串长度计算的方法。通过递归方式,该函数能够计算出给定字符串的实际长度。
```markdown ## 题目重述 用户询问:是否只有 `htim2`、`htim3`、`huart1` 和 `rx_data` 这四个变量需要定义为全局变量?其余如 `mode`、`btn_state` 等是否也需要?需要明确哪些变量必须全局,哪些可以局部。 --- ## 详解 这是一个非常关键的问题!在基于中断的嵌入式系统中,**哪些变量要定义为全局变量,取决于它们是否被中断服务函数(即回调函数)访问**。 我们逐个分析: --- ### ✅ 必须定义为 **全局变量** 的类型: | 变量名 | 是否必须全局 | 原因 | |--------|---------------|------| | `huart1` | ✅ 是 | HAL 库使用,所有 UART 回调依赖它 | | `htim2` | ✅ 是 | 定时器中断回调中判断实例用 | | `htim3` | ✅ 是 | PWM 控制和频率修改需要 | | `rx_data` | ✅ 是 | 串口接收回调中读取接收到的数据 | | `mode` | ✅ 是 | 多个回调函数(UART、EXTI、TIM)都会读它 | | `btn_state` | ✅ 是 | 按键中断和 UART 回调共同控制状态机 | | `led_step` | ✅ 是 | TIM2 中断和主逻辑共同更新流水灯步进 | | `pwm_speed_level` | ✅ 是 | EXTI 和 UART 回调都需要访问 | 👉 **结论:你项目中所有的状态控制变量都必须是全局变量!** 因为这些变量被多个中断回调函数函数访问修改,如果定义在 `main()` 内部,其他函数根本无法访问。 --- ### 🔍 示例说明 假设你这样 ❌: ```c int main(void) { uint8_t mode = 0; // ❌ 局部变量 uint8_t btn_state = 0; // ❌ 局部变量 HAL_UART_Receive_IT(&huart1, &rx_data, 1); while(1){ } } ``` 而在 `HAL_UART_RxCpltCallback` 中: ```c void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (rx_data == '1') { mode = 1; // ❌ 编译错误!mode 未定义 btn_state = 0; // ❌ 同样找不到 } } ``` ➡️ 编译器会报错:“`mode` not declared in this scope” --- ### ✅ 正确做法:全部关键变量声明为全局 ```c /* Global Variables */ UART_HandleTypeDef huart1; TIM_HandleTypeDef htim2; TIM_HandleTypeDef htim3; uint8_t rx_data = 0; // 接收缓冲 uint8_t mode = 0; // 当前模式 uint8_t btn_state = 0; // 按键状态机 uint8_t led_step = 0; // 流水灯步进 uint8_t pwm_speed_level = 0; // 呼吸灯速度等级 ``` 这样才能确保: - 所有中断回调函数都能正确读这些变量; - 状态在不同事件之间持久保存; - 系统稳定运行。 --- ### 🆚 局部变量适用场景(仅限临时使用) 局部变量只适用于: - 临时计算,如 `uint8_t temp = HAL_GPIO_ReadPin(...);` - `sprintf` 缓冲区:`char msg[20];` - 不跨函数传递的数据 例如 ✅: ```c void some_function(void) { char msg[20]; sprintf(msg, "V=%d", pwm_speed_level * 100); HAL_UART_Transmit(&huart1, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY); } ``` 这里的 `msg` 就可以是局部变量。 --- ## 知识点 ### 1. **全局变量的必要性** 被中断回调函数访问的变量必须全局定义,否则无法跨函数共享状态。 ### 2. **状态机变量管理** `mode`、`btn_state` 等控制状态流转的变量需全程持久化,必须为全局。 ### 3. **中断上下文数据可见性** 中断发生在任意时刻,只能访问生命周期长的变量(全局/静态),不能依赖栈上局部变量。 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值