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

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

该板载按键原本设计为BOOT功能,但在系统运行时也能作为普通按键使用,其按下时通过电阻R11的作用,使得QSPI_SS端(即PICO的56号引脚)呈现低电平状态,进而被系统检测识别,对按键输入电平检测,则需要将端口引脚设置为输入模式。
扩展模组上的RGB灯和按键实际上也是同理的,我们大致看一下原理图就可以了:

灯点亮的控制是低电平点亮,按键采集方式是一样的。
我们回到程序上,本次使用的是课程提供的工程进行设计,这样可以避免很多不必要的麻烦。
我们首先实现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();
}效果如下:

接下来实现呼吸灯的操作:
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);
}效果如下:

按键的采集实际上是输入检测的实现,这里我们也扩展一下,使用三个按键实现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);
}效果如下:

我要赚赏金
