GPIO(General Purpose I/O Ports)意思为通用输入/输出端口,通俗地说,就是一些引脚,可以通过它们输出高低电平或者通过它们读入引脚的状态,是高电平或是低电平。
在实际开发中,想用MCU控制一些传感器或者采集信息,几乎都会用到GPIO口。
这里可以看到和我们的STM32的命名不一样,STM32的IO口最少都有四到五组(PA-PE),而且每一组有16个IO;但是在wujian100中,只有一组且一组32个IO;
了解STM32的同学可以知道,很多外设都可以复用IO口,例如利用定时器生成PWM,并通过某一个IO口输出,基本上会用到复用,STM32的GPIO会复杂很多。
对于wujian100,单纯的GPIO感觉就像简简单单的一个输入输出口,不过多了一个中断功能。感觉很不错,对于STM32实现该功能还要配置IO的exit中断。
这里都是配置GPIO的一些寄存器,对底层操作寄存器感兴趣的同学可以参照wujian100的数据手册学习,主要就是操作对应位实现对应配置。我就不赘述啦。
GPIO模式:
输入:浮空、上拉、下拉
输出:开漏、推挽
在下面代码可以理解到:
/*----- GPIO Control Codes: Mode -----*/
typedef enum {
GPIO_MODE_PULLNONE = 0, ///< pull none for input
GPIO_MODE_PULLUP, ///< pull up for input
GPIO_MODE_PULLDOWN, ///< pull down for input
GPIO_MODE_OPEN_DRAIN, ///< open drain mode for output
GPIO_MODE_PUSH_PULL, ///< push-pull mode for output
} gpio_mode_e;
GPIO的方向:输入、输出
/*----- GPIO Control Codes: Mode Parameters: Data Bits -----*/
typedef enum {
GPIO_DIRECTION_INPUT = 0, ///< gpio as input
GPIO_DIRECTION_OUTPUT, ///< gpio as output
} gpio_direction_e;
GPIO的中断模式:上升沿、下降沿、双边沿、低电平和高电平
/*----- GPIO Control Codes: Mode Parameters: Parity -----*/
typedef enum {
GPIO_IRQ_MODE_RISING_EDGE = 0, ///< interrupt mode for rising edge
GPIO_IRQ_MODE_FALLING_EDGE, ///< interrupt mode for falling edge
GPIO_IRQ_MODE_DOUBLE_EDGE, ///< interrupt mode for double edge
GPIO_IRQ_MODE_LOW_LEVEL, ///< interrupt mode for low level
GPIO_IRQ_MODE_HIGH_LEVEL, ///< interrupt mode for high level
} gpio_irq_mode_e;
GPIO的初始化函数接口:
gpio_pin_handle_t csi_gpio_pin_initialize(int32_t gpio_pin, gpio_event_cb_t cb_event);
wujian100开源的软件架构有一点就是把中断服务程序给封装了起来,不需要我们自己写,也就提高了开发效率,那如果我们要在中断中实现对应功能,那就可以用到回调函数(callback_event);
所以GPIO初始化可以这样:(没有开中断无回调函数,即NULL)
gpio_pin_handle_t pin1;
pin1 = csi_gpio_pin_initialize(PA0,NULL);
GPIO配置的API:
参数1是你定义初始化的IO,参数2是IO模式,参数3是方向;
int32_t csi_gpio_pin_config(gpio_pin_handle_t handle,
gpio_mode_e mode,
gpio_direction_e dir);
例:定义一个上拉输入的IO
csi_gpio_pin_config(pin1, GPIO_MODE_PULLUP,GPIO_DIRECTION_INPUT);
就这样简单的两句代码,你就可以开始使用IO口了,根据需要可以编写相应逻辑,实现对应的功能。
回调函数的例子
(需要设置中断),以中断为上升沿为例。
static void gpio_cb_event(int32_t idx)
{
rising_edge_flag = 1;
printf("test rising edge OK!\n");
}
对IO配置:
gpio_pin_handle_t pin1 = NULL;
pin1 = csi_gpio_pin_initialize(PA0,gpio_cb_event);
if(pin1 == NULL) {
printf("pin1 initialize error\n");
return;
}
csi_gpio_pin_config(pin1, GPIO_MODE_PULLDOWN,GPIO_DIRECTION_INPUT);//因为上升沿中断,所以我们设置为下拉
csi_gpio_pin_set_irq(pin1, GPIO_IRQ_MODE_RISING_EDGE, 1);
gpio_pin_handle_t pin = NULL;
gpio_pin_handle_t pin1 = NULL;
gpio_pin_handle_t pin2 = NULL;
int main()
{
pin = csi_gpio_pin_initialize(PA19,NULL);
pin1 = csi_gpio_pin_initialize(PA21,NULL);
pin2 = csi_gpio_pin_initialize(PA22,NULL);
if(pin == NULL) {
printf("initialize error!\n");
return;
}
if(pin1 == NULL) {
printf("initialize error!\n");
return;
}
if(pin2 == NULL) {
printf("initialize error!\n");
return;
}
csi_gpio_pin_config(pin,GPIO_MODE_PUSH_PULL,GPIO_DIRECTION_OUTPUT);
csi_gpio_pin_config(pin1,GPIO_MODE_PUSH_PULL,GPIO_DIRECTION_OUTPUT);
csi_gpio_pin_config(pin2,GPIO_MODE_PUSH_PULL,GPIO_DIRECTION_OUTPUT);
csi_gpio_pin_write(pin,1);
csi_gpio_pin_write(pin1,1);
csi_gpio_pin_write(pin2,1);
return 0;
}