#开发板漂流计划#小车控制由简入繁之按键控制 原创 精华

Soon_L
发布于 2021-10-2 09:58
浏览
5收藏
  • 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

# CONFIG_PWM_SUPPORT is not set

改为

CONFIG_PWM_SUPPORT=y
  • 3.2 电机的控制代码
    电机控制代码是从润和Gitee小车样例代码car_control.c和car_control.h 修改而来。
    主要修改如下
    将car_control.c中
#include <app_demo_robot_car.h>

extern hi_u32  g_car_speed;

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

hi_u16  g_car_speed;

在car_control.h中添加以下define

#define     MAX_SPEED                         (100)
#define     MIN_SPEED                         (30000)
#define     PWM_DUTY_LEFT_RIGHT               (5000)
#define     PWM_DUTY_FORWARD_BACK             (10000)

小车前进

/*car go forward */
hi_void car_go_forward(hi_void)
{
    correct_car_speed();
    gpio_control(HI_IO_NAME_GPIO_0, HI_GPIO_IDX_0, HI_GPIO_DIR_OUT, HI_GPIO_VALUE1, HI_IO_FUNC_GPIO_0_GPIO);
    pwm_control(HI_IO_NAME_GPIO_1,HI_IO_FUNC_GPIO_1_PWM4_OUT,HI_PWM_PORT_PWM4, g_car_speed);
    gpio_control(HI_IO_NAME_GPIO_9, HI_GPIO_IDX_9, HI_GPIO_DIR_OUT, HI_GPIO_VALUE1, HI_IO_FUNC_GPIO_9_GPIO);
    pwm_control(HI_IO_NAME_GPIO_10,HI_IO_FUNC_GPIO_10_PWM1_OUT,HI_PWM_PORT_PWM1, g_car_speed);
}

小车后退

/*car go back */
hi_void car_go_back(hi_void)
{
    correct_car_speed();
    pwm_control(HI_IO_NAME_GPIO_0,HI_IO_FUNC_GPIO_0_PWM3_OUT,HI_PWM_PORT_PWM3, g_car_speed); 
    gpio_control(HI_IO_NAME_GPIO_1, HI_GPIO_IDX_1, HI_GPIO_DIR_OUT, HI_GPIO_VALUE1, HI_IO_FUNC_GPIO_1_GPIO);
    pwm_control(HI_IO_NAME_GPIO_9,HI_IO_FUNC_GPIO_9_PWM0_OUT,HI_PWM_PORT_PWM0, g_car_speed); 
    gpio_control(HI_IO_NAME_GPIO_10, HI_GPIO_IDX_10, HI_GPIO_DIR_OUT, HI_GPIO_VALUE1, HI_IO_FUNC_GPIO_10_GPIO);
}

小车左转

/*car turn left */
hi_void car_turn_left(hi_void)
{
    correct_car_speed();
    pwm_control(HI_IO_NAME_GPIO_0,HI_IO_FUNC_GPIO_0_PWM3_OUT,HI_PWM_PORT_PWM3, PWM_DUTY_LEFT_RIGHT); 
    gpio_control(HI_IO_NAME_GPIO_1, HI_GPIO_IDX_1, HI_GPIO_DIR_OUT, HI_GPIO_VALUE0, HI_IO_FUNC_GPIO_1_GPIO);
    gpio_control(HI_IO_NAME_GPIO_9, HI_GPIO_IDX_9, HI_GPIO_DIR_OUT, HI_GPIO_VALUE1, HI_IO_FUNC_GPIO_9_GPIO);
    pwm_control(HI_IO_NAME_GPIO_10,HI_IO_FUNC_GPIO_10_PWM1_OUT,HI_PWM_PORT_PWM1, PWM_DUTY_LEFT_RIGHT);
}

小车右转

/*car turn right */
hi_void car_turn_right(hi_void)
{
    correct_car_speed();
    gpio_control(HI_IO_NAME_GPIO_0, HI_GPIO_IDX_0, HI_GPIO_DIR_OUT, HI_GPIO_VALUE1, HI_IO_FUNC_GPIO_0_GPIO);
    pwm_control(HI_IO_NAME_GPIO_1,HI_IO_FUNC_GPIO_1_PWM4_OUT,HI_PWM_PORT_PWM4, PWM_DUTY_LEFT_RIGHT);
    pwm_control(HI_IO_NAME_GPIO_9,HI_IO_FUNC_GPIO_9_PWM0_OUT,HI_PWM_PORT_PWM0,PWM_DUTY_LEFT_RIGHT);
    gpio_control(HI_IO_NAME_GPIO_10, HI_GPIO_IDX_10, HI_GPIO_DIR_OUT, HI_GPIO_VALUE0, HI_IO_FUNC_GPIO_10_GPIO);
}

小车停止

