这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 【彩屏贪吃蛇小游戏】2、过程贴-LED灯的闪烁与按键的控制

共1条 1/1 1 跳转至

【彩屏贪吃蛇小游戏】2、过程贴-LED灯的闪烁与按键的控制

高工
2024-08-18 13:33:55     打赏

本帖主要实现以下功能:

        编程实现LED灯的闪烁((尽量实现呼吸灯)

        编程实现按键控制LED灯的亮灭(按下一次LED亮,再按一次LED灭)。

        可以看到要求中包含LED的亮灭控制和呼吸灯,以及按键采集部分,所以我们先初步划分一下,LED的状态至少有三种亮、灭、闪烁、呼吸灯,正好可以对应4个按键,同时显示模块上还有一个RGB,也可以通过按键控制加入。实际上加上开发板上的资源,我们可以使用的是1个LED、一个RGB、5个用户按键。

        首先看一下LED:

image.png

        LED的亮灭直接受控于GPIO状态,高电平激活LED发光,低电平则熄灭LED。基于PICO开发板设计,绿色LED与GPIO25引脚相连,采用高电平触发点亮机制。

        开发板按键:

image.png

        该板载按键原本设计为BOOT功能,但在系统运行时也能作为普通按键使用,其按下时通过电阻R11的作用,使得QSPI_SS端(即PICO的56号引脚)呈现低电平状态,进而被系统检测识别,对按键输入电平检测,则需要将端口引脚设置为输入模式。

        扩展模组上的RGB灯和按键实际上也是同理的,我们大致看一下原理图就可以了:

image.png

        灯点亮的控制是低电平点亮,按键采集方式是一样的。

        我们回到程序上,本次使用的是课程提供的工程进行设计,这样可以避免很多不必要的麻烦。

        我们首先实现LED的闪烁:

#define PICO_LED_PIN 25


//GPIO初始化函数
void LED_init(){
    gpio_init(PICO_LED_PIN);
    gpio_set_dir(PICO_LED_PIN, GPIO_OUT);

}
//板载灯点亮函数
void LED_ON(){
    gpio_put(PICO_LED_PIN, 1);
}
//板载灯熄灭函数
void LED_OFF(){
    gpio_put(PICO_LED_PIN, 0);
}

        闪烁的实现还是比较简单的,通过演示实现闪烁:

LED_init();
while (true){
    DEV_Delay_ms(500);    
    LED_ON();
    DEV_Delay_ms(500);    
    LED_OFF();  
}

        效果如下:

LED闪烁.gif

        接下来实现呼吸灯的操作:

void LED_PWM_init(){
    // PWM Config
    gpio_set_function(PICO_LED_PIN, GPIO_FUNC_PWM);
    my_slice_num = pwm_gpio_to_slice_num(PICO_LED_PIN);
    pwm_set_wrap(my_slice_num, 100);
    pwm_set_chan_level(my_slice_num, PWM_CHAN_B, 1);
    pwm_set_clkdiv(my_slice_num,50);
    pwm_set_enabled(my_slice_num, true);
    
}

void LED_SET_PWM(uint8_t Value)
{
    if(Value<0 || Value >100){
        //printf("DEV_SET_PWM Error \r\n");
    }else {
        pwm_set_chan_level(my_slice_num, PWM_CHAN_B, Value);
    }
}

        通过循环修改PWM的值实现呼吸灯效果:

LED_PWM_init();
while (true){
    DEV_Delay_ms(10);    
    if(pwm_cnt == 0){
        pwm_dir = 0;
    }
    if(pwm_cnt >= 100){
        pwm_dir = 1;
    }
    if(pwm_dir == 0){    
        pwm_cnt++;
    }
    else{
        pwm_cnt--;
    }    
    LED_SET_PWM(pwm_cnt);        
}

        效果如下:

呼吸灯.gif

        按键的采集实际上是输入检测的实现,这里我们也扩展一下,使用三个按键实现RGB的三个灯的亮灭控制,按一下状态翻转一下。按键都是0表示按下,这里我们集合到一起:

void key_init(){
    gpio_init   (PIN_DIRECTION_KEY_A);
    gpio_set_dir(PIN_DIRECTION_KEY_A, GPIO_IN);  
    gpio_set_pulls(PIN_DIRECTION_KEY_A,1, 0);
    
    gpio_init   (PIN_DIRECTION_KEY_B);
    gpio_set_dir(PIN_DIRECTION_KEY_B, GPIO_IN);  
    gpio_set_pulls(PIN_DIRECTION_KEY_B,1, 0);
    
    gpio_init   (PIN_DIRECTION_KEY_X);
    gpio_set_dir(PIN_DIRECTION_KEY_X, GPIO_IN);  
    gpio_set_pulls(PIN_DIRECTION_KEY_X,1, 0);
    
    gpio_init   (PIN_DIRECTION_KEY_Y);
    gpio_set_dir(PIN_DIRECTION_KEY_Y, GPIO_IN);  
    gpio_set_pulls(PIN_DIRECTION_KEY_Y,1, 0);
}

uint8_t get_button(uint8_t key_pin){
    if(gpio_get(key_pin) == 0){
        DEV_Delay_ms(10);
        if(gpio_get(key_pin) == 0){
            while(gpio_get(key_pin) == 0);
            return 1;
        }
        else
            return 0; 
    }else{
        return 0; 
    } 
}

        LED的翻转也集合一下:

void LED_Toggle(uint8_t LED_GPIO){
    uint8_t led_on = 0;
    led_on =  gpio_get(LED_GPIO);
    led_on=!led_on;
    gpio_put(LED_GPIO, led_on);
}

        然后将按键与灯进行关联:

while (true){
    if(get_button(PIN_DIRECTION_KEY_A) == 1)
        LED_Toggle(PICO_Pack_R_PIN);
    if(get_button(PIN_DIRECTION_KEY_B) == 1)
        LED_Toggle(PICO_Pack_G_PIN);
    if(get_button(PIN_DIRECTION_KEY_X) == 1)   
        LED_Toggle(PICO_Pack_B_PIN);                               
}

        效果如下:

按键控制灯.gif


共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]