HaaS EDU K1设备资源 之 GPIO

HaaS EDU K1设备资源 之 GPIO

1、背景介绍

HaaS EDU K1是HaaS Education Kit1的缩写,是基于四核高性能MCU-HaaS1000芯片打造的、集颜值和内涵于一身的物联网教育开发板。

关于整体硬件介绍,有兴趣可参考HaaS EDU K1硬件介绍

关于设备资源整体介绍,有兴趣可参考HaaS EDU K1设备资源总体介绍

 

MCU-HaaS1000是一颗专为IoT智能硬件打造的SoC,带了5组GPIO(P0~P4),每组8个,共40个。所有IO都是复用的,每个有最多有6种不同的功能可配。

具体如下表:

Function 0

Function 1

Function 2

Function 3

Function 4

Function 5

Function 6

GPIO_P0_0

I2S0_SDI

UART2_RXD

PCM_DI

SPI1_DI0

PDM0_CK

SPI1_DCN

GPIO_P0_1

I2S0_SDO

UART2_TXD

PCM_DO

SPI1_DIO

PDM0_D

 

GPIO_P0_2

I2S0_WS

I2C_M1_SCL

PCM_FSYNC

SPI1_CS0

PDM1_D

SPDIF0_DI

GPIO_P0_3

I2S0_SCK

I2C_M1_SDA

PCM_CLK

SPI1_CLK

PDM2_D

SPDIF0_DO

GPIO_P0_4

SDMMC_DATA7

SPI0_DI0

I2S_MCLK

CLK_OUT

PDM1_CK

SPI0_DCN

GPIO_P0_5

SDMMC_DATA6

SPI0_CLK

 

SPI1_CS1

PDM1_D

 

GPIO_P0_6

SDMMC_DATA5

SPI0_CS0

UART2_CTS

SPI1_CS2

PDM0_D

 

GPIO_P0_7

SDMMC_DATA4

SPI0_DIO

UART2_RTS

SPI1_CS3

PDM2_D

 

GPIO_P1_0

SDMMC_DATA2

 

SPI1_CLK

SPI0_CS1

I2S0_DI3

 

GPIO_P1_1

SDMMC_DATA3

 

SPI1_CS0

SPI0_CS2

I2S0_DI2

 

GPIO_P1_2

SDMMC_CMD

 

SPI1_CS1

SPI0_CS3

I2S0_DI1

 

GPIO_P1_3

SDMMC_CLK

I2S_MCLK

SPI1_DCN

CLK_OUT

I2S0_DI0

 

GPIO_P1_4

SDMMC_DATA0

 

SPI1_DI0

 

 

 

GPIO_P1_5

SDMMC_DATA1

 

SPI1_DIO

I2S_MCLK

CLK_OUT

 

GPIO_P1_6

UART0_RXD

I2C_M0_SCL

BT_UART_RXD

 

 

 

GPIO_P1_7

UART0_TXD

I2C_M0_SDA

BT_UART_TXD

 

 

 

GPIO_P2_0

UART1_RXD

I2C_M0_SCL

BT_UART_RXD

SPDIF0_DI

pwm2

I2S_MCLK

GPIO_P2_1

UART1_TXD

I2C_M0_SDA

BT_UART_TXD

SPDIF0_DO

pwm3

CLK_OUT

GPIO_P2_2

I2C_M1_SCL

UART2_RXD

UART1_CTS

BT_UART_CTS

 

I2S_MCLK

GPIO_P2_3

I2C_M1_SDA

UART2_TXD

UART1_RTS

BT_UART_RTS

 

CLK_OUT

GPIO_P2_4

pwm2

CLK_REQ_OUT

SPI0_DI3

 

 

 

GPIO_P2_5

pwm3

CLK_REQ_IN

SPI0_CS3

 

 

 

GPIO_P2_6

pwm0

SPI1_DI1

UART2_CTS

SPDIF0_DI

CLK_32K_IN

 

GPIO_P2_7

pwm1

SPI1_CS1

UART2_RTS

SPDIF0_DO

CLK_OUT

 

GPIO_P3_0

SPI1_DI2

 

SPI1_CS1

 

PDM0_D

WF_UART_RX

