做嵌入式开发的小伙伴,是不是总在写代码时卡壳?明明硬件电路接好了,可 C 语言函数不会用,传感器数据读不出来,LED 灯死活不亮。其实啊,嵌入式开发里的 C 语言函数就那么些常用的,把它们吃透了,写代码能省不少事。今天兔子哥就聊聊嵌入式开发里最常用的几类函数,附上市面上常见的实例代码,新手常问的 “GPIO 函数怎么用”“延时函数怎么写” 这些问题,咱们一个个说清楚,一起往下看吧!
硬件初始化函数:让设备 “醒过来” 的关键
刚接触嵌入式的朋友可能会问:“为啥电路接好了,程序烧进去没反应?” 很大可能是硬件初始化没做好。就像用手机得先开机一样,单片机、传感器这些硬件也得通过初始化函数 “唤醒”,设置好工作模式才能用。
最常用的就是 GPIO 初始化函数,比如 STM32 里的
GPIO_Init(),51 单片机里的P0=0xFF这类操作。说白了,就是告诉单片机 “哪个引脚是输入、哪个是输出”“输出高电平还是低电平”。给大家看个 51 单片机初始化 LED 灯的例子:c
// 初始化P1口为输出,控制LEDvoid LED_Init() {P1 = 0xFF; // 先让所有LED灭}是不是很简单?不过不同芯片的初始化函数格式不一样,比如 STM32 的 GPIO 初始化要配置结构体,51 单片机直接操作寄存器就行。之前有个粉丝用 STM32 时,忘了配置 GPIO 的工作模式,结果 LED 一直不亮,查了半天才发现是初始化函数少了一行模式设置,这细节可得注意。
GPIO 操作函数:控制硬件的 “开关”
初始化完硬件,就得用 GPIO 函数控制它工作了,比如点亮 LED、读取按键状态。这类函数虽简单,但用错了也容易出问题。兔子哥整理了最常用的两类 GPIO 函数实例:
| 函数功能 | 51 单片机实例代码 | STM32 实例代码 |
|---|---|---|
| 输出高低电平 | P1_0 = 0; // 点亮 LED | HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET); |
| 读取输入状态 | key_state = P3_2; // 读按键 | key_state = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1); |
有朋友问:“为啥我的按键读取总不稳定?” 这多半是没加消抖处理。按键按下时会有机械抖动,直接读状态可能忽高忽低,最好在读取函数里加个延时,比如:
c
// 带消抖的按键读取函数uint8_t Read_Key() {uint8_t state;state = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1);if(state == 0) { // 检测到按键按下HAL_Delay(10); // 延时10ms消抖if(state == HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1)) {return 1; // 确认按下}}return 0;}这样读出来的按键状态就稳定多了,这小技巧在实际开发中特别管用。
延时函数:让程序 “等一等”
嵌入式开发里经常需要延时,比如 LED 闪烁要等几百毫秒,传感器采集数据要等稳定。延时函数虽简单,但不同芯片实现方式不一样,用错了会影响程序效率。
新手最常用的是
HAL_Delay()(STM32)或delay_ms()(51 单片机)这类毫秒级延时函数,比如让 LED 闪烁的代码:c
// LED闪烁函数void LED_Blink() {while(1) {HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_0); // 翻转电平HAL_Delay(500); // 延时500ms}}不过话说回来,用
HAL_Delay()时要注意,它是阻塞式延时,延时期间程序啥也干不了。如果需要同时做其他事,就得用定时器中断做非阻塞延时,这部分稍微复杂点,新手可以先掌握基础延时函数,后面再学进阶用法。之前有个粉丝在主循环里用了太长的延时,导致按键响应变慢,就是没搞懂阻塞延时的问题。传感器数据读取函数:跟硬件 “对话”
做嵌入式开发常要接传感器,比如温湿度传感器、光照传感器,这时候就得用数据读取函数跟传感器 “对话”。以常用的 DHT11 温湿度传感器为例,它的读取函数要严格按照通信时序来:
c
// 简化的DHT11读取函数uint8_t DHT11_ReadData(uint8_t *temp, uint8_t *humi) {// 发送起始信号HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_RESET);HAL_Delay(20);HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_SET);HAL_Delay(30);// 读取响应信号和数据(省略具体时序判断)// ...*temp = 25; // 假设读到温度25℃*humi = 60; // 假设读到湿度60%return 1; // 读取成功}这类函数的关键是严格遵守传感器的数据手册,时序错一点就可能读不到数据。有个粉丝用 DHT11 时,起始信号的延时时间不够,结果一直读不到数据,后来对照手册调整了延时才搞定,所以数据手册一定要多看。
串口通信函数:让设备 “说话”
嵌入式设备常需要通过串口跟电脑或其他设备通信,比如打印调试信息、发送传感器数据。串口初始化和收发函数是必学的,以 STM32 的 HAL 库为例:
c
// 串口初始化(在main函数里调用)void UART_Init() {MX_USART1_UART_Init(); // 初始化串口1}// 发送字符串函数void UART_SendString(uint8_t *str) {HAL_UART_Transmit(&huart1, str, strlen((char*)str), 100);}// 接收数据中断回调函数void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {if(huart == &huart1) {// 处理接收到的数据UART_SendString("收到数据啦:");HAL_UART_Transmit(&huart1, &rx_data, 1, 100);HAL_UART_Receive_IT(&huart1, &rx_data, 1); // 重新开启接收中断}}用串口时要注意波特率、数据位、校验位这些参数,两边设备必须设置一致,不然会出现乱码。之前有个粉丝调试时,电脑串口助手波特率设成 9600,单片机设成 115200,结果收到的全是乱码,改一致就好了。
最后说点个人心得吧。嵌入式开发里的 C 语言函数,重点不在记多少,而在理解每个函数的作用和使用场景。不同芯片的函数库可能不一样,但核心逻辑相通,比如 GPIO 操作无非就是读写电平,传感器读取都是按时序通信。新手刚开始可以照着实例代码改,改多了就知道怎么自己写了。还有就是数据手册一定要多看,硬件特性都在里面,比单纯记函数管用多了。坚持练这些常用函数,用不了多久你就会发现,嵌入式开发没那么难,写代码也会越来越顺!
版权声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。
还木有评论哦,快来抢沙发吧~