社区编辑申请
注册/登录
开发板漂流计划之小车控制由简入繁之按键控制
开发
实现最简单的按键控制小车前进、后退、左转、右转、停止的Demo,代码在openharmonny1.10 和openharmony3.00 测试可以正常工作。

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

1.简介

实现最简单的按键控制小车前进、后退、左转、右转、停止的Demo,代码在openharmonny1.10 和openharmony3.00 测试可以正常工作。

2. 功能介绍

1).短按 OLED 扩展板S1按键 - 前进

2).长按 OLED 扩展板S1按键 - 左转

3).短按 OLED 扩展板S2按键 - 后退

4).长按 OLED 扩展板S2按键 - 右转

5).短按核心板User按键 - 停止

3.电机的控制代码

3.1 电机的控制需要用到PWM,所以需要先将PWM 功能开启,开启方式如下

device/hisilicon/hispark_pegasus/sdk_liteos/build/config/usr_config.mk

  1. # CONFIG_PWM_SUPPORT is not set 

 改为

  1. CONFIG_PWM_SUPPORT=y 

 3.2 电机的控制代码

电机控制代码是从润和Gitee小车样例代码car_control.c和car_control.h 修改而来。

主要修改如下

将car_control.c中

  1. #include <app_demo_robot_car.h> 
  2.  
  3. extern hi_u32  g_car_speed; 

 移除app_demo_robot_car.h和extern ,改为如下

  1. hi_u16  g_car_speed; 

 在car_control.h中添加以下define

  1. #define     MAX_SPEED                         (100) 
  2. #define     MIN_SPEED                         (30000) 
  3. #define     PWM_DUTY_LEFT_RIGHT               (5000) 
  4. #define     PWM_DUTY_FORWARD_BACK             (10000) 

 小车前进

  1. /*car go forward */ 
  2. hi_void car_go_forward(hi_void) 
  3.     correct_car_speed(); 
  4.     gpio_control(HI_IO_NAME_GPIO_0, HI_GPIO_IDX_0, HI_GPIO_DIR_OUT, HI_GPIO_VALUE1, HI_IO_FUNC_GPIO_0_GPIO); 
  5.     pwm_control(HI_IO_NAME_GPIO_1,HI_IO_FUNC_GPIO_1_PWM4_OUT,HI_PWM_PORT_PWM4, g_car_speed); 
  6.     gpio_control(HI_IO_NAME_GPIO_9, HI_GPIO_IDX_9, HI_GPIO_DIR_OUT, HI_GPIO_VALUE1, HI_IO_FUNC_GPIO_9_GPIO); 
  7.     pwm_control(HI_IO_NAME_GPIO_10,HI_IO_FUNC_GPIO_10_PWM1_OUT,HI_PWM_PORT_PWM1, g_car_speed); 

 小车后退

  1. /*car go back */ 
  2. hi_void car_go_back(hi_void) 
  3.     correct_car_speed(); 
  4.     pwm_control(HI_IO_NAME_GPIO_0,HI_IO_FUNC_GPIO_0_PWM3_OUT,HI_PWM_PORT_PWM3, g_car_speed);  
  5.     gpio_control(HI_IO_NAME_GPIO_1, HI_GPIO_IDX_1, HI_GPIO_DIR_OUT, HI_GPIO_VALUE1, HI_IO_FUNC_GPIO_1_GPIO); 
  6.     pwm_control(HI_IO_NAME_GPIO_9,HI_IO_FUNC_GPIO_9_PWM0_OUT,HI_PWM_PORT_PWM0, g_car_speed);  
  7.     gpio_control(HI_IO_NAME_GPIO_10, HI_GPIO_IDX_10, HI_GPIO_DIR_OUT, HI_GPIO_VALUE1, HI_IO_FUNC_GPIO_10_GPIO); 

 小车左转

  1. /*car turn left */ 
  2. hi_void car_turn_left(hi_void) 
  3.     correct_car_speed(); 
  4.     pwm_control(HI_IO_NAME_GPIO_0,HI_IO_FUNC_GPIO_0_PWM3_OUT,HI_PWM_PORT_PWM3, PWM_DUTY_LEFT_RIGHT);  
  5.     gpio_control(HI_IO_NAME_GPIO_1, HI_GPIO_IDX_1, HI_GPIO_DIR_OUT, HI_GPIO_VALUE0, HI_IO_FUNC_GPIO_1_GPIO); 
  6.     gpio_control(HI_IO_NAME_GPIO_9, HI_GPIO_IDX_9, HI_GPIO_DIR_OUT, HI_GPIO_VALUE1, HI_IO_FUNC_GPIO_9_GPIO); 
  7.     pwm_control(HI_IO_NAME_GPIO_10,HI_IO_FUNC_GPIO_10_PWM1_OUT,HI_PWM_PORT_PWM1, PWM_DUTY_LEFT_RIGHT); 

 小车右转

  1. /*car turn right */ 
  2. hi_void car_turn_right(hi_void) 
  3.     correct_car_speed(); 
  4.     gpio_control(HI_IO_NAME_GPIO_0, HI_GPIO_IDX_0, HI_GPIO_DIR_OUT, HI_GPIO_VALUE1, HI_IO_FUNC_GPIO_0_GPIO); 
  5.     pwm_control(HI_IO_NAME_GPIO_1,HI_IO_FUNC_GPIO_1_PWM4_OUT,HI_PWM_PORT_PWM4, PWM_DUTY_LEFT_RIGHT); 
  6.     pwm_control(HI_IO_NAME_GPIO_9,HI_IO_FUNC_GPIO_9_PWM0_OUT,HI_PWM_PORT_PWM0,PWM_DUTY_LEFT_RIGHT); 
  7.     gpio_control(HI_IO_NAME_GPIO_10, HI_GPIO_IDX_10, HI_GPIO_DIR_OUT, HI_GPIO_VALUE0, HI_IO_FUNC_GPIO_10_GPIO); 

 小车停止

  1. /*car stop */ 
  2. hi_void car_stop(hi_void) 
  3.     correct_car_speed(); 
  4.     pwm_control(HI_IO_NAME_GPIO_0,HI_IO_FUNC_GPIO_0_PWM3_OUT,HI_PWM_PORT_PWM3, PWM_DUTY_STOP);  
  5.     gpio_control(HI_IO_NAME_GPIO_1, HI_GPIO_IDX_1, HI_GPIO_DIR_OUT, HI_GPIO_VALUE0, HI_IO_FUNC_GPIO_1_GPIO); 
  6.     pwm_control(HI_IO_NAME_GPIO_9,HI_IO_FUNC_GPIO_9_PWM0_OUT,HI_PWM_PORT_PWM0, PWM_DUTY_STOP); 
  7.     gpio_control(HI_IO_NAME_GPIO_10, HI_GPIO_IDX_10, HI_GPIO_DIR_OUT, HI_GPIO_VALUE0, HI_IO_FUNC_GPIO_10_GPIO); 
  8.  

