网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
{undefined
//按键检测程序…
}
然后我们在主程序用:
while(1)
{undefined
Unsigned char key;
If(10ms时间到)
{undefined
Key = ScanKey();
}
if(Key == 有效按键值)
{undefined
//执行按键功能程序
}
}
这样不断地去扫描按键,检测按键是否被按下。
这种方式当然也是可以的,只是不够专业,不够好。
因为这个我需要一直在while循环里判断Key的值,然后根据Key的值来判断有没有按键按下,在一定程度上,造成了cpu资源的浪费。
而且有些应用场景,这种方式不好实现,比如说串口数据,你不能一直在while循环里判断是否有新的串口数据过来吧?
那我们理想的一种状态是什么?
就是如果有按键按下了,或者有新的数据来了,再通知我。
这种通知方式一般叫事件触发,就是触发了按键这个事件,我才去处理。
所以,这个时候回调函数就能很好地解决这种需求。
我们还是拿按键来举例。
前面我说每个人写回调函数的风格可能都不一样,STM32固件库的那些中断处理函数基本都是回调函数,但是跟我的编写风格还是有些差异。
我们在写回调函数的时候,需要以下几步:
第一步:
自定义一个函数指针类型,类型名称是KeyEvent_CallBack_t。
typedef void (*KeyEvent_CallBack_t)(KEY_VALUE_TYPEDEF keys);
还有这个一般是要自定义在头文件,因为别的.c文件也会用到。
这是一个无返回值的,形参是KEY_VALUE_TYPEDEF枚举类型的函数指针类型。
一般这个形参keys就是我们最终要通过回调函数传递到别的.c文件的信号/数据,如果是按键检测的话也就是按键值,是哪个按键按下的。
我们来看下KEY_VALUE_TYPEDEF这个枚举都有哪些值?
typedef enum
{undefined
KEY_IDLE_VAL,
KEY1_CLICK,
KEY1_CLICK_RELEASE,
KEY1_LONG_PRESS,
KEY1_LONG_PRESS_CONTINUOUS,
KEY1_LONG_PRESS_RELEASE, //5
KEY2_CLICK, //6
KEY2_CLICK_RELEASE,
KEY2_LONG_PRESS,
KEY2_LONG_PRESS_CONTINUOUS,
KEY2_LONG_PRESS_RELEASE,
KEY3_CLICK, //11
KEY3_CLICK_RELEASE,
KEY3_LONG_PRESS,
KEY3_LONG_PRESS_CONTINUOUS,
KEY3_LONG_PRESS_RELEASE,
KEY4_CLICK, //16
KEY4_CLICK_RELEASE,
KEY4_LONG_PRESS,
KEY4_LONG_PRESS_CONTINUOUS,
KEY4_LONG_PRESS_RELEASE,
KEY5_CLICK, //21
KEY5_CLICK_RELEASE,
KEY5_LONG_PRESS,
KEY5_LONG_PRESS_CONTINUOUS,
KEY5_LONG_PRESS_RELEASE,
KEY6_CLICK, //26
KEY6_CLICK_RELEASE,
KEY6_LONG_PRESS,
KEY6_LONG_PRESS_CONTINUOUS,
KEY6_LONG_PRESS_RELEASE,
}KEY_VALUE_TYPEDEF;
我们这个项目总共有6个按键,每个按键需要检测短按、短按释放、长按、长按释放、连续长按这5个功能,所以总共有30个不同的枚举值分别来对应不同按键的不同功能。
第二步:
自定义了函数指针类型以后,我们就可以通过KeyEvent_CallBack_t这个类型名称,去定义我们的函数指针变量。
KeyEvent_CallBack_t KeyScanCBS;
那KeyScanCBS就是函数指针,所以它的返回值是void类型,形参是KEY_VALUE_TYPEDEF枚举类型的。
最终就是把这个指针指向别的.c文件的函数,从而实现不同.c文件之间的数据传递,同时又能保持很好的可移植性(相互独立,互不干扰)。
那怎么指向呢?我的方法是重新定义一个函数,专门来为这个指针指向,这样方便别的.c文件调用,这个函数我称为注册函数。
比如以下函数:
void hal_KeyScanCBSRegister(KeyEvent_CallBack_t pCBS)
{
if(KeyScanCBS == 0)
{
KeyScanCBS = pCBS;
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
45577999)]
[外链图片转存中…(img-4aiqFaOA-1715645577999)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新