【LVGL】不同类型输入设备驱动接口的实现

官方提供了lv_port_indev_template.c文件,用以实现触摸屏、鼠标、键盘、编码器、按钮五种输入设备的接口程序。使用相应的设备,就需要去掉接口部分的注释,填充相应的初始化函数和读取函数。
LVGL支持多设备输入,只需要在lv_port_indev_init()函数中注册多个输入设备结构体即可。
比如,这里注册了三个输入设备,分别对应触摸屏键盘编码器

void lv_port_indev_init(void)
{
    static lv_indev_drv_t indev_drv1, indev_drv2, indev_drv3;

    /* 初始化触摸屏 */
    touchpad_init();

    /* 注册触摸屏输入设备 */
    lv_indev_drv_init(&indev_drv1);
    indev_drv1.type = LV_INDEV_TYPE_POINTER;
    indev_drv1.read_cb = touchpad_read;
    indev_touchpad = lv_indev_drv_register(&indev_drv1);

    /* 初始化键盘 */
    keypad_init();

    /* 注册键盘输入设备 */
    lv_indev_drv_init(&indev_drv2);
    indev_drv2.type = LV_INDEV_TYPE_KEYPAD;
    indev_drv2.read_cb = keypad_read;
    indev_keypad = lv_indev_drv_register(&indev_drv2);

    /* 初始化编码器 */
    encoder_init();

    /* 注册编码器输入设备 */
    lv_indev_drv_init(&indev_drv3);
    indev_drv3.type = LV_INDEV_TYPE_ENCODER;
    indev_drv3.read_cb = encoder_read;
    indev_encoder = lv_indev_drv_register(&indev_drv3);
}

需要注意的是,键盘和编码器需要绑定到对应的group,才能对group里的控件进行响应。

	g = lv_group_create();					//创建组
	lv_group_set_default(g);				//设置当前组为默认
	lv_indev_set_group(indev_encoder, g);	//设置当前组的输入设备为编码器

对于触摸屏来说,需要在touchpad_init()函数中通过iic完成对触摸芯片的初始化,在touchpad_read()函数中判断触摸状态读取触摸坐标

static void touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
{
    static lv_coord_t last_x = 0;
    static lv_coord_t last_y = 0;

    /* 保存按下的坐标和状态 */
    if(touchpad_is_pressed())
    {
        touchpad_get_xy(&last_x, &last_y);			//获取触摸坐标点
        data->state = LV_INDEV_STATE_PR;			//触摸屏按下
    } 
    else
        data->state = LV_INDEV_STATE_REL;			//触摸屏松开

    /* 设置最后按下的坐标 */
    data->point.x = last_x;
    data->point.y = last_y;
}

键盘输入设备可以是普通按键,也可以是红外遥控键盘,只要能得到不同的键值就行。键盘输入设备的初始化keypad_init()主要对IO口进行初始化操作,通过keypad_read()查询按键状态以及当前键值。

static void keypad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
{
    static uint32_t last_key = 0;

    /* 获取按键是否被按下,并保存键值 */
    uint32_t act_key = keypad_get_key();
    if(act_key != 0) 
    {
        data->state = LV_INDEV_STATE_PR;		//按键按下
        /* 将键值转换成 LVGL 的事件控制字符 */
        switch(act_key) 						//键值不为0,说明有按键按下
        {				
			case 21:
				act_key = LV_KEY_DOWN;
				break;
			case 64:
				act_key = LV_KEY_ENTER;
				break;
			case 67:
				act_key = LV_KEY_NEXT;
				break;
			case 68:
				act_key = LV_KEY_PREV;
				break;
			case 70:
				act_key = LV_KEY_UP;
				break;
			default:
				break;		
        }
        last_key = act_key;
    } 
    else 
        data->state = LV_INDEV_STATE_REL;		//按键释放

    data->key = last_key;
}

编码器由于既有旋钮又有按钮,故相比键盘输入设备多了读取旋钮状态的部分代码。

