[MCU] 【中科蓝讯AB32VG1 RISC-V板“碰上”RTT测评】+LED与按键控制

xiyue521   2021-5-1 01:53 楼主

 

 

由原理图可以知道LED低电平亮,按键按下去低电平,配置按键上拉输入即可检测:

rt_pin_mode(S3, PIN_MODE_INPUT_PULLUP ); 图片2.png

图片1.png

 

 

1.先封装底层函数,rt_pin_get获取引脚id值

                              rt_pin_mode,rt_pin_write,rt_pin_read这三个是按键模式,读,写函数,直接把获取到的id值传进去就可以修改对应的引脚。

 

 

 



void RGB_Init(void){
    // 获得led成员
    LED_R = rt_pin_get("PE.1");
    LED_G = rt_pin_get("PE.4");
    LED_B = rt_pin_get("PA.2");
    // 设置引脚为输出方式
    rt_pin_mode(LED_R, PIN_MODE_OUTPUT);
    rt_pin_mode(LED_G, PIN_MODE_OUTPUT);
    rt_pin_mode(LED_B, PIN_MODE_OUTPUT);
}
// on=1:红灯亮,on=0:全灭
void RGB_Red(rt_bool_t on){
    if (on) {
        rt_pin_write(LED_R, PIN_LOW);
    }else {
        rt_pin_write(LED_R, PIN_HIGH);
    }
    rt_pin_write(LED_G, PIN_HIGH);
    rt_pin_write(LED_B, PIN_HIGH);
}

void RGB_Blue(rt_bool_t on){
    if (on) {
        rt_pin_write(LED_B, PIN_LOW);
    }else {
        rt_pin_write(LED_B, PIN_HIGH);
    }
    rt_pin_write(LED_G, PIN_HIGH);
    rt_pin_write(LED_R, PIN_HIGH);
}

void RGB_Green(rt_bool_t on){
    if (on) {
        rt_pin_write(LED_G, PIN_LOW);
    }else {
        rt_pin_write(LED_G, PIN_HIGH);
    }
    rt_pin_write(LED_R, PIN_HIGH);
    rt_pin_write(LED_B, PIN_HIGH);
}


void RGB_ALL(rt_bool_t on){
    if (on) {
        rt_pin_write(LED_G, PIN_LOW);
        rt_pin_write(LED_R, PIN_LOW);
        rt_pin_write(LED_B, PIN_LOW);
    }
    else
    {
        rt_pin_write(LED_G, PIN_HIGH);
        rt_pin_write(LED_R, PIN_HIGH);
        rt_pin_write(LED_B, PIN_HIGH);
    }

}


void Key_Init(void){
    S3= rt_pin_get("PF.0");
    S2 = rt_pin_get("PF.1");
    // 上拉输入
    rt_pin_mode(S2, PIN_MODE_INPUT_PULLUP );
    rt_pin_mode(S3, PIN_MODE_INPUT_PULLUP );
}

 

 

2.接下来创建一个led的任务,期间用到了全局变量mode,也可以用邮箱来传值。还有就是可以用INIT_APP_EXPORT()函数来直接对函数初始化,不用再去main调用他。



static void rgb_thread_entry(void* pdata)
{
    RGB_Init();
    while(1)
    {


        switch(mode)
       {

            case 0:
                RGB_ALL(0);
                rt_thread_mdelay(1000);
                RGB_ALL(1);
                rt_thread_mdelay(1000);
               break;
            case 1:

                rt_thread_mdelay(1000);
                RGB_Blue(1);
                rt_thread_mdelay(1000);
                RGB_Green(1);
                rt_thread_mdelay(1000);
                RGB_Red(1);
                break;

        }

    }
}


static int Thread_RGB(void){
    rt_thread_t thread = RT_NULL;
    thread = rt_thread_create("rgb", rgb_thread_entry, RT_NULL, 512, 9, 10);
    if(thread == RT_NULL)
    {
        rt_kprintf("Thread_GRB Init ERROR");
        return RT_ERROR;
    }
    rt_thread_startup(thread);
}

INIT_APP_EXPORT(Thread_RGB); // 线程自动初始化

 

3.创建按键任务,这里用到了轮询的方式检测按键,100ms检测一次,检测到对应按键修改mode来切换不同的led闪烁模式。

    两个任务都是用动态创建的,格式也差不多,所以用RTOS其实可以简化很多东西。特别是RTTHREAD还有控制台,LOG的一些功能,调试的时候比较方便,极力推荐!

 



static void key_thread_entry(void *parameter){
    Key_Init();
    RGB_Init();
    RGB_Red(1);
    while(1){
        if (rt_pin_read(S2)==PIN_LOW) mode=0;

        if (rt_pin_read(S3)==PIN_LOW) mode=1;

        rt_thread_mdelay(100);
    }
}

static int Key_Thread_Init(void){


    rt_thread_t thread = RT_NULL;
    thread = rt_thread_create("key_thread", key_thread_entry, RT_NULL, 512, 10, 10);
    if(thread == RT_NULL)
    {
        rt_kprintf("Thread_GRB Init ERROR");
        return RT_ERROR;
    }
    rt_thread_startup(thread);




}
INIT_APP_EXPORT(Key_Thread_Init);  // 初始化线程

 

4.main函数就是没1s打印一次mode,其他没有了。

#include <rtthread.h>
#include "board.h"
uint8_t LED_R;
uint8_t LED_B;
uint8_t LED_G;
uint8_t S2;
uint8_t S3;
uint8_t mode ;
int main(void)
{

    rt_kprintf("Hello, world\n");


    while (1)
    {
        rt_kprintf("mode:%d\r\n",mode);
        rt_thread_mdelay(1000); //空延时
    };




    return 0;
}

 

image.png

5.输入ps可以查看线程信息,可以看见多了按键线程和led线程。

QQ截图20210501015231.png

本文就到这里,下文介绍下定时器。

 

 

本帖最后由 xiyue521 于 2021-5-1 02:30 编辑
  • image.png

回复评论 (1)

看楼主用RTOS可以简化很多东西,调试确实是方便

点赞  2021-5-1 17:51
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复