>[success] **技术支持说明:**
>**1**.一般以自主学习为主
> **2**.可到官方问答社区中提问:[**去提问**](https://bbs.csdn.net/forums/nb-iot)
> **3**.工程师**会尽快**解答社区问题,但他们是一线开发,【**难以保证**】解答时效,解答辛苦,感谢理解!
<br/>
上节课讲解了如何创建日志记录、LED控制、通过串口发送数据和显示器显示信息等任务,这些任务均属于输出型任务。本节课将以按键输入为例讲解如何创建输入型任务。
<br/>
打开节课配套的工程,如图所示。
![](https://img.kancloud.cn/45/15/451566ad20cca542e008b62b5d9410ea_346x726.png =300x)
<br/>
## **svc_button 服务**
svc\_button 服务对按键进行抽象,为任务(Task)提供按键次数计算服务。svc_button.c代码如下:
```
#include "svc_button.h"
#include "hal_button.h"
//记录按键次数计数器
static int svcButtonClickTimesCounter = 0;
static void svcButtonOnClick(void);
/*
*按键初始化
*/
void svcButtonInit()
{
/*向HAL设置按键回调函数,
前面的课程曾经讲解过,需要给按键传入一个回调函数*/
halButtonSetCallback(svcButtonOnClick);
}
/*
*返回按键次数
*/
int svcButtonClickTimes()
{
return svcButtonClickTimesCounter;
}
/*
*清0按键次数
*/
void svcButtonClickTimesClear()
{
svcButtonClickTimesCounter = 0;
}
/*
*按键回调函数,当按键被按下时执行此函数
*/
void svcButtonOnClick()
{
//按键次数+1
svcButtonClickTimesCounter++;
}
```
<br/>
## **输入型任务task_input**
输入型任务task\_input的主要工作内容是处理按键输入、接收串口数据等,task\_input.c代码如下:
```
#include "task_input.h"
#include "svc_button.h"
#include "svc_log.h"
#include "svc_task.h"
static void taskInputRunner(uint8_t, void *);
void taskInputInit()
{
/*每隔400毫秒执行1次taskInputRunner*/
svcTaskAdd(400, 1, taskInputRunner, 0);
}
/*
*回调函数,定义此任务的具体工作内容
*/
void taskInputRunner(uint8_t id, void *args)
{
//读取按键次数
int times = svcButtonClickTimes();
//清0按键次数
svcButtonClickTimesClear();
if (times == 1) //如果400毫秒内的按键次数=1
svcLogWrite((uint8_t *)"TASK[INPUT] single click\n");
else if (times == 2) //如果400毫秒内的按键次数=2
svcLogWrite((uint8_t *)"TASK[INPUT] double click\n");
/*
通常,如果在400毫秒内按了按键两下,表示这是双击;按了1下,表示这是单击
*/
}
```
<br/>
## **编写主函数**
打开main.c文件,代码如下:
```
#include "main.h"
#include "task_input.h"
#include "task_lcd.h"
#include "task_uart.h"
#include "task_led.h"
#include "task_test.h"
#include "svc_button.h"
#include "svc_plugins.h"
#include "svc_log.h"
#include "svc_task.h"
#include "hal_button.h"
#include "hal_oled12864.h"
#include "hal_led.h"
#include "hal_uart.h"
#include "hal_system.h"
static void halInit(void);
static void svcInit(void);
static void taskInit(void);
int main(void)
{
halInit();
svcInit();
taskInit();
//每隔1毫秒查看有没有任务需要执行
while (1) {
halSystemDelayUs(1000);
svcTaskPoll(1);
}
}
/* HAL */
void halInit()
{
halSystemInit();
halUartInit(115200);
halLedInit();
halOLED12864Init();
halButtonInit(0);
}
/* Services */
void svcInit()
{
svcTaskInit();
svcLogInit();
svcPluginsInit();
svcButtonInit();
}
/* Tasks */
void taskInit()
{
taskTestInit();
taskLedInit();
taskLcdInit();
taskUartInit();
taskInputInit();//输入型任务初始化
}
```
<br/>
## **代码测试**
* 编译链接工程代码,把生成的Hex文件烧录到开发板中。
* 把STM32开发板的第1、2、3和4打到右边,第5和6位打到左边,如图所示。
![](https://img.kancloud.cn/58/9a/589a66f16f8ca111d36b54fac452805c_1076x1045.png =250x)
###
* 使用USB线连接开发板到电脑,然后打开串口助手并做好相关配置,先后单击和双击PA0按钮,可以看到如下提示。
![](https://img.kancloud.cn/cf/c4/cfc4873f0bb07a378678c8155517502e_1022x747.png =500x)
<br/>
<br/>
## **商务合作**
如有以下需求,可扫码添加管理员好友,注明“**商务合作**”
* 项目定制开发,技术范围:**NB-IoT**、**CATn(4G)**、**WiFi**、**ZigBee**、**BLE Mesh**以及**STM32**、**嵌入式Linux**等;
* 入驻平台,成为讲师;
* 接项目赚外快;
* 善学坊官网:[www.sxf-iot.com](https://www.sxf-iot.com/)
![](https://img.kancloud.cn/b7/5a/b75ac8c3da945f20568771f5935c388f_430x430.png =150x)
(非商务合作**勿扰**,此处**非**技术支持)
- 课程简介
- 配套资源下载
- 配套开发套件简介
- 简介
- 硬件组成 & 技术参数
- STM32 Pro 主板 原理图 & PCB图
- STM32 Std 主板 原理图 & PCB图
- 板载设备使用说明
- STM32开发指南
- 1. 搭建开发环境
- 1.1 Keil MDK简介与安装
- 1.2 STM32 Pack 简介与安装
- 1.3 CH34x 驱动简介与安装
- 1.4 ISP 串口下载工具
- 1.5 串口调试工具
- 2. STM32 开发基础
- 2.1 新建工程
- 2.2 实现第1个程序
- 2.3 Hex 文件烧录详解
- 3. 移植官方标准工程模板
- 4. GPIO实验:LED
- 5. 系统延时应用
- 6. GPIO实验:按键
- 7. GPIO中断实验——按键触发实验
- 8. 使用定时器TIM3
- 9. 串口通信实验
- 10. ADC 实验
- 11. OLED显示器实验
- 12. SDK 设计思想
- 13. SDK 架构解析
- 14. 多任务应用实验
- 15. 输入型任务:按键输入实验
- 16. 输入型任务:串口接收实验
- 17. 高精度温湿度传感器实验
- 进阶课程