RT thread tutorial series - based on RT studio

Posted by loony383 on Tue, 08 Mar 2022 10:21:42 +0100

RT thread entry Series 2 - key control RGB

The main contents of this section are as follows:
1. Using button package
2. Key control creation thread
3. Key control delete thread

1. Using button package
The software package greatly improves the development efficiency, which is also the advantage of RTOS. Therefore, I began to use the software package in the second article. After that, almost every example will use the software package. It can also be directly applied in practical projects.
1) Configuration and selection of software package
This is very simple. Just click add, then search the element button, and then save it.

2) Use of software packages
The use of the software package is also very simple, but beginners may encounter some problems. The general file structure is as follows:

The inc folder is the header file contained in the. src is the concrete implementation of the button function. You can check readme with a simple description MD file, or directly click the root directory of the package folderThere are operation instances. We can directly copy the instance to the main function to experience the key operation.

/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2021-03-12     RT-Thread    first version
 */

#include <rtthread.h>
#include <rtdevice.h>
#include "drv_common.h"
#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
#include "ulog.h"
#include "agile_button.h"
#define LED_PIN  GET_PIN(E,7)

#define PIN_LED_R       GET_PIN(E, 7)
#define PIN_LED_B       GET_PIN(E, 9)
#define PIN_LED_G       GET_PIN(E, 8)

#define KEY0_PIN       GET_PIN(D, 10)

static agile_btn_t *key0 = RT_NULL;
static void key_create(void);
int sys_clock_information(void)
{
    LOG_D("System Clock information");
    LOG_D("SYSCLK_Frequency = %d", HAL_RCC_GetSysClockFreq());
    LOG_D("HCLK_Frequency   = %d", HAL_RCC_GetHCLKFreq());
    LOG_D("PCLK1_Frequency  = %d", HAL_RCC_GetPCLK1Freq());
    LOG_D("PCLK2_Frequency  = %d", HAL_RCC_GetPCLK2Freq());

    return RT_EOK;
}

int main(void)
{
    int count = 1;
    rt_pin_mode(LED_PIN,PIN_MODE_OUTPUT);
    rt_pin_mode(PIN_LED_R,PIN_MODE_OUTPUT);
    rt_pin_mode(PIN_LED_B,PIN_MODE_OUTPUT);
    rt_pin_mode(PIN_LED_G,PIN_MODE_OUTPUT);

    rt_pin_write(PIN_LED_R, PIN_HIGH);
    rt_pin_write(PIN_LED_B, PIN_HIGH);
    rt_pin_write(PIN_LED_G, PIN_HIGH);
    key_create();
    sys_clock_information();
    while (count++)
    {

       // LOG_D("LED run times is %d.",count);
        rt_pin_write(LED_PIN, PIN_HIGH);
         rt_thread_mdelay(500);
        rt_pin_write(LED_PIN, PIN_LOW);
        rt_thread_mdelay(500);
    }

    return RT_EOK;
}
static void btn_click_event_cb(agile_btn_t *btn)
{
    //rt_kprintf("light LED-BLUE !");
    rt_pin_write(PIN_LED_B, PIN_LOW);
    rt_thread_mdelay(100);
    rt_pin_write(PIN_LED_B, PIN_HIGH);
    rt_kprintf("[button click event] pin:%d   repeat:%d, hold_time:%d\r\n", btn->pin, btn->repeat_cnt, btn->hold_time);
}

static void btn_hold_event_cb(agile_btn_t *btn)
{
    //rt_pin_write(PIN_LED_B, PIN_HIGH);
    rt_kprintf("[button hold event] pin:%d   hold_time:%d\r\n", btn->pin, btn->hold_time);
}
static void key_create(void)
{


    if(key0 == RT_NULL)
    {
        key0 = agile_btn_create(KEY0_PIN, PIN_LOW, PIN_MODE_INPUT_PULLUP);
        agile_btn_set_event_cb(key0, BTN_CLICK_EVENT, btn_click_event_cb);
        agile_btn_set_event_cb(key0, BTN_HOLD_EVENT, btn_hold_event_cb);
        agile_btn_start(key0);
    }


}

The pin of RGB lamp and key 0 are initialized. Press the key and the blue light will light up. The use of software package is to directly copy the operation on the routine. Very convenient. If you want to write your own key driver, it still takes some time. Using software packages is still more efficient.
2. Key control creation thread

Key control is actually more complex. The key itself has a variety of signals, such as falling edge, rising edge, long press and short press. At least these four states. In addition, there are operations in the callback function of the key. Generally, the semaphore is released to transmit the key information.

Try to create another thread in one thread. After the test, the hardware error is found and cannot be realized. The specific reason is not clear. I didn't find it. I'll answer later when I have a better understanding of the system. I still use some general methods to release semaphores to create another thread.

enum agile_btn_state
{
    BTN_STATE_NONE_PRESS = 0,
    BTN_STATE_CHECK_PRESS,
    BTN_STATE_PRESS_DOWN, //Press
    BTN_STATE_PRESS_HOLD, //Long press
    BTN_STATE_PRESS_UP, // Bounce
};

From the above, you can see the general key status of the software package, which is divided into press, pop-up, long press and no press.
The operation of the keys is h file, you can operate according to the following functions.

agile_btn_t *agile_btn_create(rt_base_t pin, rt_base_t active_logic, rt_base_t pin_mode);
// Delete key object
int agile_btn_delete(agile_btn_t *btn);
// Start button
int agile_btn_start(agile_btn_t *btn);
// Stop button
int agile_btn_stop(agile_btn_t *btn);
// Set the key debounce time
int agile_btn_set_elimination_time(agile_btn_t *btn, uint8_t elimination_time);
// BTN after setting key is pressed_ HOLD_ The period of the event callback function
int agile_btn_set_hold_cycle_time(agile_btn_t *btn, uint32_t hold_cycle_time);
// Set key event callback function
int agile_btn_set_event_cb(agile_btn_t *btn, enum agile_btn_event event, void (*event_cb)(agile_btn_t *btn));

About semaphore creation: