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详情
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)。
如下图:
图1 硬件示意图
其电路在开发板上默认是已经连接好了的。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工具烧录部分。
开发者技术支持
如需更多技术支持,可加入钉钉开发者群,或者关注微信公众号
更多技术与解决方案介绍,请访问阿里云AIoT首页https://iot.aliyun.com/
标签:HAL,hal,PIN,HaaS,EDU,IOMUX,K1,GPIO,gpio 来源: https://blog.csdn.net/HaaSTech/article/details/114578967