GPIO_P3_1

SPI1_CS2

 

SPI1_CS2

 

PDM1_D

WF_UART_TX

GPIO_P3_2

SPI1_CS3

 

SPI1_CS3

 

PDM2_D

 

GPIO_P3_3

SPI1_DI3

 

 

 

PDM2_CK

 

GPIO_P3_4

pwm2

SPI0_DI1

I2S0_DI3

SPI1_DI0

CLK_OUT

SPI1_DCN

GPIO_P3_5

pwm3

SPI0_CS1

I2S0_DI2

SPI1_DIO

 

 

GPIO_P3_6

pwm0

SPI0_DI2

I2S0_DI1

SPI1_CS0

 

 

GPIO_P3_7

pwm1

SPI0_CS2

I2S0_DI0

SPI1_CLK

 

 

GPIO_P4_0

I2S0_DI3

UART2_CTS

 

 

 

 

GPIO_P4_1

I2S0_DI2

UART2_RTS

 

 

 

 

GPIO_P4_2

I2S0_DI1

 

 

 

 

 

GPIO_P4_3

I2S0_DI0

 

 

 

 

 

GPIO_P4_4

WF_UART_RX

 

 

 

 

 

GPIO_P4_5

WF_UART_TX

 

 

 

 

 

GPIO_P4_6

WF_UART_CTS

 

 

 

 

 

GPIO_P4_7

WF_UART_RTS

 

 

 

 

 

                                                            表1 HaaS1000芯片GPIO Iomux可选功能表

 

在HaaS EDU K1中,绝大多数IO都进行了分配,可供外部扩展使用的只有直接有8个。GPIO分配如下表所示:

 

功能模块

原理图网络名

管脚名称

GPIO对应软件port_num

默认选中功能以及IOMUX选择

OLED

SPI1_DIO(MOSI)

Y11

HAL_IOMUX_PIN_P3_5

SPI1_DIO

Function 4

SPI1_CLK

V11

HAL_IOMUX_PIN_P3_7

SPI1_CLK

Function 4

SPI1_DI0(MISO)

W10

HAL_IOMUX_PIN_P3_4

GPIO_P3_4

Function 0

OLED_RST

U10

HAL_IOMUX_PIN_P3_6

GPIO_P3_6

Function 0

AP3216C_INT

T5

HAL_IOMUX_PIN_P4_7

GPIO_P4_7

Function 0

SPI0_CS0

B9

HAL_IOMUX_PIN_P0_6

GPIO_P0_6

Function 0

I2C1

I2C_SCL1

F11

HAL_IOMUX_PIN_P0_2

GPIO_P0_2

Function 0

I2C_SDA1

E12

HAL_IOMUX_PIN_P0_3

GPIO_P0_3

Function 0

T-FLASH

SDMMC0_D2

F7

HAL_IOMUX_PIN_P1_0

SDMMC_DATA2

Function 1

SDMMC0_D3

E6

HAL_IOMUX_PIN_P1_1

SDMMC_DATA3

Function 1

SDMMC0_CMD

M12

HAL_IOMUX_PIN_P1_2

SDMMC_CMD

Function 1

SDMMC0_CLK

N12

HAL_IOMUX_PIN_P1_3

SDMMC_CLK

Function 1

SDMMC0_D0

D9

HAL_IOMUX_PIN_P1_4

SDMMC_DATA0

Function 1

SDMMC0_D1

C7

HAL_IOMUX_PIN_P1_5

SDMMC_DATA1

Function 1

SDMMC0_DET_L

Y6

HAL_IOMUX_PIN_P3_1

GPIO_P3_1

Function 0

蜂鸣器

PWM0

N10

HAL_IOMUX_PIN_P2_6

GPIO_P2_6

Function 0

LED

LED3

AA5

HAL_IOMUX_PIN_P4_2

GPIO_P4_2

Function 0

LED4

AA4

HAL_IOMUX_PIN_P4_3

GPIO_P4_3

Function 0

LED5

R4

HAL_IOMUX_PIN_P4_4

GPIO_P4_4

Function 0

KEY

KEY1

M13

HAL_IOMUX_PIN_P2_7

GPIO_P2_7

