BL602 GPIO的使用

参考3. GLB — BL602/604 参考手册(Confidential) 文档

一、使用函数操作IO口

1、IO口的操作,常用以下几个函数

//设管脚为输出模式
int bl_gpio_enable_output(uint8_t pin, uint8_t pullup, uint8_t pulldown)

//设置管脚为输入模式
int bl_gpio_enable_input(uint8_t pin, uint8_t pullup, uint8_t pulldown)

//设置管脚电平(输出模式使用)
int bl_gpio_output_set(uint8_t pin, uint8_t value)

//获取管脚电平(输入模式使用)
int bl_gpio_input_get_value(uint8_t pin)

这些函数属于hal_drv模块,因此我们需要把工程路径下的Makefile文件中的INCLUDE_COMPONENTS字段添加hal_drv

 2、在aos_loop_proc函数中调用user_gpio_init,一般放在aos_loop_run()之前

  这里我们创建一个GPIO的任务,间隔1秒执行LED管脚电平取反,并打印KEY管脚的电平状态

#define R_LED_PIN       GLB_GPIO_PIN_17
#define G_LED_PIN       GLB_GPIO_PIN_14
#define B_LED_PIN       GLB_GPIO_PIN_11

#define KEY_PIN         GLB_GPIO_PIN_1


/********************************************************************
 *@brief	GPIO任务
 *@input    
 *@return
********************************************************************/
static void user_gpio_task(void *arg)
{
	
	bl_gpio_enable_output(R_LED_PIN,0,0);		//配置管脚为输出,不打开上下拉电阻
	bl_gpio_enable_input(KEY_PIN,1,0);			//配置管脚为输入,打开上拉电阻

	bool flag = 0;
	while(1)
	{
    	vTaskDelay(1000/portTICK_RATE_MS);

		if(flag)
		{
			flag = 0;
			bl_gpio_output_set(R_LED_PIN,0);
		}
		else
		{
			flag = 1;
			bl_gpio_output_set(R_LED_PIN,1);
		}

		printf("bl_gpio_input_get_value %d\r\n",bl_gpio_input_get_value(KEY_PIN));
	}

	vTaskDelete(NULL);
}



/********************************************************************
 *@brief	GPIO初始化
 *@input    
 *@return
********************************************************************/
void user_gpio_init()
{
	xTaskCreate(user_gpio_task, "", 512, NULL, 2, NULL);
}

  注意:函数bl_gpio_input_get_value只能作为输入模式时读取的才是管脚电平,如果是输出模式,则读取的都是0。

  如果想在输出模式获取管脚状态时,可以获取设置寄存器的值,代码如下

uint32_t bl_gpio_output_get_value(GLB_GPIO_Type gpioPin)
{
    uint32_t *p=(uint32_t *)(GLB_BASE+GLB_GPIO_OUTPUT_OFFSET+((gpioPin>>5)<<2));
    uint32_t pos=gpioPin%32;

    if((*p)&(1<<pos)){
        return 1;
    }else{
        return 0;
    }
}

    

3、GPIO中断的使用

static void gpio_irq_callback(gpio_ctx_t *pstnode)
{
	//重新打开中断
	bl_gpio_intmask(pstnode->gpioPin,0);

	printf("gpio_irq_callback\r\n");
}


/********************************************************************
 *@brief	GPIO任务
 *@input    
 *@return
********************************************************************/
static void user_gpio_task(void *arg)
{
	gpio_ctx_t pstnode;
	pstnode.gpioPin 	 = KEY_PIN;
    pstnode.intCtrlMod 	 = GLB_GPIO_INT_CONTROL_SYNC;
    pstnode.intTrgMod 	 = GLB_GPIO_INT_TRIG_NEG_PULSE;    //下降沿中断
    pstnode.gpio_handler = (void *)&gpio_irq_callback;
    pstnode.arg 		 = NULL;
	pstnode.next 		 = NULL;

	bl_gpio_enable_input(pstnode.gpioPin,1,0);	//配置管脚为输入,打开上拉电阻
	bl_gpio_register(&pstnode);					//注册中断

	while(1)
	{
    	vTaskDelay(1000/portTICK_RATE_MS);
	}	

	vTaskDelete(NULL);
}