4. 按键长按短按功能能的实现

按键功能的实现唐佐林老师已经做了很深入的分享,我这边也是参考唐老师的分享来实现的,

附上唐老师的帖子链接:

实现按键“按下事件”和“释放事件”的通用框架(V0.0.1)

实现物理按键的“长按事件”(按键通用框架 V0.0.2)

实现S1,S2,User三个物理按键的独立事件-上(解决思路分析)

实现S1,S2,User三个物理按键的独立事件-下(DTButton-V0.0.3)

本案例中按键功能实现在KeyEvent.c和KeyEvent.h

4.1 主要函数介绍在KeyEvent.h中

  1. /* 
  2.   Description:  
  3.       Key event callback function pointer type. 
  4.  
  5.   Parameter: 
  6.       id --  key id 
  7.       event  -- key event type 
  8.  
  9.   Return Value: 
  10.       0     -- Success 
  11.       other -- Failure 
  12. */ 
  13. typedef void (*PKeyEventCallback)(KEY_ID_TYPE keyid, KEY_EVENT_TYPE event); 
  14.  
  15. /* 
  16.   Description:  
  17.        initialize key event process context. 
  18.  
  19.   Parameter: 
  20.       None 
  21.  
  22.   Return Value: 
  23.       0     -- Success 
  24.       other -- Failure 
  25. */ 
  26. int KeyEvent_Init(void); 
  27.  
  28. /* 
  29.   Description:  
  30.       To register callback functions for a GPIO key
  31.  
  32.   Parameter: 
  33.       name     -- target GPIO port name for a phisical key 
  34.       callback -- callback function for key event 
  35.       event    -- the target key event to trigger callback 
  36.  
  37.   Return Value: 
  38.       0     -- Success 
  39.       other -- Failure 
  40. */ 
  41. int KeyEvent_Connect(const charname, PKeyEventCallback callback, unsigned int event); 
  42.  
  43. /* 
  44.   Description:  
  45.       To unregister callback functions for a GPIO key
  46.  
  47.   Parameter: 
  48.       name -- target GPIO port name for a phisical key 
  49.  
  50.   Return Value: 
  51.       None 
  52. */ 
  53. void KeyEvent_Disconnect(const charname); 
  54.  
  55. /* 
  56.   Description:  
  57.       To close key event process context. 
  58.  
  59.   Parameter: 
  60.       None 
  61.  
  62.   Return Value: 
  63.       None 
  64. */ 
  65. void KeyEvent_Close(void); 