/*car stop */
hi_void car_stop(hi_void)
{
    correct_car_speed();
    pwm_control(HI_IO_NAME_GPIO_0,HI_IO_FUNC_GPIO_0_PWM3_OUT,HI_PWM_PORT_PWM3, PWM_DUTY_STOP); 
    gpio_control(HI_IO_NAME_GPIO_1, HI_GPIO_IDX_1, HI_GPIO_DIR_OUT, HI_GPIO_VALUE0, HI_IO_FUNC_GPIO_1_GPIO);
    pwm_control(HI_IO_NAME_GPIO_9,HI_IO_FUNC_GPIO_9_PWM0_OUT,HI_PWM_PORT_PWM0, PWM_DUTY_STOP);
    gpio_control(HI_IO_NAME_GPIO_10, HI_GPIO_IDX_10, HI_GPIO_DIR_OUT, HI_GPIO_VALUE0, HI_IO_FUNC_GPIO_10_GPIO);
}
  • 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中
/*
  Description: 
      Key event callback function pointer type.

  Parameter:
      id --  key id
      event  -- key event type

  Return Value:
      0     -- Success
      other -- Failure
*/
typedef void (*PKeyEventCallback)(KEY_ID_TYPE keyid, KEY_EVENT_TYPE event);

/*
  Description: 
       initialize key event process context.

  Parameter:
      None

  Return Value:
      0     -- Success
      other -- Failure
*/
int KeyEvent_Init(void);

/*
  Description: 
      To register callback functions for a GPIO key.

  Parameter:
      name     -- target GPIO port name for a phisical key
      callback -- callback function for key event
      event    -- the target key event to trigger callback

  Return Value:
      0     -- Success
      other -- Failure
*/
int KeyEvent_Connect(const char* name, PKeyEventCallback callback, unsigned int event);

/*
  Description: 
      To unregister callback functions for a GPIO key.

  Parameter:
      name -- target GPIO port name for a phisical key

  Return Value:
      None
*/
void KeyEvent_Disconnect(const char* name);

/*
  Description: 
      To close key event process context.

  Parameter:
      None

  Return Value:
      None
*/
void KeyEvent_Close(void);
  • 4.2 使用范例
    先初始化按键事件处理、并注册回调函数和所需的事件
    ret += KeyEvent_Init(); // 初始化按键事件处理上下文
    /* 设置GPIO_5按键的回调函数,同时需要响应按下,释放以及长按三个事件 */
    /* 按键触发顺序: Pressed -> LongPressed(optional) -> Released */
    ret += KeyEvent_Connect("GPIO_5", KeyEvent_Callback, KEY_EVENT_PRESSED | KEY_EVENT_LONG_PRESSED | KEY_EVENT_RELEESED);

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

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

接着实现KeyEvent_Callback回调

static void KeyEvent_Callback(KEY_ID_TYPE keyid, KEY_EVENT_TYPE event)
{
    printf("[CarDemo] KeyEvent_Callback() : keyid=%d event= %d\n", (int)keyid, (int)event);

    int ret = -1;
    switch (keyid)
    {
    case KEY_ID_USER:
         printf("[CarDemo] KEY_ID_USER\n");
        if( event == KEY_EVENT_PRESSED ) { /*  按下事件处理代码 */ 
            car_stop();
        }
        if( event == KEY_EVENT_LONG_PRESSED ) { /*  长按事件处理代码 */

        }
        if( event == KEY_EVENT_RELEESED ) { /*  松开事件处理代码 */ 

        }
        break;
    case KEY_ID_S1:
         printf("[CarDemo] KEY_ID_S1\n");
        if( event == KEY_EVENT_PRESSED ){  /*  按下事件处理代码 */ 
            car_go_forward();
        }
        if( event == KEY_EVENT_LONG_PRESSED ) { /*  长按事件处理代码 */
            car_turn_left();
        }
        if( event == KEY_EVENT_RELEESED ){ /*  松开事件处理代码 */ 

        }
        break;
    case KEY_ID_S2:
         printf("[CarDemo] KEY_ID_S2\n");
        if( event == KEY_EVENT_PRESSED )      { /*  按下事件处理代码 */ 
            car_go_back();
        }
        if( event == KEY_EVENT_LONG_PRESSED ) { /*  长按事件处理代码 */ 
            car_turn_right();
        }
        if( event == KEY_EVENT_RELEESED ){ /*  松开事件处理代码 */ 

        }
        break;
    
    default:
        break;
    }

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

  • 5.1解压附件将car目录放到applications/sample/wifi-iot/app/下
    #开发板漂流计划#小车控制由简入繁之按键控制-鸿蒙开发者社区
  • 5.2修改applications/sample/wifi-iot/app/BUILD.gn
import("//build/lite/config/component/lite_component.gni")

lite_component("app") {
    features = [
        "car",
    ]
}

文中相关设备来源于51CTO 鸿蒙技术社区【开发板漂流计划】

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
car.zip 6.72K 25次下载
已于2021-10-2 17:05:50修改
6
收藏 5
回复
举报
回复
    相关推荐