二、设备树使用

1、LED输出实验

1.1在aos_loop_proc函数中添加loopset_led_hook_on_looprt

 

 1.2在aos_loop_proc函数中添加hal_gpio_init_from_dts

    if (0 == get_dts_addr("gpio", &fdt, &offset)) {
        hal_gpio_init_from_dts(fdt, offset);
    }

  

1.3打开烧录工具中的bl_factory_params_IoTKitA_40M.dts,文件路径如下

添加如下代码

    gpio {
        #address-cells = <1>;
        #size-cells = <1>;
        max_num = <31>;
        gpio0 {                                  
            status = "okay";   	//okay or disable                  
            pin  = <11>;                          
            feature = "led";    //led                 
            active = "Lo"; 		//Hi or Lo
            mode = "blink"; 	//blink or heartbeat or onoff
            time = <500>; 		//duration for this mode
        };	
        gpio1 {                                  
            status = "okay"; 	//okay or disable                  
            pin  = <17>;                          
            feature = "led";    //led                 
            active = "Lo"; 		//Hi or Lo
            mode = "heartbeat"; //blink or heartbeat or onoff
            time = <1000>; 		//duration for this mode
        };	
        gpio2 {                                  
            status = "okay"; 	//okay or disable                  
            pin  = <14>;                          
            feature = "led";    //led                 
            active = "Lo"; 		//Hi or Lo
            mode = "onoff"; 	//blink or heartbeat or onoff
            time = <1500>; 		//duration for this mode
        };			
		
    };

  我们在上面定义了3个gpio管脚,分别是11、17、14管脚。功能是这三个管脚分别500ms、1000ms、1500ms闪烁

2、按键实验

2.1在aos_loop_proc函数中添加以下代码

    if (0 == get_dts_addr("gpio", &fdt, &offset)) {
        fdt_button_module_init((const void *)fdt, (int)offset);
    }

 

 2.2打开烧录工具中的bl_factory_params_IoTKitA_40M.dts,文件路径如下

添加如下代码

    gpio {
        #address-cells = <1>;
        #size-cells = <1>;
        max_num = <31>;
    
        gpio3 {
            status = "okay";
            pin = <1>;
            feature = "button";
            active = "Lo";
            mode = "multipress";
            button {
                debounce = <10>;
                short_press_ms {
                    start = <100>;
                    end = <3000>;
                    kevent = <2>;
                };
                long_press_ms {
                    start = <6000>;
                    end = <10000>;
                    kevent = <3>;
                };
                longlong_press_ms {
                    start = <15000>;
                    kevent = <4>;
                };
                trig_level = "Lo";
            };
            hbn_use = "disable";
        };
		
    };

  上面定义了IO1为按键管脚,100~3000ms是为短按,6000~10000ms是为长按,大于15000ms时为长长按

  我们还需要注册按键事件,在user_gpio_init初始化时调用aos_register_event_filter注册按键事件


static void event_cb_key_event(input_event_t *event, void *private_data)
{
    switch (event->code) {
        case KEY_1:
        {
            printf("[KEY_1] [EVT] INIT DONE %lld\r\n", aos_now_ms());
            printf("short press \r\n");
        }
        break;
        case KEY_2:
        {
            printf("[KEY_2] [EVT] INIT DONE %lld\r\n", aos_now_ms());
            printf("long press \r\n");
        }
        break;
        case KEY_3:
        {
            printf("[KEY_3] [EVT] INIT DONE %lld\r\n", aos_now_ms());
            printf("longlong press \r\n");
        }
        break;
        default:
        {
            printf("[KEY] [EVT] Unknown code %u, %lld\r\n", event->code, aos_now_ms());
            /*nothing*/
        }
    }
}

/********************************************************************
 *@brief	GPIO初始化
 *@input    
 *@return
********************************************************************/
void user_gpio_init()
{
	aos_register_event_filter(EV_KEY, event_cb_key_event, NULL);
}

LOG打印如下

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dear_Wally

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值