static void encoder_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
{
	static uint32_t last_key = 0;
	uint32_t act_key = key_scan(0);			//读取键值
	int8_t adc_num = adc_get_number();		//读取编码器增量,这里用adc采样分段量化进行模拟
    if(act_key != 0) 						//按键按下
    {
        switch(act_key) 
        {
            case 4:							
                act_key = LV_KEY_ENTER;				//enter键
                encoder_state = LV_INDEV_STATE_PR;    //按钮按下,触发相应的输入事件
                break;
            case 1:
                act_key = LV_KEY_LEFT;				//left键
                encoder_diff = -1;					//通过按键触发使编码器增量-1
                encoder_state = LV_INDEV_STATE_REL;	//按钮未按下(实际上已按下但是无需响应)
                break;
            case 5:
                act_key = LV_KEY_RIGHT;				//right键    
                encoder_diff = 1;					//通过按键触发使编码器增量1
                encoder_state = LV_INDEV_STATE_REL;	//按钮未按下(实际上已按下但是无需响应)
                break;
            default:
            	break;
        }
        last_key = act_key;
    }
    else if(adc_num != 0)					//编码器转动
	{
		encoder_diff = adc_num;				//增量为正会向下切换控件,增量为负会向上切换控件
     	encoder_state = LV_INDEV_STATE_REL;
	}
    else									//既无按键按下,也无编码器增量
    {
        encoder_diff = 0;
        encoder_state = LV_INDEV_STATE_REL;
    }
    data->key = last_key;					//编码器键值
    data->enc_diff = encoder_diff;			//编码器增量
    data->state = encoder_state;			//编码器触发状态
    encoder_diff=0;							//将增量置为0,否则会一直触发
}

adc模拟编码器增量的代码如下

uint32_t adc_value;

int8_t adc_get_number(void)
{
	int8_t ret =0;
	
	adc_value =adc_get_result(1);			//调节电位器,获取不同的ADC采样值

	if(adc_value < 400)
		adc_number = 1;
	else if(adc_value > 800 && adc_value < 1200)
		adc_number = 2;
	else if(adc_value > 1600 && adc_value < 2000)
		adc_number = 3;
	else if(adc_value > 2400 && adc_value < 2800)
		adc_number = 4;
	else if(adc_value > 3200 && adc_value < 3600)
		adc_number = 5;
	if(adc_number > adc_number_prev)
		ret = 1;
	else if(adc_number < adc_number_prev)
		ret = -1;
	adc_number_prev = adc_number;
	
	return ret;
}
  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
你可以使用LVGL库来实现鼠标输入设备的支持。LVGL提供了一个继承自输入设备接口的鼠标输入设备驱动程序。你可以在LVGL的文档中找到关于鼠标输入设备的详细信息和示例代码。以下是一个简单的示例,展示了如何使用LVGL来处理鼠标输入: ```c #include "lvgl/lvgl.h" // 鼠标输入设备事件回调函数 bool mouse_event_cb(lv_indev_drv_t * drv, lv_event_t event) { if (event == LV_EVENT_PRESSED) { // 处理鼠标按下事件 } else if (event == LV_EVENT_RELEASED) { // 处理鼠标释放事件 } else if (event == LV_EVENT_SHORT_CLICKED) { // 处理鼠标短按事件 } else if (event == LV_EVENT_LONG_PRESSED) { // 处理鼠标长按事件 } // 返回true表示事件已经处理,返回false表示事件未处理 return true; } int main() { // 初始化LVGL库 lv_init(); // 初始化显示设备、鼠标输入设备等 lv_disp_drv_t disp_drv; lv_disp_drv_init(&disp_drv); // 设置显示设备相关参数... lv_indev_drv_t indev_drv; lv_indev_drv_init(&indev_drv); // 设置鼠标输入设备相关参数... indev_drv.read_cb = mouse_event_cb; // 注册鼠标输入设备 lv_indev_t * mouse_indev = lv_indev_drv_register(&indev_drv); // 创建一个窗口 lv_obj_t * win = lv_win_create(lv_scr_act()); // 设置窗口相关参数... // 设置窗口的输入设备为鼠标输入设备 lv_win_set_click(win, mouse_indev); while (1) { // 处理LVGL库的任务 lv_task_handler(); } } ``` 该示例演示了如何初始化LVGL库、注册鼠标输入设备并将其与窗口关联。你可以根据自己的需要在回调函数中处理鼠标事件。请注意,上述示例只是基本的框架,你需要根据实际情况进行适当的修改和扩展。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

chvngzhvng

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

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

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

打赏作者

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

抵扣说明:

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

余额充值