【STM32】通俗易懂的讲解回调函数

转载:https://blog.csdn.net/vincent040/article/details/50832955

回调函数在程序开发中是一个非常重要的概念,所谓的回调其实就是不同程序模块之间的接口和约定,是软件分层设计的基本方式。

拓展:

回调(callback)是一种非常重要的机制,主要可以用来实现软件的分层设计,使得不同软件模块的开发者的工作进度可以独立出来,不受时空的限制,需要的时候通过约定好的接口(或者标准)相互契合在一起,也就是C++或者JAVA等现代编程语言声称的所谓面向接口编程。同时回调也是定制化软件的基石,通过回调机制将软件的前端和后端分离,前端提供逻辑策略,后端提供逻辑实现。

我们知道C语言中的函数实际上就相当于一个人,你给他一些参数,他帮你完成一样固定的功能,比方说你给厨师一个菜名,他将会把这道菜烹饪出来,你给医生一位病人,他将会对这位病人进行医治等等,这里,厨师和医生都相当于功能确切的函数,等着你来调用。我们身边不乏有很多这样的“函数”,假设你每天都到食堂吃饭,慢慢地你发现每次吃饭来回一趟走路的时间太长,于是你想让前台小妹吃饭时顺便帮你打饭回来,那么,在小妹外出午餐之前,你传递一些参数给她(比方说:10块钱,以及说清楚你要吃什么),半个小时后,小妹拿着饭堂热腾腾的盒饭回来给你。这就是普通函数的调用过程:你调用了小妹,实现了你脚不挪手不动也能吃上饭的夙愿,用图来说明一下这个过程:

在这里插入图片描述

那什么是回调呢?

吃了食堂的饭一个礼拜之后,实在太难吃,你已经确定你无法再吃下去了,于是你决定不吃食堂的饭,改为自己做饭吃,当然你不能亲自出马,你还是调用前台小妹帮你干活,这次你也必须给她一些钱,以及你想吃的东西,让她帮你去菜市场买回来做好,端给你吃。虽然前台小妹非常愿意为你效劳,她可以跑腿、买菜、砍价、端茶递水,但可惜她不会做饭,你急中生智,果断地从黑市雇佣了一名资深大厨,啥也不会就会做饭,你只要给他材料就行了。这样,你的午饭的产生过程变成了:你将要吃的菜品清单和需要花的钱传递给前台小妹,不仅如此,你还把大厨的电话号码给到小妹,叮嘱说:买了菜就打这个电话,让他帮你把菜做了,然后你捯饬好了给我送过来。于是小妹屁颠屁颠地就出去买菜了,与此同时,你可以“定制”你的大厨,你叮嘱你的大厨说:大厨,我喜欢吃辣,以后你做的任何菜里,都要放够足量的辣椒。请看:

在这里插入图片描述

在上面的“午饭”秀中,实现了典型的回调机制,你定制了一位做任何菜都死命放辣椒的大厨,然后你在调用前台小妹的同时,将大厨的电话号码也给到她,小妹在需要做饭的时候,就会根据你提供的参数(大厨的电话)回过去调用(回调!)那位大厨,做好饭后小妹再细心地捯饬捯饬,端给你吃。

你还应该注意到,在上图中一个最重要的信息:左边的两个人和右边的那个人之间有一条饱含深意的虚线,他意味着左右两边是两拨人,左边的人负责做饭和吃饭,右边的人负责跑腿、砍价等。比如:你只要知道怎么找到前台小妹,传给她参数让她干活就行了,根本不需要知道她究竟到哪儿买的菜跑了多远的路,另外管好大厨,让他死命放辣椒就行了,也根本不需要管小妹什么时候会去找大厨,以及他们之间的任何其他事情。对于右边的小妹而言,她只要根据你的嘱咐勤快跑腿,有必要的时候“回调”一下大厨就行了,也根本不管大厨做的饭究竟啥口味。

瞧,左右两拨人各干各的,互不耦合,独立性强,但又可以非常方便地相互合作,达成一个更丰富的功能。这里,大厨就是一个回调函数——一个不被设计者(你)直接调用,而是被其他人(小妹)回过来调用的函数。你传递给小妹的电话号码,相当于一个能找到大厨的指针,被称之为函数指针,回调机制就是靠传递函数指针来告知回调函数的位置的。

