本帖最后由 gjianw217 于 2015-10-17 23:56 编辑
本帖主要内容:本帖子主要使用庆科提供的MiCOKit开发环境,来测试板上的2个Key的响应,并简单了解MiCOKit的封装。 一、测试环境: 庆科开发套件EMW3165底板和扩展板 庆科SDK_MiCOKit_v2.3.0.2 USB串口线 串口调试助手
二、硬件分析: 在EMW3165套件上,一共配置了4个按键,如下图所示,其中底板2个,扩展板2个,如图中所示,当按键按下时,对应引脚接地,为低电平,否则为高电平。
另外通过查看原理图和 开发板,各个按键分别对应 EMW3165无线控制模块的引脚,如下图所示:
三、软件分析: 1 软件分层
在庆科提供的 SDK_MiCOKit_v2.3.0.2开发包中,进行了三层的软件封装,即:用户层(外设层),平台层,驱动层。
(1)用户层(外设层),定义在 SDK_MiCOKit_v2.3.0.2/Platform/Drivers/MiCOKit_EX/目录下,主要通过调用平台层的封装函数,定义了各扩展板上外设的操作,用户只要调用它们,而无需知道各外设的原理,即可对其进行操作。 (2)平台层 定义在SDK_MiCOKit_v2.3.0.2/Platform/Peripherals/目录下,以platform_xxx.h命名,主要通过调用驱动层的封装函数,定义了MiCO系统需要调用的接口,方便将MiCO移植到不同的芯片平台上。
(3)驱动层 定义在SDK_MiCOKit_v2.3.0.2/Platform/Peripherals/Libraries/ STM32F4xx_StdPeriph_Driver/目录下,以stm32f4xx_xx.c命名,主要移植了有关芯片提供商提供的对芯片操作的接口函数。 2 软件定义
在 SDK_MiCOKit_v2.3.0.2PlatformDriversMiCOKit_EXTkey目录下的key.c文件中,定义了4+4+2个函数,实现对按键初始化以及单击和长按事件的响应函数,在分析具体函数前,需要弄明白两个关键字: static和weak下面是摘自维基百科的一段话:
A weak symbol denotes a specially annotatedsymbol during linking of Executable and Linkable Format (ELF) object files. Bydefault, without any annotation, a symbol in an object file is strong. Duringlinking, a strong symbol can override a weak symbol of the same name. Incontrast, two strong symbols that share a name yield a link error duringlink-time. When linking a binary executable, a weakly declared symbol does notneed a definition. In comparison, (by default) a declared strong symbol withouta definition triggers an undefined symbol link error.
Astaticvariable is a variable that ha***een allocated statically in computer programming,—whose lifetime or"extent" extends across the entire run of the program. This is incontrast to the more ephemeral automatic variables (local variables aregenerally automatic), whose storage is allocated and deallocated on the callstack; and in contrast to objects whose storage is dynamically allocated in heapmemory.
在key.c文件中,
首先是2个初始化函数:在初始化函数中,首先将按键对应的引脚初始为上拉输入模式,然后为其初始化一个定时器,如果在规定的时间内按下按键,则响应定时中断任务,最后将其初始化为下降边沿中断,如果按键被按下,则响应相应的事件。
- void user_key1_init(void)
- {
- MicoGpioInitialize( (mico_gpio_t)USER_KEY1, INPUT_PULL_UP );
- mico_init_timer(&_user_key1_timer, user_key1_long_press_timeout, _user_key1_timeout_handler, NULL);
- MicoGpioEnableIRQ( (mico_gpio_t)USER_KEY1, IRQ_TRIGGER_FALLING_EDGE, _user_key1_irq_handler, NULL );
- }
- void user_key2_init(void)
- {
- MicoGpioInitialize( (mico_gpio_t)USER_KEY2, INPUT_PULL_UP );
- mico_init_timer(&_user_key2_timer, user_key2_long_press_timeout, _user_key2_timeout_handler, NULL);
- MicoGpioEnableIRQ( (mico_gpio_t)USER_KEY2, IRQ_TRIGGER_FALLING_EDGE, _user_key2_irq_handler, NULL );
- }
复制代码
其次,其定义了4个静态本地函数,通过逻辑判断,实现相应按键响应长按事件还是单击事件
- static void _user_key1_irq_handler( void* arg )
- {
- (void)(arg);
- int interval = -1;
-
- if ( MicoGpioInputGet( (mico_gpio_t)USER_KEY1 ) == 0 ) {
- _default_key1_start_time = mico_get_time()+1;
- mico_start_timer(&_user_key1_timer);
- MicoGpioEnableIRQ( (mico_gpio_t)USER_KEY1, IRQ_TRIGGER_RISING_EDGE, _user_key1_irq_handler, NULL );
- }
- else {
- interval = mico_get_time() + 1 - _default_key1_start_time;
- if ( (_default_key1_start_time != 0) && interval > 50 && interval < user_key1_long_press_timeout){
- /* button clicked once */
- user_key1_clicked_callback();
- MicoGpioEnableIRQ( (mico_gpio_t)USER_KEY1, IRQ_TRIGGER_FALLING_EDGE, _user_key1_irq_handler, NULL );
- }
- mico_stop_timer(&_user_key1_timer);
- _default_key1_start_time = 0;
- }
- }
- static void _user_key1_timeout_handler( void* arg )
- {
- (void)(arg);
- _default_key1_start_time = 0;
- MicoGpioEnableIRQ( (mico_gpio_t)USER_KEY1, IRQ_TRIGGER_FALLING_EDGE, _user_key1_irq_handler, NULL );
- if( MicoGpioInputGet( (mico_gpio_t)USER_KEY1 ) == 0){
- user_key1_long_pressed_callback();
- }
- mico_stop_timer(&_user_key1_timer);
- }
- static void _user_key2_irq_handler( void* arg )
- {
- (void)(arg);
- int interval = -1;
-
- if ( MicoGpioInputGet( (mico_gpio_t)USER_KEY2 ) == 0 ) {
- //keys_log("_user_key2_irq_handler1");
- _default_key2_start_time = mico_get_time()+1;
- mico_start_timer(&_user_key2_timer);
- MicoGpioEnableIRQ( (mico_gpio_t)USER_KEY2, IRQ_TRIGGER_RISING_EDGE, _user_key2_irq_handler, NULL );
- }
- else {
- //keys_log("_user_key2_irq_handler2");
- interval = mico_get_time() + 1 - _default_key2_start_time;
- if ( (_default_key2_start_time != 0) && interval > 50 && interval < user_key2_long_press_timeout){
- /* button clicked once */
- user_key2_clicked_callback();
- MicoGpioEnableIRQ( (mico_gpio_t)USER_KEY2, IRQ_TRIGGER_FALLING_EDGE, _user_key2_irq_handler, NULL );
- }
- mico_stop_timer(&_user_key2_timer);
- _default_key2_start_time = 0;
- }
- }
- static void _user_key2_timeout_handler( void* arg )
- {
- (void)(arg);
- _default_key2_start_time = 0;
- MicoGpioEnableIRQ( (mico_gpio_t)USER_KEY2, IRQ_TRIGGER_FALLING_EDGE, _user_key2_irq_handler, NULL );
- if( MicoGpioInputGet( (mico_gpio_t)USER_KEY2 ) == 0){
- user_key2_long_pressed_callback();
- }
- mico_stop_timer(&_user_key2_timer);
- }
复制代码
最后,定义了4个用户接口函数,即2个按键的长按事件和单击事件的接口,由于是用weak来修改该函数(接口),故用户可重写该4个函数,实现自己的功能,默认什么也不做。
- WEAK void user_key1_clicked_callback(void)
- {
- return;
- }
- // Key1 long pressed callback
- WEAK void user_key1_long_pressed_callback(void)
- {
- return;
- }
- // Key2 clicked callback: next test module in test mode
- WEAK void user_key2_clicked_callback(void)
- {
- return;
- }
- // Key2 long pressed callback(use for enter MFG MODE when reset)
- WEAK void user_key2_long_pressed_callback(void)
- {
- return;
- }
复制代码
四、测试程序:
1 指定头文件
由于在IAR开发环境中,SDK_MiCOKit_v2.3.0.2已经指定了头文件目录 ,如下图所示,
故在测试文件中,指定头文件的方法如下:
2 编写测试程序
- #define sensor_log(M, ...) custom_log("Sensor", M, ##__VA_ARGS__) //在helloworld文件中,重新定义串口测试函数
- void user_key1_clicked_callback(void)//点击key1,SYS_LED反转三次
- {
- MicoGpioOutputTrigger( MICO_SYS_LED );
- mico_thread_sleep(1);
- MicoGpioOutputTrigger( MICO_SYS_LED );
- mico_thread_sleep(1);
- MicoGpioOutputTrigger( MICO_SYS_LED );
- mico_thread_sleep(1);
- sensor_log("key1_clicked_callback");
- }
- // Key1 long pressed callback
- void user_key1_long_pressed_callback(void)//长按key1,SYS_LED反转一次
- {
- MicoGpioOutputTrigger( MICO_SYS_LED );
- mico_thread_sleep(1);
- sensor_log("key1_long_pressed_callback");
- return;
- }
- // Key2 clicked callback
- void user_key2_clicked_callback(void)//点击key2,RF_LED反转三次
- {
- MicoGpioOutputTrigger( MICO_RF_LED );
- mico_thread_sleep(1);
- MicoGpioOutputTrigger( MICO_RF_LED );
- mico_thread_sleep(1);
- MicoGpioOutputTrigger( MICO_RF_LED );
- mico_thread_sleep(1);
- sensor_log("key2_clicked_callback");
- return;
- }
- // Key2 long pressed callback
- void user_key2_long_pressed_callback(void)//长按key2,RF_LED反转一次
- {
- MicoGpioOutputTrigger( MICO_RF_LED );
- mico_thread_sleep(1);
- sensor_log("key2_long_pressed_callback");
- return;
- }
- void TestKey(void)//由application_start函数调用
- {
- //Led已经Bootloader中初始化,故无需要再初始化
- user_key1_init();
- user_key2_init();
- while(1);
- }
复制代码
3由于在micoket_ext_mfg.c文件中,定义了user_key1_clicked_callback和user_key2_clicked_callback,故需要注释掉这两个函数,才能正常编译过去。
五、测试结果:
开板板效果:
串口效果:
测试不正常:
刚开始可以正常响应几次,但多次后,出错死机的现像,其中的一次测试结果如:
0
|
|
|
|