Function 0

KEY2

D7

HAL_IOMUX_PIN_P2_4

GPIO_P2_7

Function 0

KEY3

E8

HAL_IOMUX_PIN_P2_5

GPIO_P2_5

Function 0

KEY4

W6

HAL_IOMUX_PIN_P3_2

GPIO_P3_2

Function 0

MPU6050

MPU6050_INT

Y9

HAL_IOMUX_PIN_P4_1

GPIO_P4_1

Function 0

QMC5883L

QMC5883L_INT

T4

HAL_IOMUX_PIN_P4_6

GPIO_P4_6

Function 0

AP3216C

AP3216C_INT

T5

HAL_IOMUX_PIN_P4_7

GPIO_P4_7

Function 0

UART串口

UART_RX

U12

HAL_IOMUX_PIN_P1_6

UART0_RXD

Function 1

UART_TX

V13

HAL_IOMUX_PIN_P1_7

UART0_TXD

Function 1

30p扩展接口

UART2_RXD

D11

HAL_IOMUX_PIN_P2_2

UART2_RXD

Function 2

UART2_TXD

C12

HAL_IOMUX_PIN_P2_3

UART2_TXD

Function 2

SPI0_DI0(MISO)

B10

HAL_IOMUX_PIN_P0_4

SPI0_DI0

Function 1

SPI0_CLK

E10

HAL_IOMUX_PIN_P0_5

SPI0_CLK

Function 1

SPI0_CS0

B9

HAL_IOMUX_PIN_P0_6

SPI0_CS0

Function 1

SPI0_DIO(MOSI)

C10

HAL_IOMUX_PIN_P0_7

SPI0_DIO

Function 1

SWDIO

C8

HAL_IOMUX_PIN_P0_0

GPIO_P0_0

Function 0

SWCLK

F9

HAL_IOMUX_PIN_P0_1

GPIO_P0_1

Function 0

                                                            表2 HaaS EDU k1 GPIO默认分配

 

默认每个模块(比如I2C,SPI, ADC,  PWM,  SDCARD等)的占用的GPIO的配置都已经分别封装到每个模块内部去了,比如SPI0初始化后,驱动代码就会自动将GPIO_P0_4,GPIO_P0_5,GPIO_P0_6,GPIO_P0_7配置成SPI模式。不需要再次手动配置。

所有的I2C器件(MPU6050、QMC5883L、AP3216C等)都连接到一根I2C总线上(GPIO_P0_2,GPIO_P0_3)。

所有的IO均可以配置成GPIO模式,但是对于已经被占用了的IO,以不影响基本功能为前提(比如OLED占用了三个SPI管脚,如果需要OLED显示,就不要重新配置这三个IO了)。对于未被占用的这些GPIO,均可以通过GPIO初始化的方式重新初始化,AliOS Things中对这些接口已经进行了封装,直接调用即可。

以30P扩展口的UART2_RXD为例,当我们不使用uart2时,可以将其配置成普通的GPIO来使用。首先从表2中查到UART2_RXD的的"GPIO对应软件port名"项对应的port_num为HAL_IOMUX_PIN_P2_2。

配置如下:

gpio_dev_t gpio_test;

gpio_test.port = HAL_IOMUX_PIN_P2_2; // UART2_RXD引脚对应的port number

/* set as output mode */

gpio_test.config = OUTPUT_PUSH_PULL;

ret = hal_gpio_init(&gpio_test);

在AliOS Things中,GPIO的使用都已经封装到了HaL层接口里面。下面详细介绍一下。

 

2、HAL层接口介绍

2.1、API列表

hal_gpio_init

初始化指定GPIO管脚

hal_gpio_output_high

使指定GPIO输出高电平

hal_gpio_output_low

使指定GPIO输出低电平

hal_gpio_output_toggle

使指定GPIO输出翻转

hal_gpio_input_get

获取指定GPIO管脚的输入值

hal_gpio_enable_irq

使能指定GPIO的中断模式,挂载中断服务函数

hal_gpio_disable_irq

关闭指定GPIO的中断

hal_gpio_clear_irq

清除指定GPIO的中断状态

hal_gpio_finalize

关闭指定GPIO

 

