一。分析LED灯原理图
RVB2601开发板,有一个封装好的红绿蓝三色灯,可以帮助我们熟悉GPIO的输出配置和端口的置位。看原理图,红灯对应的是PA7,绿灯对应PA25,蓝灯对应PA4. 通过原理图我们知道:当IO口输出为低电平时,LED二极管正向偏置,可以使发光二极管导通并发光;当IO口输出高电平,或者输出高阻时二极管不能形成正向偏置,发光二极管不能正常发光。
二。按键原理图
按键程序可以用来学习IO口的输入功能, 从按键原理图可知,无按键按下是IO口电平为高电平,当按键按下时IO口电平为低电平。
三。代码分析
主要是应用API库函数进行各种操作,多多参考https://yoc.docs.t-head.cn/yocbook/Chapter3-AliOS/CSI%E8%AE%BE%E5%A4%87%E9%A9%B1%E5%8A%A8%E6%8E%A5%E5%8F%A3/CSI2/GPIO_PIN.html#csigpiopininit,一定会有不小的收获。
CPU的IO口一般有多个可选功能,在soc.h 文件中有各个IO的定义,对于PA4口共有6个功能可以选择,分别为:
PA4_I2S0_SDA = 0U, PA4_SPI0_MOSI = 1U, PA4_UART1_CTS = 2U, PA4_PWM_CH4 = 3U, PA4_ADC_A2 = 9U, PIN_FUNC_GPIO = 4U,
我们使用IO口输出高低电平使用的是 IO口的PIN_FUNC_GPIO功能,下面以PA4口的蓝灯为例进行讲解,IO的操作我使用了gpio_pin.h中声明的头文件,原文件在chip_ch2601的drivers目录下gpio_pin.c及pinmux.c , 所以通过调用以下函数来实现IO初始化
csi_pin_set_mux(PA4, PIN_FUNC_GPIO);//来实现功能选择
csi_gpio_pin_init(&pin_blue_led, PA4); // 通过引脚号初始化对应的PIN脚 R
csi_gpio_pin_dir(&pin_blue_led, GPIO_DIRECTION_OUTPUT); //IO口设置成输出口
csi_gpio_pin_mode(&pin_red_led,GPIO_MODE_OPEN_DRAIN); //IO口设置成开漏输出模式,如果输出高电平点亮LED灯,应该设置IO口为推拉模式。
csi_gpio_pin_write(&pin_blue_led, GPIO_PIN_LOW)和csi_gpio_pin_write(&pin_blue_led, GPIO_PIN_HIGH) //控制IO输出低电平还是高电平
红灯和绿灯的使用方法和蓝灯是一样的。
按键代码中为了节省查询的方法,直接使用了下降沿中断来检测按键是否按下。按键中和点亮LED不同处是,按键IO必须设置成出入方式,
csi_gpio_pin_dir(&pin_key1, GPIO_DIRECTION_INPUT); //按键1设置成输入IO,还有就是编写按键的回调函数。static void key_interrupt_handler(csi_gpio_pin_t *pin,void *arg)
设置按键的中断触发是下降沿,上升沿,还是双边沿。并开启按键的中断功能。
四。程序源码
以下程序在ch2601_hello_world工程的基础上修改的main.c
#include <stdlib.h>
#include <string.h>
#include <aos/aos.h>
#include "aos/cli.h"
#include "main.h"
#include "app_init.h"
#include "oled.h"
#include <soc.h>
#include "drv/gpio_pin.h"
#include <drv/pin.h>
#define TAG "app"
//led定义
csi_gpio_pin_t pin_red_led;//PA7
csi_gpio_pin_t pin_green_led;//PA25
csi_gpio_pin_t pin_blue_led;//PA4
//LED宏定义
#define LED_RED_ON csi_gpio_pin_write(&pin_red_led, GPIO_PIN_LOW)
#define LED_GREEN_ON csi_gpio_pin_write(&pin_green_led, GPIO_PIN_LOW)
#define LED_BLUE_ON csi_gpio_pin_write(&pin_blue_led, GPIO_PIN_LOW)
#define LED_RED_OFF csi_gpio_pin_write(&pin_red_led, GPIO_PIN_HIGH)
#define LED_GREEN_OFF csi_gpio_pin_write(&pin_green_led, GPIO_PIN_HIGH)
#define LED_BLUE_OFF csi_gpio_pin_write(&pin_blue_led, GPIO_PIN_HIGH)
//key定义
csi_gpio_pin_t pin_key1;//PA11
csi_gpio_pin_t pin_key2;//PA12
/*LED初始化*/
void led_init(void)
{
csi_pin_set_mux(PA7, PIN_FUNC_GPIO);
csi_pin_set_mux(PA25, PIN_FUNC_GPIO);
csi_pin_set_mux(PA4, PIN_FUNC_GPIO);
csi_gpio_pin_init(&pin_red_led, PA7);
csi_gpio_pin_init(&pin_green_led, PA25);
csi_gpio_pin_init(&pin_blue_led, PA4);
csi_gpio_pin_dir(&pin_red_led, GPIO_DIRECTION_OUTPUT);
csi_gpio_pin_dir(&pin_green_led, GPIO_DIRECTION_OUTPUT);
csi_gpio_pin_dir(&pin_blue_led, GPIO_DIRECTION_OUTPUT);
csi_gpio_pin_mode(&pin_red_led,GPIO_MODE_OPEN_DRAIN);
csi_gpio_pin_mode(&pin_green_led,GPIO_MODE_OPEN_DRAIN);
csi_gpio_pin_mode(&pin_blue_led,GPIO_MODE_OPEN_DRAIN);
}
//按键中断回调函数
static void key_interrupt_handler(csi_gpio_pin_t *pin,void *arg)
{
if(csi_gpio_pin_read(&pin_key1)==GPIO_PIN_LOW)
{
printf("key1 press\r\n");
}
if(csi_gpio_pin_read(&pin_key2)==GPIO_PIN_LOW)
{
printf("key2 press\r\n");
}
}
/*按键初始化*/
void key_init(void)
{
csi_pin_set_mux(PA11, PIN_FUNC_GPIO);
csi_pin_set_mux(PA12, PIN_FUNC_GPIO);
csi_gpio_pin_init(&pin_key1, PA11);
csi_gpio_pin_init(&pin_key2, PA12);
csi_gpio_pin_dir(&pin_key1, GPIO_DIRECTION_INPUT);
csi_gpio_pin_dir(&pin_key2, GPIO_DIRECTION_INPUT);
csi_gpio_pin_mode(&pin_key1,GPIO_MODE_PULLNONE);
csi_gpio_pin_mode(&pin_key2,GPIO_MODE_PULLNONE);
csi_gpio_pin_attach_callback(&pin_key1,key_interrupt_handler,NULL);
csi_gpio_pin_attach_callback(&pin_key2,key_interrupt_handler,NULL);
csi_gpio_pin_irq_mode(&pin_key1, GPIO_IRQ_MODE_FALLING_EDGE);
csi_gpio_pin_irq_mode(&pin_key2, GPIO_IRQ_MODE_FALLING_EDGE);
csi_gpio_pin_irq_enable(&pin_key1, true);
csi_gpio_pin_irq_enable(&pin_key2, true);
}
int main(void)
{
board_yoc_init();
LOGD(TAG, "%s\n", aos_get_app_version());
oled_init();
led_init();
key_init();
LED_RED_OFF;
LED_GREEN_OFF;
LED_BLUE_OFF;
LOGD(TAG, "led and key test");
//红、绿、蓝灯交替点亮
while (1) {
LED_RED_ON;
aos_msleep(1000);
LED_RED_OFF;
LED_GREEN_ON;
aos_msleep(1000);
LED_GREEN_OFF;
LED_BLUE_ON;
aos_msleep(1000);
LED_BLUE_OFF;
}
return 0;
}
五。总结
搞定程序前,必须能够读懂原理图。然后参照API就可以轻松搞定你想做的了。下期一起搞定UART(串口),期待下期再会!