ble开发-按键启动控制LED与简易蓝牙数据发送

发布时间 2023-05-26 15:50:28作者: foorun

小白初次接触ble开发,网上相关教程较为复杂混乱,因此在此系统讲解ble开发相关流程并记录本人开发过程,有何错误欢迎评论指正。

嵌入式学习第一步,点个灯先

嵌入式学习第二步,搞个按键

嵌入式学习第三步,按键点个灯

1.本工程所使用SDK为伦茨官方提供按键例程

伦茨17Hxx开发文档中ST17H66_SDK_3.1.1.2_key工程

2.本工程按键部分代码已基本实现,接下来阐述一下按键实现的具体流程

请首先参考其他文献对OSAL系统有初步了解,以方便进一步理解。首先是按键初始化,定义引脚状态并使能与注册中断。当按键按下后进入中断 user_key_handler

void userKey_Init(uint8 task_id)
{
    userKeyTaskID = task_id;
    hal_gpio_pin_init(P0, GPIO_OUTPUT);//P0为输出状态
        hal_gpio_pull_set(P0, PULL_DOWN);//下拉
hal_gpio_pin_init(P24, GPIO_OUTPUT);
//P24为LED hal_gpio_pull_set(P0, PULL_DOWN); hal_gpio_pin_init(PIN_TOUCH_KEY, IE);//P14为输入状态 hal_gpio_pull_set(PIN_TOUCH_KEY, STRONG_PULL_UP);//上拉 hal_gpioin_enable(PIN_TOUCH_KEY);//使能中断 hal_gpioin_register(PIN_TOUCH_KEY, NULL,user_key_handler);//注册中断处理#endif }

中断 user_key_handler,其主要功能为当触发中断是开启按键任务中的按键扫描事件

void __ATTR_SECTION_SRAM__  __attribute__((used))  user_key_handler(gpio_pin_e pin,gpio_polarity_e type)
{
    if(pin == PIN_TOUCH_KEY) {
    hal_gpioin_register(PIN_TOUCH_KEY, NULL, NULL);
        hal_gpioin_register(PIN_TOUCH_KEY1, NULL, NULL);
    key_time_timeout = KEY_TIMEOUT_MAX;
    osal_start_timerEx(userKeyTaskID, USER_KEY_SCAN_EVT, KEY_SCAN_INTERVAL);  //启动KEY_SCAN_INTERVAL事件

KEY_SCAN_INTERVAL
} }

按键扫描事件,其主要功能为调用key_scan()函数

        if(events & USER_KEY_SCAN_EVT)
        {
                key_scan();
                return (events ^USER_KEY_SCAN_EVT);
        }

key_scan()函数主要功能即为按键扫描,包括长按、短按、连续按。当任务没超时即!key_time_timeout 时继续执行扫描事件,超时后便将引脚重新赋予中断(超时即长时间未按下按键)并且不在执行本任务。当按键按下后我们可以添加按键触发动作执行相关程序。其内容在key_do()函数中。

void key_scan(
{
    static uint8 key_last_val;
    static uint32 key_release_tick,key_press_tick;
    static uint32 key_short_cnt,key_long_time_cnt;
    uint8 key_cur_val = get_cur_key(P14,P0);
      //LOG("P0:%d  P14:%d",hal_gpio_read(P0),hal_gpio_read(P14));
    if(key_cur_val != key_last_val) {
        if(key_cur_val) {    //按下
                        key_time_timeout = KEY_TIMEOUT_MAX;
            key_press_tick = rtc_get_counter();
            key_long_time_cnt = 0;
                      LOG("Key_Down");
                      key_do(0,1);
        }
        else {//松开
            key_release_tick = rtc_get_counter();
            uint32 key_tick_diff = key_release_tick > key_press_tick? (key_release_tick-key_press_tick):0;
                      
                      LOG("Key_press");
                      key_do(0,2);
            if(key_tick_diff && (key_tick_diff< RTC_nMs(350)&& (key_tick_diff > RTC_nMs(20)))) {
                key_short_cnt++;//连按次数
                            
                                if( key_short_cnt >= 2) {
                                    key_do(0,3);
                                }
                                static int last_tick;
                                
               // LOG("\n %8d  tick = %8d  dif= %8d",key_short_cnt, (key_release_tick*1000/32768), (key_release_tick-last_tick)*1000/32768);            
                                last_tick = key_release_tick;
            }
        }
        key_last_val = key_cur_val;
    }
    else {
        if(key_cur_val) {//长按
            key_time_timeout = KEY_TIMEOUT_MAX;
            if(key_long_time_cnt < 254) {
                key_long_time_cnt++;
//                LOG("S");
                if(key_long_time_cnt == (2200/50)) {

                }
                                if(key_long_time_cnt == (6200/50)) {                                    
                                }
            }
        }
        else {
        }
    }
    if(key_time_timeout) {
        key_time_timeout--;
                if(key_time_timeout == (KEY_TIMEOUT_MAX-6))
                {

                }                
        if(key_time_timeout ==0) {
            key_short_cnt = 0;
            hal_gpioin_register(PIN_TOUCH_KEY,  NULL,user_key_handler);
        }
                
        osal_start_timerEx(userKeyTaskID, USER_KEY_SCAN_EVT, KEY_SCAN_INTERVAL);
    }
}

key_do(),本函数即为按键动作,所需按键功能可在本函数中进行编写。其中P24引脚为LED引脚,可通过其实现对LED的控制。sbpSerialAppSendNoti(a,3)为蓝牙发送,通过次函数蓝牙可发送长度为3的数据123到安卓端。对本函数的讲解留到之后,到此按键点灯功能实现。

void key_do(uint8 key_val,uint8 key_state)//按键执行事件
{
    if(key_val==0&&key_state==1)
    {
        hal_gpio_pull_set(P24,STRONG_PULL_UP);//点亮LED
    }
    if(key_val==0&&key_state==2)
    {
        hal_gpio_pull_set(P24,PULL_DOWN);//熄灭LED
    }
    if(key_val==0&&key_state==3)
    {
        if( get_ble_state()==GAPROLE_CONNECTED)
        {
            uint8 a[3]={1,2,3};
            LOG("ble_send:%s",a);
            sbpSerialAppSendNoti(a,3);
        }            
    }
}

 串口接收到的数据如下。

 蓝牙接收到的数据如下