2.2、API详情

请参考include/aos/hal/gpio.h

 

2.2.1、相关结数据结构

gpio_dev_t

typedef struct {

    uint8_t       port;    /* gpio逻辑端口号 */

    gpio_config_t config;  /* gpio配置信息 */

    void         *priv;    /* 私有数据 */

} gpio_dev_t;

gpio_config_t

typedef enum {

    ANALOG_MODE,               /* 管脚用作功能引脚,如用于pwm输出,uart的输入引脚 */

    IRQ_MODE,                  /* 中断模式,配置为中断源 */

    INPUT_PULL_UP,             /* 输入模式,内部包含一个上拉电阻 */

    INPUT_PULL_DOWN,           /* 输入模式,内部包含一个下拉电阻 */

    INPUT_HIGH_IMPEDANCE,      /* 输入模式,内部为高阻模式 */

    OUTPUT_PUSH_PULL,          /* 输出模式,普通模式 */

    OUTPUT_OPEN_DRAIN_NO_PULL, /* 输出模式,输出高电平时,内部为高阻状态 */

    OUTPUT_OPEN_DRAIN_NO_PULL, /* 输出模式,输出高电平时,被内部电阻拉高 */

} gpio_config_t;

gpio_irq_trigger_t

typedef enum {

    IRQ_TRIGGER_RISING_EDGE  = 0x1, /* 上升沿触发 */

    IRQ_TRIGGER_FALLING_EDGE = 0x2, /* 下降沿触发 */

    IRQ_TRIGGER_BOTH_EDGES   = IRQ_TRIGGER_RISING_EDGE | IRQ_TRIGGER_FALLING_EDGE,                                    /* 上升沿下降沿均触发 */

} gpio_irq_trigger_t;

gpio_irq_handler_t

typedef void (*gpio_irq_handler_t)(void *arg);

 

2.2.2、hal_gpio_init

GPIO 初始化

函数原型

int32_t hal_gpio_init(gpio_dev_t *gpio);

参数

gpio_dev_t *gpio

入参

GPIO设备描述,定义需要初始化的GPIO管脚的相关特性

用户自定义该结构体

返回值

类型:int 返回成功或失败, 返回0表示GPIO初始化成功,非0表示失败

 

调用示例

#define GPIO_LED_IO HAL_IOMUX_PIN_P4_2 // LED3

gpio_dev_t led;

led.port = GPIO_LED_IO;

/* set as output mode */

led.config = OUTPUT_PUSH_PULL;

ret = hal_gpio_init(&led);


2.2.3、hal_gpio_output_high

某GPIO输出高电平

函数原型

int32_t hal_gpio_output_high(gpio_dev_t *gpio)

参数

gpio_dev_t *gpio

入参

GPIO设备描述

使用hal_gpio_init初始化传入值 ,需要预设输出模式

返回值

类型:int 返回成功或失败, 返回0表示GPIO输出高电平成功,非0表示失败

调用示例

#define GPIO_IO_OUT HAL_IOMUX_PIN_P4_2 //LED3

gpio_dev_t gpio_out;

gpio_out.port = GPIO_IO_OUT;

/* set as output mode */

gpio_out.config = OUTPUT_PUSH_PULL;

ret = hal_gpio_init(&gpio_out);

ret= hal_gpio_output_high(&gpio_out);

 

2.2.4、hal_gpio_output_low

某GPIO输出低电平

函数原型

int32_t hal_gpio_output_low(gpio_dev_t *gpio)

参数

gpio_dev_t *gpio

入参

GPIO设备描述

使用hal_gpio_init初始化传入值 ,需要预设输出模式

返回值

类型:int 返回成功或失败, 返回0表示GPIO输出低电平成功,非0表示失败

调用示例

#define GPIO_IO_OUT HAL_IOMUX_PIN_P4_2 //LED3

gpio_dev_t gpio_out;

gpio_out.port = GPIO_IO_OUT;

/* set as output mode */

gpio_out.config = OUTPUT_PUSH_PULL;

ret = hal_gpio_init(&gpio_out);

ret= hal_gpio_output_low(&gpio_out);

 

2.2.5、hal_gpio_output_toggle

