本帖最后由 seighbang_842344017 于 2020-3-24 14:12 编辑

前面我们学习了编写hello world,在SDK的程序框架中,基本的入口是在/application/proc_main.c 文件,里面的函数void user_entry_after_ble_init(void){ }中进行编写。会发现这里面有两个调用:
1.user_task_init();
2.simple_peripheral_init();

实际上,这两个函数分别是两个模块,一个是user_task.c, 还要一个是在文件ble_simple_peripheral.c,体现在包含文件。
proc_main头文件.png



具体的函数定义分别在user_task.c文件和ble_simple_peripheral.c/.h中。

1.从操作的角度来理解例程的运行流程
开机—》显示logo——(按下k1)—— 》显示图片——(按下k1)——》播放音乐——(按下k1)——》显示传感器数值,可见, k1  按键进行了流程的主要切换的功能。另外k2可以在当前模式下来切换不同的工作状态。例如在显示图片模式下,可以通过按下k2来切换不同的图片。分别是logo,二维码还有屏幕的红,蓝,绿三种图片背景。

那么我们看到的lcd的显示的代码,以及按键的处理的代码的运行的机制,分别在simple_peripheral.c中,以及user_task.c中进行编写。

2.ble_simple_peripheral.h 中的App_Mode ——钥匙变量。这个变量是非常重要的,用于清晰的表明当前的工作模式,也就是k1 按键按下所改变的模式,对应的钥匙变量,相当于程序的指挥员角色。
  1. enum WORK_MODE
  2. {
  3.     PICTURE_UPDATE,
  4.     SENSOR_DATA,
  5.     SPEAKER_FROM_FLASH,
  6. <font color="#ff8c00">        CLOCK_SHOW,//Clock Mode</font>
  7.     MODE_MAX,
  8. };
  9. /*
  10. * GLOBAL VARIABLES (全局变量)
  11. */
  12. extern         uint8_t <font color="#ff0000">App_Mode;</font>
在代码中,按键处理部分,当按下k1,就依次把App_Mode 切换,循环切换为 PICTURE_UPDATE,    SENSOR_DATA,    SPEAKER_FROM_FLASH,几种模式。如果我们要开发一个停表模式,就可以在这里增加一项。

3.lcd_显示处理——根据App_Mode 来显示不同的信息。代码位于simple_peripheral.c中。在这个文件中的主体,是启动了一个1s的定时器例程timer_refresh_fun()来驱动lcd屏幕的刷新。每秒刷新1次。
timer_refresh.png
实际在编程中,如何应用定时器进行工作是一项很重要的任务。SDK的操作系统可以提供30个软件定时器。例子中的lcd刷新定时器的相关代码是。 timer_refresh_ define.png
定时器当定时触发时,需要执行的部分放在一个回调函数timer_refresh()函数中。
timer_refresh_ function.png
在这个函数中,根据 App_Mode的不同,lcd上刷新的信息是不同的。

4.按键处理代码。
按键的处理实际上是从底层操作系统粗发事件,涉及到操作系统的多任务运行,比较复杂。但是从应用的角度来看,其相关的部分主要是从user_task.c中来看。先看simple_peripheral_init()启动函数。
button_init.png
其具体实现在button.c,代码中是应用状态机,把按键封装为系统的事件,抛出给应用层。其消息传递应用到了操作系统的消息传递机制os_msg_post. button_msg_post.png
其中user_task_id是在 user_task.c代码中的user_task_init(){}初始化函数中,启动线程而得到的线程id.

应用层的处理代码在user_task.c代码中。
在被 proc_main调用的函数user_task_init(){}入口函数中,启动了一个线程。
os_create_user_task_func.png
线程的主题是函数user_task_func(){}这个部分主要的处理,实际上就是处理按键事件,实现整个程序的流程控制。参考MVC的思维,那么simple_peripheral.c中主要的是view的部分,就是处理用户界面前端的部分,而这里user_task_func()是处理按键部分,是属于控制的部分。
具体的按键处理参考代码的注释。

5. 敲黑板,如何增加一个停表的功能呢?

停表实际上是一个定时器,这个定时器由按键k2来控制启动和停止。整体上,需要在App_Mode 中新增一个模式,例如CLOCK_SHOW, 然后按k1切换的过程中,可以进入相应的模式。
相关的代码如下。
5.1 定义部分
clock_show.png

这是在simple_peripheral.h 文件中对App_Mode的修改。
在user_task.c文件中进行相关的定义。
clock_define.png
回调函数:在屏幕上显示当前的记录的时间。
clock_show_func.png
5.2显示界面部分。在simple_peripheral.c中,对于提示信息的修改。
timer_refresh_func_1.png
timer_refresh_func_2.png
5.3 控制部分。需要在user_task.c文件中进行编写。
定时器的初始化代码。
clock_init.png
定时器的启动和停止,需要在user_task_func()的按键处理程序中进行编写。
clock_button_1.png
clock_button_2.png

6测试结果。
这是运行时视频截图。
测试图片.png