在我们使用cubemx创建了工程后 生成的keil文件 虽然我们可以直接使用工程文件进行编辑 (写在工程规定的自己写代码的位置) 但是这个工程是不方便移植的 我们可以自己改造 工程把工程改造成适合移植 并且方便查看的版本
    主要就是使用的结构体把操作、函数、 数组、 指针进行封装
    使用回调函数
    image.png
    可以把调用者与被调用者分开,所以调用者不关心谁是被调用者。它只需知道存在一个具有特定原型和限制条件的被调用函数。简而言之,回调函数就是允许用户把需要调用的函数的指针作为参数传递给一个函数,以便该函数在处理相似事件的时候可以灵活的使用不同的方法。
    方便了系统的调用 而且应用程序不需要管底层函数 ,底层的功能想要增加的话 只需要修改少量代码
    有利于解耦整个程序 把程序分成应用层 中间层 和应用层
    eg

    1. /***********应用层*******/
    2. #include "fun.h"
    3. #include<stdio.h>
    4. #include<stdlib.h>
    5. typedef struct gfun{
    6. int (*pfun)(int);
    7. }gfun; //面向对象思想 进行封装 然后方便工程变大时调用
    8. int myfun(int data)
    9. {
    10. printf("get data:%d\n",data);
    11. return (data*2);
    12. }
    13. int main(int argc,char *argv[])
    14. {
    15. int ret;
    16. gfun gf;
    17. gf.pfun = myfun;
    18. ret = rt_data(100,gf.pfun);
    19. printf("return data:%d\n",ret); //回调函数实现
    20. return 0;
    21. }
    1. /*************底层******fun.h**/
    2. #ifndef _FUN_H_
    3. #define _FUN_H_
    4. int rt_data(int data,int (*tr_fun)()); //回调函数声明
    5. #endif
    1. /*************底层******fun.c**/
    2. #include "fun.h"
    3. int rt_data(int data,int (*tr_fun)())
    4. {
    5. return ((*tr_fun)(data));
    6. } //回调函数的逻辑
    1. /***********具体工程实现************/
    2. typedef struct
    3. {
    4. void (*LED_Fun)(uint8_t,void(*Callback)(uint8_t));
    5. } LED_t;
    6. static void LED_Fun(uint8_t,void(*Callback)(uint8_t));
    7. /* Public variables-----------------------------------------------------------*/
    8. LED_t LED =
    9. {
    10. LED_Fun,
    11. };
    12. /* Private function prototypes------------------------------------------------*/
    13. /*
    14. * @name LED_Fun
    15. * @brief LED功能函数,中间虚拟函数
    16. * @param Num -> 编号,Callback ->回调函数指针
    17. * @retval None
    18. */
    19. static void LED_Fun(uint8_t LED_Num,void(*Callback)(uint8_t))
    20. {
    21. (*Callback)(LED_Num);
    22. }