4.2 使用范例

先初始化按键事件处理、并注册回调函数和所需的事件

  1. ret += KeyEvent_Init(); // 初始化按键事件处理上下文 
  2.   /* 设置GPIO_5按键的回调函数,同时需要响应按下,释放以及长按三个事件 */ 
  3.   /* 按键触发顺序: Pressed -> LongPressed(optional) -> Released */ 
  4.   ret += KeyEvent_Connect("GPIO_5", KeyEvent_Callback, KEY_EVENT_PRESSED | KEY_EVENT_LONG_PRESSED | KEY_EVENT_RELEESED); 

如只需要按下的功能只需要注册KEY_EVENT_PRESSED

  1. ret += KeyEvent_Connect("GPIO_5", KeyEvent_Callback, KEY_EVENT_PRESSED); 

接着实现KeyEvent_Callback回调

  1. static void KeyEvent_Callback(KEY_ID_TYPE keyid, KEY_EVENT_TYPE event) 
  2.     printf("[CarDemo] KeyEvent_Callback() : keyid=%d event= %d\n", (int)keyid, (int)event); 
  3.  
  4.     int ret = -1; 
  5.     switch (keyid) 
  6.     { 
  7.     case KEY_ID_USER: 
  8.          printf("[CarDemo] KEY_ID_USER\n"); 
  9.         if( event == KEY_EVENT_PRESSED ) { /*  按下事件处理代码 */  
  10.             car_stop(); 
  11.         } 
  12.         if( event == KEY_EVENT_LONG_PRESSED ) { /*  长按事件处理代码 */ 
  13.  
  14.         } 
  15.         if( event == KEY_EVENT_RELEESED ) { /*  松开事件处理代码 */  
  16.  
  17.         } 
  18.         break; 
  19.     case KEY_ID_S1: 
  20.          printf("[CarDemo] KEY_ID_S1\n"); 
  21.         if( event == KEY_EVENT_PRESSED ){  /*  按下事件处理代码 */  
  22.             car_go_forward(); 
  23.         } 
  24.         if( event == KEY_EVENT_LONG_PRESSED ) { /*  长按事件处理代码 */ 
  25.             car_turn_left(); 
  26.         } 
  27.         if( event == KEY_EVENT_RELEESED ){ /*  松开事件处理代码 */  
  28.  
  29.         } 
  30.         break; 
  31.     case KEY_ID_S2: 
  32.          printf("[CarDemo] KEY_ID_S2\n"); 
  33.         if( event == KEY_EVENT_PRESSED )      { /*  按下事件处理代码 */  
  34.             car_go_back(); 
  35.         } 
  36.         if( event == KEY_EVENT_LONG_PRESSED ) { /*  长按事件处理代码 */  
  37.             car_turn_right(); 
  38.         } 
  39.         if( event == KEY_EVENT_RELEESED ){ /*  松开事件处理代码 */  
  40.  
  41.         } 
  42.         break; 
  43.      
  44.     default
  45.         break; 
  46.     } 
  47.  

5.附上完整的代码如附件car.zip

5.1解压附件将car目录放到applications/sample/wifi-iot/app/下

#开发板漂流计划#小车控制由简入繁之按键控制-鸿蒙HarmonyOS技术社区

5.2修改applications/sample/wifi-iot/app/BUILD.gn

  1. import("//build/lite/config/component/lite_component.gni"
  2.  
  3. lite_component("app") { 
  4.     features = [ 
  5.         "car"
  6.     ] 

文章相关附件可以点击下面的原文链接前往下载

https://harmonyos.51cto.com/resource/1286

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

 

责任编辑:jianghua 来源: 鸿蒙社区

同话题下的热门内容

Rust难懂?一文解读其“所有权”和“借用”概念太强了!Python 开发桌面小工具,让代码替我们干重复的工作!K8s需要替代品!你离完全理解 SQL 只差这十步分享六个 Vue3 开发必备的 VSCode 插件程序员如何寻找技术突破、体现技术价值?接口性能优化实战:从20s到500ms,三招搞定六七十岁程序员工资暴涨 就因为这门没啥人学的编程语言

编辑推荐

2017年9月编程语言排行榜:Java、C与C++三巨头还能统治排行榜多久?2017年最受欢迎的5个前端框架比较2017年11月编程语言排行榜:脚本语言怎么了?2017年3月编程语言排行榜:Swift首次进入前十最近租房有点烦!技术人如何用Python找到称心如意的“小窝”?
我收藏的内容
点赞
收藏

51CTO技术栈公众号