<think>好的,用户现在想让我以精通STM32单片机的老师的身份来解答他的问题。首先,我需要确定他的学习阶段和具体需求。他可能刚开始学习,需要基础知识的讲解,或者已经在做项目,遇到了具体问题。不过,根据问题描述,他可能处于初级阶段,需要系统的指导。 接下来,我应该考虑如何结构化回答。用户要求结构清晰,逐步解决问题,所以分步骤或分模块讲解比较合适。STM32涵盖的内容很多,包括开发环境、GPIO、时钟系统、中断、外设、RTOS、调试工具、常见问题等。需要覆盖这些方面,但不要过于深入,以免让用户感到困惑。 用户提到使用中文回答,并且需要符合LaTeX格式的数学表达式,但在这个问题中可能涉及数学的地方不多,不过如果有公式,比如计算时钟频率或PWM占空比,需要正确应用规则。例如,计算时钟频率时可能需要用到分频公式,这时候需要用$$...$$来展示。 还需要注意用户可能存在的误区,比如直接跳入复杂项目而不打基础,或者对库函数和寄存器操作的区别不清楚。应该提醒他先掌握基础,再逐步深入。 另外,用户可能没有明确说出具体的问题,所以作为老师,我应该先概述STM32学习的核心内容,然后分点详细讲解,最后给出学习建议和常见问题。这样既全面又有条理,帮助用户建立知识框架。 最后,确保语言通俗易懂,避免过多专业术语,必要时举例说明,比如用LED闪烁的例子解释GPIO操作,或者用定时器控制PWM的例子说明外设的使用。同时,鼓励用户动手实践,强调实践的重要性,并提供资源推荐,帮助他进一步学习。</think>我将以STM32开发工程师的视角,为您构建系统的学习路径。以下是关键知识点和操作指南: 一、开发环境搭建(基础关键) 1. 工具链选择 $$Keil\ MDK-ARM\ 或\ STM32CubeIDE\ (推荐)$$ 2. 新建工程步骤: - 安装STM32CubeMX - 配置时钟树(重点) - 生成初始化代码 - 添加用户代码区 二、GPIO操作核心要点 ```c // 标准操作流程 GPIO_InitTypeDef GPIO_InitStruct = {0}; __HAL_RCC_GPIOA_CLK_ENABLE(); // 使能时钟 GPIO_InitStruct.Pin = GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); ``` 三、时钟系统架构 $$\text{系统时钟} = \frac{\text{HSI/HSE频率} \times \text{PLLN}}{\text{PLLM} \times \text{PLLP}}$$ 1. 掌握时钟树结构图 2. 使用STM32CubeMX可视化配置 3. 验证时钟配置: ```c SystemCoreClockUpdate(); printf("系统时钟频率: %lu Hz", SystemCoreClock); ``` 四、中断处理进阶技巧 1. NVIC优先级分组设置 ```c HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); ``` 2. 中断服务函数编写规范 ```c void EXTI0_IRQHandler(void) { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0); } void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { // 用户回调代码 } ``` 五、外设驱动开发要点 1. USART通信标准配置: - 波特率计算:$$BRR = \frac{f_{CK}}{波特率}$$ - DMA模式配置 2. ADC采样注意事项: - 参考电压稳定 - 采样时间设置 - 软件触发与硬件触发选择 六、实时操作系统(RTOS)应用 1. FreeRTOS任务创建: ```c xTaskCreate(vTaskLED, "LED_Task", 128, NULL, 1, NULL); ``` 2. 信号量使用规范: ```c SemaphoreHandle_t xSemaphore = xSemaphoreCreateBinary(); ``` 七、调试技巧(工程师必备) 1. SWD接口接线规范: - SWCLK: 第37脚 - SWDIO: 第34脚 - GND: 就近接地 2. 断点设置原则: - 避免在中断服务函数设置过多断点 - 使用条件断点调试特定数据 学习建议: 1. 硬件选型从STM32F1系列入门(如STM32F103C8T6) 2. 每日实践:LED→按键→定时器→串口→ADC的渐进路线 3. 必备工具清单: - ST-Link V2调试器 - 逻辑分析仪(建议24MHz以上) - 万用表(真有效值型) 常见问题解决方案: 1. 程序无法下载: - 检查BOOT0引脚电平 - 验证复位电路设计 2. 外设不工作: - 确认时钟使能 - 检查复用功能映射 3. 异常功耗: - 使用Stop模式 - 配置未用引脚为模拟输入 推荐学习资源: 1. 官方文档:《STM32参考手册》 2. 实践平台:正点原子/野火开发板 3. 进阶教材:《Cortex-M3权威指南》 请根据当前学习阶段选择具体问题进行深入讨论,建议从GPIO控制LED开始实践,逐步扩展到定时器PWM输出等应用。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值