某GPIO输出翻转

函数原型

int32_t hal_gpio_output_toggle(gpio_dev_t* gpio)

参数

gpio_dev_t *gpio

入参

GPIO设备描述

使用hal_gpio_init初始化传入值 ,需要预设输出模式

返回值

类型:int 返回成功或失败, 返回0表示GPIO翻转成功,非0表示失败。

调用示例

#define GPIO_IO_OUT HAL_IOMUX_PIN_P4_2 //LED3

gpio_dev_t gpio_out;

gpio_out.port = GPIO_IO_OUT;

/* set as output mode */

gpio_out.config = OUTPUT_PUSH_PULL;

ret = hal_gpio_init(&gpio_out);

ret= hal_gpio_output_toggle(&gpio_out);

 

2.2.6、hal_gpio_input_get

获取某GPIO管脚输入值

函数原型

int32_t hal_gpio_input_get(gpio_dev_t *gpio, uint32_t *value)

参数

gpio_dev_t *gpio

入参

GPIO设备描述

使用hal_gpio_init初始化传入值 ,需要预设输入模式

uint32_t *value

出参

需要获取的管脚值存放地址

自定义uint32_t数据结构,传入地址

返回值

类型:int 返回成功或失败, 返回0表示GPIO输入获取成功,非0表示失败。

调用示例

#define GPIO_IO_OUT HAL_IOMUX_PIN_P2_7 //KEY1

uint32_t pinval = 0;

gpio_dev_t gpio_out;

gpio_out.port = GPIO_IO_OUT;

/* set as input mode */

gpio_out.config = INPUT_PULL_UP;

ret = hal_gpio_init(&gpio_out);

ret= hal_gpio_input_get(&gpio_out,&pinval);

 

2.2.7、hal_gpio_enable_irq

使能指定GPIO的中断模式,挂载中断服务函数,需要预先调用hal_gpio_init,设置IRQ_MODE。

函数原型

int32_t hal_gpio_enable_irq(gpio_dev_t *gpio, gpio_irq_trigger_t trigger,gpio_irq_handler_t handler, void *arg)

参数

gpio_dev_t *gpio

入参

GPIO设备描述

使用hal_gpio_init初始化传入值

gpio_irq_trigger_t

入参

中断的触发模式,上升沿、下降沿还是都触发

直接使用gpio_irq_trigger_t枚举

gpio_irq_handler_t handler

入参

中断服务函数指针,中断触发后将执行指向的函数

 

void *arg

入参

中断服务函数的入参

 

返回值

类型:int 返回成功或失败, 返回0使能中断成功,非0表示失败。

调用示例

#define GPIO_IO_INT HAL_IOMUX_PIN_P2_7 //KEY1

void gpio_irq_fun(void *arg)

{

}

gpio_dev_t gpio_int;

gpio_int.port = GPIO_IO_INT;

/* set as int mode */

gpio_int.config = IRQ_MODE;

ret = hal_gpio_init(&gpio_int);

/* int triggered int rising edge */

ret= hal_gpio_enable_irq(&gpio_int, IRQ_TRIGGER_RISING_EDGE,gpio_irq_fun,NULL);

 

2.2.8、hal_gpio_disable_irq

关闭指定GPIO的中断。

函数原型

int32_t hal_gpio_disable_irq(gpio_dev_t *gpio)

参数

gpio_dev_t *gpio

入参

GPIO设备描述

使用hal_gpio_init初始化传入值

返回值

类型:int 返回成功或失败, 返回0表示中断去使能成功,非0表示失败。

调用示例

ret= hal_gpio_disable_irq(&gpio_int);

 

2.2.9、hal_gpio_clear_irq

清除指定GPIO的中断。

函数原型

int32_t hal_gpio_clear_irq(gpio_dev_t *gpio)

参数

gpio_dev_t *gpio

入参

GPIO设备描述

使用hal_gpio_init初始化传入值

返回值

类型:int 返回成功或失败, 返回0表示清中断成功,非0表示失败。

调用示例

ret= hal_gpio_clear_irq(&gpio_int);


2.2.10、hal_gpio_finalize

关闭指定GPIO,及其中断。

函数原型

int32_t hal_gpio_finalize(gpio_dev_t *gpio)

参数

gpio_dev_t *gpio

入参

GPIO设备描述

使用hal_gpio_init初始化传入值

返回值

类型:int 返回成功或失败, 返回0表示关闭成功,非0表示失败。

调用示例

ret= hal_gpio_finalize(&gpio_int);

 

3、案例介绍

本小结主要学习通过LED验证GPIO的输出。

3.1、硬件实现

本章用到的硬件为LED5 (GPIO_P4_4,对应面板的L1)、LED4 (GPIO_P4_3,对应面板的L2), LED3(GPIO_P4_2,对应面板的L3)。

如下图:

HaaS EDU K1设备资源 之 GPIO

 

图1 硬件示意图

 

其电路在开发板上默认是已经连接好了的。GPIO拉低点亮,拉高熄灭,所以在硬件上不需要动任何东西。其连接原理图如图下:

HaaS EDU K1设备资源 之 GPIO

 

图2 LED部分原理图

 

3.2、软件设计

本小节用到了三个GPIO,通过拉高GPIO就可以让对应的LED亮起来,通过拉低GPIO再将对应的LED灭掉。

运行效果

三个状态灯一直循环闪烁。

应用代码

通过控制GPIO的高低来控制LED1的亮灭。

代码路径如下:

application/example/edu_demo/mfg_test/led_test.c
 

void led_blink(void)

{

    unsigned int led_id = 0;



    while(led_test_flag) {

        if(led_id % 2 == 0) {

            led_switch(1, LED_ON);

            led_switch(2, LED_ON);

            led_switch(3, LED_ON);

        } else {

            led_switch(1, LED_OFF);

            led_switch(2, LED_OFF);

            led_switch(3, LED_OFF);

        }

        aos_msleep(500);

        led_id ++;

    }

}

LED代码实现

代码路径如下:

platform/board/haaseduk1/drivers/led.c

void led_switch(led_num_e id, led_e onoff)

{

    int ret = 0;

    gpio_dev_t led;



    /* gpio port config */

    switch (id) {

        case 1: led.port = HAL_IOMUX_PIN_P4_4;

            break;

        case 2: led.port = HAL_IOMUX_PIN_P4_3;

            break;

        case 3: led.port = HAL_IOMUX_PIN_P4_2;

            break;

        default:

            return;

    }



    /* set as output mode */

    led.config = OUTPUT_PUSH_PULL;



    ret = hal_gpio_init(&led);

    if(ret != 0) {

        printf("hal_gpio_init %d failed, ret=%d\n", id, ret);

        return;

    }



    if(onoff == LED_ON) {

        ret = hal_gpio_output_high(&led);

    } else {

        ret = hal_gpio_output_low(&led);

    }

    if(ret != 0) {

        printf("hal_gpio_output %d failed, ret=%d\n", id, ret);

        return;

    }

}

3.3、编译与下载

3.3.1、代码准备

参考HaaS EDU K1 快速开始下载HaaS EDK K1的完成代码。

  • 打开edu_demo的产测开关

application/example/edu_demo/Config.in

在该文件中修改编译选项,打开EDK_DEMO_FACTORY_TEST_ENABLIE开关。

config EDK_DEMO_FACTORY_TEST_ENABLIE

    bool "enable factory test function"

    default y

  • 加入Demo到启动代码

application/example/edu_demo/app_entry.c

函数application_start中注释掉menu_init();,添加led_test();

        //menu_init();

        led_test();

 

3.3.2、编译

有两种方法进行编译,

命令行方式

aos make distclean

aos make edu_demo@haaseduk1 -c config

aos make

 

3.3.3、烧录

  • 命令行方式
aos upload
  • 图形界面方式

详见haaS EDU k1 快速开始 第4.3.3章节-使用GUI工具烧录部分。

 

开发者技术支持

如需更多技术支持,可加入钉钉开发者群,或者关注微信公众号

HaaS EDU K1设备资源 之 GPIO

更多技术与解决方案介绍,请访问阿里云AIoT首页https://iot.aliyun.com/

 

上一篇:重磅:Flume1-7结合kafka讲解


下一篇:如何一步一步新建一个Owin项目