RT-Thread 学习笔记(十四)--- 开启基于RTGUI的LCD显示功能(4)<demo组件的按键响应和焦点支持>

【RT-Thread】——GUI服务器 RT-Thread/GUI是一个图形用户界面(Graphic  ) 阅读详情

软件环境:Win7,Keil MDK 4.72a, IAR EWARM 7.2, GCC 4.2,Python 2.7 ,SCons 2.3.2

硬件环境:Armfly STM32F103ZE-EK v3.0开发板

参考文章:RT-Thread编程指南

RT-Thread_1.2.0+lwip+rtgui0.8.0 移植心得

RT-Thread RTOS组件:RTGUI教程 Hello World

前面基本解决了触摸屏的驱动和校正问题,但是还有些问题,比如按键响应,触摸屏校正数据的存储,打开多个Demo组件时会有问题存在等,接下来就要研究这些问题。

【1】按键响应

(1)查看原理图硬件接口电路,如下图:

从原理图可以看到,一个五向摇杆有五个按键,已经能够满足LCD显示屏上操作的需要。可以根据原理图上的标出的硬件接口修改RTGUI底层硬件接口代码。

(2)对于RT-Thread来讲,对于底层硬件,需要将按键信息包装成事件信息传递个GUI server处理,然后server发给LCD 作为响应。所以需要新建一个文件key.c,处做这件事情。参考realtouch和魔笛F1开发板的按键例程代码修改而得到key.c的代码如下:

<pre name="code" class="cpp">#include <rtthread.h>
#include <board.h>

#include <rtgui/event.h>
#include <rtgui/rtgui_server.h>

//常规按键处理使用
#define DEBOUNCE_SHORT_TIME 	3   // 轻触按键消抖时间5(单位:20毫秒)
#define DEBOUNCE_LONG_TIME  	5  	// 长按键时间DEBOUNCE_COUT_FIRST+DEBOUNCE_COUT_INTERVAL*DEBOUNCE_LONG_TIME(单位:10毫秒)
#define DEBOUNCE_COUT_FIRST 	500//50 // 连按键间隔时间100(单位:20毫秒)
#define DEBOUNCE_COUT_INTERVAL 	10  // 连按键间隔时间50(单位:20毫秒)

//特殊按键处理使用
#define C_RELASE_COUT			3
#define C_SHORT_COUT			3		//3*20ms
#define C_SPECIAL_LONG_COUT		60  //60*20ms

//按键标志
#define C_FLAG_SHORT			0x00000001
#define C_FLAG_COUNT			0x00000002
#define C_FLAG_LONG				0x00000004
#define C_FLAG_RELASE			0x00000008

//按键键值
#define  C_UP_KEY 				0x01
#define  C_DOWN_KEY 			0x02
#define  C_LEFT_KEY 			0x04
#define  C_RIGHT_KEY 			0x08
#define  C_ENTER_KEY 			0x10
#define  C_SPECIAL_KEY 		C_ENTER_KEY

/*enter键长按 我们定义为home键*/
#define  C_HOME_KEY 			C_SPECIAL_KEY+0x44

/*
KEY_UP    PG15
KEY_DOWN  PD3
KEY_LEFT  PG14
KEY_RIGHT PG13
KEY_ENTER PG7
*/

#define KEY_UP_GETVALUE()     GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_15)//PG15
#define KEY_DOWN_GETVALUE()   GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_3)//PD3
#define KEY_LEFT_GETVALUE()   GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_14)//PG14
#define KEY_RIGHT_GETVALUE()  GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_13)//PG13
#define KEY_ENTER_GETVALUE()  GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_7)//PG7

/* 使用面向对象的方式,将按键所用到的所有元素进行打包 */
struct rtgui_key
{
    rt_timer_t poll_timer;
    struct rtgui_event_kbd kbd_event;

    rt_uint32_t key_last;
    rt_uint32_t key_current;
    //检测到的按键值
    rt_uint32_t key_get;
    //常规按键使用
    rt_uint32_t key_debounce_count;
    rt_uint32_t key_long_count;
    //特殊按键使用
    rt_uint32_t key_special_count;
    rt_uint32_t key_relase_count;
    //按键标志
    rt_uint32_t key_flag;

};

static struct rtgui_key *key;


static void GPIO_Configuration(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG|RCC_APB2Periph_GPIOD,ENABLE);

    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_Pin   = (GPIO_Pin_15|GPIO_Pin_14|GPIO_Pin_13|GPIO_Pin_7);
    GPIO_Init(GPIOG, &GPIO_InitStructure);
	
    GPIO_InitStructure.GPIO_Pin   = (GPIO_Pin_3);
    GPIO_Init(GPIOD, &GPIO_InitStructure);

}


static void key_timeout(void* parameter)
{
		//按键未按下时,每位读入的值为1
    key->key_current = KEY_UP_GETVALUE();
    key->key_current |= KEY_DOWN_GETVALUE()<<1;
    key->key_current |= KEY_LEFT_GETVALUE()<<2;
    key->key_current |= KEY_RIGHT_GETVALUE()<<3;
    key->key_current |= KEY_ENTER_GETVALUE()<<4;

    key->key_current =~ (key->key_current);//取反
    key->key_current &= 0x0000001f; //过滤掉低五位以外的值,因为只有五个按键


    key->key_flag &= ~C_FLAG_SHORT;
    key->key_flag &= ~C_FLAG_COUNT;
    key->key_flag &= ~C_FLAG_LONG;
    key->key_get = 0;

//
    /*对于有长按和短按的特殊键做处理*/
    if ((key->key_flag)&C_FLAG_RELASE)
    {   //检查放键
        if (key->key_current == 0)
        {
            if ((++(key->key_relase_count)) >= C_RELASE_COUT)
            {   //按键已经放开
                key->key_relase_count = 0;
                key->key_flag &= ~C_FLAG_RELASE;
            }
        }
        else
        {
            key->key_relase_count = 0;
        }
    }
    else
    {   //检查按键
        if (key->key_current == C_SPECIAL_KEY)
        {
            if ((++(key->key_special_count)) >= C_SPECIAL_LONG_COUT)
            {
                key->key_special_count = 0;

                key->key_get = C_HOME_KEY;
                key->key_flag |= C_FLAG_LONG;		//特殊键 长按键按下
                key->key_flag |= C_FLAG_RELASE;	//按下后要求检测放键
            }
        }
        else
        {   //放开键后才检测短按
            if ((key->key_special_count >= C_SHORT_COUT) && (key->key_special_count <C_SHORT_COUT+30))
            {
                key->key_get = C_SPECIAL_KEY;
                key->key_flag |= C_FLAG_SHORT;	//特殊键 短按键按下
            }
            key->key_special_count = 0;
        }
    }

// 普通按键处理
    if((key->key_current == 0)||(key->key_current != key->key_last)|| (key->key_current == C_SPECIAL_KEY))
    {
        key->key_debounce_count = 0;			//第一次
        key->key_long_count = 0;	        //清除长按键计数器
    }
    else
    {
        if(++(key->key_debounce_count) == DEBOUNCE_SHORT_TIME)
        {
            key->key_get = key->key_current;
            key->key_flag |= C_FLAG_SHORT;	//短按键按下
        }
        if(key->key_debounce_count == DEBOUNCE_COUT_FIRST + DEBOUNCE_COUT_INTERVAL)
        {
            key->key_get = key->key_current;
            key->key_flag |= C_FLAG_COUNT;	//连按键 按键按下
            key->key_debounce_count = DEBOUNCE_COUT_FIRST;
            ++(key->key_long_count);
        }

        if(key->key_long_count == DEBOUNCE_LONG_TIME)
        {
            key->key_get = key->key_current;
            key->key_flag |= C_FLAG_LONG;	//短按键按下
            key->key_long_count=DEBOUNCE_LONG_TIME+1;
        }
    }

    key->key_last = key->key_current;				// 保存本次键值


    /* 检测到按键后,向系统上报键值 */
    key->kbd_event.key = RTGUIK_UNKNOWN;
    key->kbd_event.type = RTGUI_KEYDOWN;

    if (key->key_get)
    {
        rt_kprintf("key = %x \n",key->key_get);
        if (((key->key_get)==C_UP_KEY) && ((key->key_flag) & C_FLAG_SHORT))
            key->kbd_event.key  = RTGUIK_UP;

        if (((key->key_get)==C_DOWN_KEY) && ((key->key_flag) & C_FLAG_SHORT))
            key->kbd_event.key  = RTGUIK_DOWN;

        if (((key->key_get)==C_LEFT_KEY) && ((key->key_flag) & C_FLAG_SHORT))
            key->kbd_event.key  = RTGUIK_LEFT;

        if (((key->key_get)==C_RIGHT_KEY) && ((key->key_flag) & C_FLAG_SHORT))
            key->kbd_event.key  = RTGUIK_RIGHT;

        //if (((key->key_get)==C_STOP_KEY) && ((key->key_flag) & C_FLAG_SHORT))
        //	key->kbd_event.key  = RTGUIK_UP;
        //if (((key->key_get)==C_MENU_KEY) && ((key->key_flag) & C_FLAG_SHORT))
        //	key->kbd_event.key  = RTGUIK_UP;
        if ((key->key_get)==C_ENTER_KEY)
            key->kbd_event.key  = RTGUIK_RETURN;

        if ((key->key_get)==C_HOME_KEY)
            key->kbd_event.key  = RTGUIK_HOME;
    }

    if (key->kbd_event.key != RTGUIK_UNKNOWN)
    {
        /* 先上报按键按下*/
        rtgui_server_post_event(&(key->kbd_event.parent), sizeof(key->kbd_event));

        /* delay to post up event */
        rt_thread_delay(2);

        /* 再上报按键松开,完成一个从按下到松开的组合*/
        key->kbd_event.type = RTGUI_KEYUP;
        rtgui_server_post_event(&(key->kbd_event.parent), sizeof(key->kbd_event));
    }
}



int rt_hw_key_init(void)
{
    GPIO_Configuration();

    key = (struct rtgui_key*)rt_malloc (sizeof(struct rtgui_key));
    if (key == RT_NULL)
        return -1; /* no memory yet */

    /* init keyboard event */
    RTGUI_EVENT_KBD_INIT(&(key->kbd_event));
    key->kbd_event.wid = RT_NULL;
    key->kbd_event.mod  = RTGUI_KMOD_NONE;
    key->kbd_event.unicode = 0;

    key->key_last = 0;
    key->key_current = 0;
    key->key_get = 0;
    key->key_debounce_count = 0;
    key->key_long_count = 0;
    key->key_special_count = 0;
    key->key_relase_count = 0;
    key->key_flag = 0;

    /* create 1/50=20ms  timer */
    key->poll_timer = rt_timer_create("key", key_timeout, RT_NULL,
                                      RT_TICK_PER_SECOND/50, RT_TIMER_FLAG_PERIODIC);

    /* 启动定时器 */
    if (key->poll_timer != RT_NULL)
        rt_timer_start(key->poll_timer);

    return 0;
}

INIT_DEVICE_EXPORT(rt_hw_key_init);

 

需要说明的是,key.c是启用了五向摇杆的五个按键,而在demo_application.c中,使用了RTGUIK_LEFT和RTGUI_RIGHT两个方向的按键,代码如下:

static rt_bool_t demo_handle_key(struct rtgui_object *object, struct rtgui_event *event)
{
    struct rtgui_event_kbd *ekbd = (struct rtgui_event_kbd *)event;

    if (ekbd->type == RTGUI_KEYUP)
    {
        if (ekbd->key == RTGUIK_RIGHT)
        {
            demo_view_next(RT_NULL, RT_NULL);
            return RT_TRUE;
        }
        else if (ekbd->key == RTGUIK_LEFT)
        {
            demo_view_prev(RT_NULL, RT_NULL);
            return RT_TRUE;
        }
    }
    return RT_TRUE;
}

(3)把key.c添加到drivers目录下以后,还需要修改下drivers目录下Sconscript脚本,打开脚本文件定位到30行附近,加入如下代码:

# add RTGUI drvers.
if GetDepend('RT_USING_RTGUI'):
    src += ['key.c']
    if rtconfig.RT_USING_LCD_TYPE == 'ILI932X' :
        src += ['ili_lcd_general.c']
    elif rtconfig.RT_USING_LCD_TYPE == 'SSD1289':
        src += ['ssd1289.c']
    elif rtconfig.RT_USING_LCD_TYPE == 'OTM4001A':
        src += ['otm4001a.c']

CPPPATH = [cwd]
别忘了,书写格式按四个空格或者tab键递进,否则会出现执行脚本时会出现错误。然后保存。

(4)在demo_application.c中先加入三个demo文件,代码如下:

/*    demo_view_benchmark();

    demo_view_dc();
#ifdef RTGUI_USING_TTF
    demo_view_ttf();
#endif

#ifndef RTGUI_USING_SMALL_SIZE
    demo_view_dc_buffer();
#endif
    demo_view_animation();
#ifndef RTGUI_USING_SMALL_SIZE
    demo_view_buffer_animation();
    demo_view_instrument_panel();
#endif
    demo_view_window();
*/    demo_view_label();
    demo_view_button();
    demo_view_checkbox();
/*    demo_view_progressbar();
    demo_view_scrollbar();
    demo_view_radiobox();
    demo_view_textbox();
    demo_view_listbox();
    demo_view_menu();
    demo_view_listctrl();
    demo_view_combobox();
    demo_view_slider();
    demo_view_notebook();
    demo_view_mywidget();
    demo_plot();
	demo_view_digtube();
*/

然后保存并scons编译,下载,复位后,五向摇杆向右摇下,会切换到下一个页面,向左摇下,会切换到上一个页面,因为我们的demo页面还没打开完,左右按两下是可以看到效果的。

【2】屏幕中文支持

(1)在rtconfig.h文件中打开RTGUI_USING_FONTHZ向关编译选项,定位到179行附近,代码修改如下:

#define RTGUI_USING_FONT16
/* support Chinese font */
#define RTGUI_USING_FONTHZ
/* use DFS as file interface */
#define RTGUI_USING_DFS_FILERW
/* use font file as Chinese font */
#define RTGUI_USING_HZ_FILE
/* use Chinese bitmap font */
#define RTGUI_USING_HZ_BMP
/* use small size in RTGUI */
#define RTGUI_USING_SMALL_SIZE

(2)修改rtgui_system_server_init()的初始化调用

如果按默认调用,RTGUI在打开上面的RTGUI_USING_FONTHZ选项后,显示中文时会出现乱码。

<1>打开rtgui/common/rtgui_system.c文件,定位到58行附近,注释掉组件加载的宏,代码修改如下:

int rtgui_system_server_init(void)
{
    rt_mutex_init(&_screen_lock, "screen", RT_IPC_FLAG_FIFO);

    /* the graphic device driver must be set before initialization */
    RT_ASSERT(rtgui_graphic_driver_get_default() != RT_NULL);

    /* init image */
    rtgui_system_image_init();
    /* init font */
    rtgui_font_system_init();

    /* set the rect of main window to full screen */
    rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(), &_mainwin_rect);

    /* init rtgui server */
    rtgui_topwin_init();
    rtgui_server_init();

	/* use driver rect for main window */
	rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(), &_mainwin_rect);

    /* init theme */
    rtgui_system_theme_init();
    return 0;
}
//INIT_APP_EXPORT(rtgui_system_server_init);


<2>在application.c的RTGUI初始化部分加入rtgui_system_server_init()调用,定位到83行附近,确认代码修改和下面一致:

void rt_init_thread_entry(void* parameter)
{
	
		/* initialization RT-Thread Components */
		rt_components_init();
		
#if defined(RT_USING_DFS) && defined(RT_USING_DFS_ELMFAT)
		/* mount SPI flash as root directory */ 
    if (dfs_mount("flash0", "/", "elm", 0, 0) == 0)
    {      
				rt_kprintf("flash0 mount to /.\n");				
    }
    else
        rt_kprintf("flash0 mount to / failed.\n");
		/* mount SD Card as /dev/sd directory */ 
    if (dfs_mount("sd0", "/dev", "elm", 0, 0) == 0)
    {
        rt_kprintf("sd0 mount to /dev.\n");
    }
    else		
        rt_kprintf("sd0 mount to /dev failed.\n");	
#endif /* RT_USING_DFS */		
				       
#ifdef RT_USING_RTGUI
		{
				rt_device_t lcd; 	
				/* find lcd device */
				lcd = rt_device_find("lcd");
				/* set lcd device as rtgui graphic driver */
				rtgui_graphic_set_device(lcd);
				rtgui_system_server_init();
				gui_application_init();
#ifdef RTGUI_USING_CALIBRATION
				calibration_set_restore(calibration_restore);//initialize the pointer to load user data
				calibration_set_after(calibration_store); //initialize the poiter to save user data
				calibration_init();		
#endif /* RTGUI_USING_CALIBRATION */	
		}
#endif /* RT_USING_RTGUI */

需要强调下,rt_components_init()需要在开始部分调用,因为硬件初始化都是在这个函数中进行的。

(3)确认各硬件初始化代码是否加入了组件调用导入的宏INIT_DEVICE_EXPORT(xxx_xxx_init);

<1>otm4001a.c文件的int rt_hw_lcd_init(void)的后面,代码如下:

int rt_hw_lcd_init(void)
{
	
	/* register lcd device */
	_lcd_device.type  = RT_Device_Class_Graphic;
	_lcd_device.init  = lcd_init;
	_lcd_device.open  = lcd_open;
	_lcd_device.close = lcd_close;
	_lcd_device.control = lcd_control;
	_lcd_device.read  = RT_NULL;
	_lcd_device.write = RT_NULL;

	_lcd_device.user_data = &otm4001_ops;
    
  otm4001_hw_init();

	lcd_set_backlight(200);
    /* register graphic device driver */
	rt_device_register(&_lcd_device, "lcd",
	RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);
	return 0;
}
INIT_DEVICE_EXPORT(rt_hw_lcd_init);

<2>touch_driver.c的468行附近在int rtgui_touch_hw_init(void)的末尾处,代码如下:

    /* register touch device to RT-Thread */
    rt_device_register(&(touch->parent), "touch", RT_DEVICE_FLAG_RDWR);
		return 0;
}
INIT_DEVICE_EXPORT(rtgui_touch_hw_init);

<3>在key.c文件的262行附近的int rt_hw_key_init(void)的末尾处,代码如下:

    /* startup the timer */
    if (key->poll_timer != RT_NULL)
        rt_timer_start(key->poll_timer);

    return 0;
}
INIT_DEVICE_EXPORT(rt_hw_key_init);

(4)加载汉字库,可参考下面步骤进行,如果文件系统已经挂载,下面步骤2的前面两步可不必进行。

1. 准备资源文件:
把sdcard目录下所有目录复制到SD卡根目录,
然后把SD卡插到开发板上面备用。
2. finsh执行:
2.1 格式化flash,然后重新启动。
finsh>>mkfs("elm", "flash0")
2.2 创建目录用于挂载SD卡及资源文件目录,因需要挂载SD卡,所以最后需要重新启动。
finsh>>mkdir("/dev")
finsh>>mkdir("/resource")
2.3 准备就绪后,启动会显示根目录和SD卡都挂载成功,然后就可以开始复制资源文件了。
finsh>>copy("/dev/resource/gbk2uni.tbl", "/resource/gbk2uni.tbl")
finsh>>copy("/dev/resource/uni2gbk.tbl", "/resource/uni2gbk.tbl")
finsh>>copy("/dev/resource/hzk12.fnt", "/resource/hzk12.fnt")
finsh>>copy("/dev/resource/hzk16.fnt", "/resource/hzk16.fnt")
2.4 所有资源文件复制完成后,重启动即可
(5)如果上面修改完成并保存了,执行scons编译,下载的开发板上后可以看到之前的乱码变成中文了。

【3】焦点支持

未完,待续。。。

基于RT-thread使用STM32F407驱动LCD屏幕 不管哪款LCD,都是同理的,我这款LCD是用的IIC通信。 然后本工程使用普通IO口模拟IIC时序进行通信 十四、在applications文件下新建system_deal文件夹,再在system_deal文件下新建system_deal.c和system_deal.h文件 十八、在system_deal.h中这么写 十九、system_config.h中这么写 二十、在applications文件夹下新建screen_deal文件夹,再在screen_deal文件夹下新建lcd_font.c、lc 阅读详情

相关推荐

RT-Thread学习笔记系列之littlevgl GUI(3)

文章目录前言一、资源介绍二、配置过程添加littlevgl2rtt软件包分析过程总结 前言 随着物联网、智能家居、智能控制等行业的极速发展,小而美的且反应迅速且成本低的,模块化,定制化的嵌入式系统的需求越来越大,其中降低使用要求,提高用户体验,人机交互是一个非常好的方法,所以本文记录的是调试rtthread+lcd+littlevgl GUI的记录及流程 一、资源介绍 硬件是自行画的PCB板,资源如下 MCU:STM32F407ZGT6 LCD:3.2寸320*240分辨率,驱动芯片:ILI9341。 引

weixin_39137443的博客 5394

RTGUI粗讲(个人见解篇之一:基本架构)

声明:因为个人发现在对架构理解上与RTGUI开发人员存在很在分歧,因此该系列所有内容仅限个人见解,与RTGUI原有含义完全无关。 由于个人属于什么都不懂,什么都不怎么会的菜鸟,所以希望在看这些小东东的大侠海涵,对的地方你就看把,不对的地方,你也将就着看吧。 这是这个讲解系列第一篇,一般都不会写得很好,因为思路会很不清晰,当然,也不会保证会有下一篇,因为个人时间真的有限,只能是利用晚上时

xuzhenglim的专栏 5598

RT-Thread Radio开发套件深度解析:从硬件选型到内核调试

实时操作系统(RTOS)是嵌入式系统的核心软件平台,它通过任务调度、内存管理和进程间通信等机制,为资源受限的微控制器提供多任务并发执行能力。其技术价值在于能够高效管理硬件资源,确保关键任务的实时响应,从而广泛应用于物联网设备、工业控制和消费电子等领域。本文以RT-Thread Radio网络播放器开发套件为具体案例,深入剖析了其基于STM32F103的硬件架构设计,包括网络、音频、存储等关键外设的协同原理。同时,重点探讨了如何利用RT-Thread内置的Finsh Shell工具进行动态系统状态诊断和实时调

weixin_30947043的博客 403

RT-Thread 学习笔记(十一)--- 开启基于RTGUI的LCD显示功能(1)<LCD驱动接口移植>

软件环境:Win7,Keil MDK 4.72a, IAR EWARM 7.2, GCC 4.2,Python 2.7 ,SCons 2.3.2 硬件环境:Armfly STM32F103ZE-EK v3.0开发板 参考文章:RT-Thread编程指南 RT-Thread_1.2.0+lwip+rtgui0.8.0 移植心得 RT-Thread RTOS组件:RTGUI

aping_cs_dn的专栏 1万+

STM32与RTGUI图形界面集成实践指南

STM32微控制器系列,由意法半导体(STMicroelectronics)生产,是基于ARM Cortex-M内核的广泛使用的32位微控制器。它以其高性能、低功耗、丰富的外设和灵活的配置选项而闻名,在工业控制、医疗设备、消费电子产品及物联网等领域有着广泛应用。市场上有许多基于STM32系列的开发板,如Nucleo、Discovery和Eval板,它们为开发者提供了方便的起始平台。这些开发板通常带有丰富的接口和功能,用户可以通过它们快速评估和开发STM32微控制器的应用。

weixin_42298778的博客 902

rtgui.rar_ RTGUI_RTGUI

国产的GUI,概念是全新的,很有研究价值

RT-Thread 柿饼GUI入门课程学习总结

前言 11月中旬的时候,我在RT-Thread的微信公众号推文看到了柿饼UI的入门课程活动。其实也不是第一次看到这个GUI的介绍,但是用Js开发的方式有点吸引我。 https://mp.weixin.qq.com/s/bBMuZ1qmtnI4cH86DR8enw 入门课程一个月左右的时间,一共5次作业,下面是部分我个人比较喜欢的作品: 第二周的基础题: 附加题: 最后一次是在柿饼派上运行的汽车模拟汽车仪表盘: ...

NameisBoy的博客 6719

伺服电机入门01

编码器输出 旋转信号 , 接收端: 使用ADC 捕捉旋转信号 ,转成数字信号,驱动器得到数字处理, 因为信号量是模拟信号, mcu mpu 等芯片通常内部处理是数字,通过adc 得到数字cpu 才能识别 传输过来的pos 等信息。IPM 芯片示例, IRAM256A 这个芯片已经停产,有换新的,,下面示例来自stmbl 高功率方案,4 步进电机 有全步控制,半步控制 ,微步控制,FOC控制,步进电机也是可以做伺服系统的。以下面几种信号是可以细分,也就是通过细分增加编码器的分辨率,

qq_25160559的博客 970

RTGUI粗讲(个人见解篇之二、RTGUI事件简述)

这是本系列第二篇。本来是准备定WIDGET的,不过后来想想,EVENT还是需要先在WIDGET之前简单讲一下的,毕竟在RTGUI里面,事件是一个比较独立的东西,它派生的基类就是RTGUI EVETN,与widget无关,需要先单独做一个了解,再到后面讲如何搭建自己的widget的时候才会清晰一些。然而我也实在不知道该怎么讲这个,一个是毫无经验,另一个则是不知从何讲起,估计还是会讲的一头雾水吧。

xuzhenglim的专栏 3417

LVGL8.x 实体按键与Keypad驱动的无缝对接实战

本文详细解析了LVGL8.x中实体按键与Keypad驱动的两种对接方案:坐标映射的Button方式与事件驱动的Keypad方式。重点阐述了如何模块化裁剪lv_port_indev.c模板文件,并深入讲解了Keypad驱动与Group焦点管理系统的核心协作机制,为无触摸屏的嵌入式设备提供流畅的UI交互解决方案。

weixin_29164497的博客 448

Cadence公司的数字IC设计工具:综合工具(Genus)——(2)

介绍Cadence公司的数字IC设计工具Genus

qq_42922513的博客 1944

RTGUI粗讲(个人见解篇之三、RTGUI WIDGET (2))

又要开始码字了。 这次是接上次的内容开始讲下object,本来还打算说下事件,不过感觉还是没法怎么说,这种涉及具体用法的东西,只能是放在实用篇尝试在确实应用中找。由于是续篇,多余话就不说了。 首先看下下面这个关于RTGUI WIDGET 的基本数据结构   struct rtgui_widget   {    /* inherit from rtgui_object */

xuzhenglim的专栏 2128

1.5 RAG技术栈全景图:LangChain vs LlamaIndex深度对比,选错框架后悔3年,一文帮你选对

摘要:LangChain与LlamaIndex框架深度对比 本文全面对比了RAG领域两大主流框架LangChain和LlamaIndex。LangChain是通用AI应用框架,具有模块化设计和丰富生态;LlamaIndex专为RAG优化,提供开箱即用解决方案。功能对比显示,LangChain在文档加载和Agent支持方面更强,而LlamaIndex在检索策略、向量存储和多模态处理上表现更优。代码示例展示了二者实现RAG的不同方式:LangChain需要更多配置但灵活性高,LlamaIndex则提供更简洁的A

yonggeit的博客 3239

RT-Thread Studio上移植GUI-Guider-1.4开发LVGL8.2

这时候我们的工程没有GUI函数进行调用了,我们需要开始自己设计,所以我们打开GUI-Guider-1.4来进行对LVGL8.2的GUI设计,本篇主要讲解如何移植,具体GUI-Guider-1.4的使用方法大家还是上网自己学习。不同版本的GUI Guider可以创建的LVGL版本不一样,按照自己移植的LVGL来选择安装GUI Guider软件即可。由于LVGL的环境是现成的,所以我们就只需要将自带的demo给关闭掉就行了,这样就可以省下很多空间来进行设计。开始最重要的环节,设置我们的屏幕参数了。

qq_45902737的博客 2195

Halcon学习之一维测量(3)

带定位器的测量。首先看一下“定位”是什么意思?回答:比如我们测量一个芯片,这时候我们设置一个测量矩形,来沿着测量目标进行测量。但是下一张当芯片的位置发生变化时,测量矩形的位置就不对了,就不是沿着测量目标了。这样就不对了!芯片在转,测量矩形也要跟着一起转才行。这个时候就需要“定位”来起作用了!定位之后得到这个芯片的旋转角度之后,测量矩形可以跟着这个角度转。这就是“定位”+“测量”,这是我们工业视觉常用的一个手法,在Halcon里面也是有例子展现的。

deep_love1314的博客 788

通信算法之264: DJI O2 协议物理层逆向工程解析

对于 DroneID,标志之间的间隙由循环前缀 (CP) 填充:每个标志末尾的副本附加在相应标志的开头。有了关于确切标志开始的信息,可以使用 FFT 将标志转移到频域 - 来自时域的 1024 个样本导致频域中的 1024 个子载波。使用比特流的解扰和涡轮解码,并将生成的数据映射到如上的DroneID 结构,通过逆向工程在无人机的固件中找到了它。注意到一些无人机(Mavic 2 和更早的 OcuSync 无人机)不发送第一个标志(标志 1),这导致更短的帧持续时间为 576 µs。//产品型号数字代号。

leegang12的专栏 3947

RT-Thread 学习笔记(十二)--- 开启基于RTGUI的LCD显示功能(2)<编译测试>

软件环境:Win7,Keil MDK 4.72a, IAR EWARM 7.2, GCC 4.2,Python 2.7 ,SCons 2.3.2 硬件环境:Armfly STM32F103ZE-EK v3.0开发板 参考文章:RT-Thread编程指南 RT-Thread_1.2.0+lwip+rtgui0.8.0 移植心得 RT-Thread RTOS组件:RTGUI

aping_cs_dn的专栏 7995

基于Simulink的光伏+储能家庭能源管理系统仿真

本文通过Simulink建模,分析了家庭光伏+储能系统的优化调度问题。针对光伏发电与用电高峰不匹配导致电费节省有限的问题,构建了包含5kW光伏、10kWh电池和6kW负荷的完整模型,设计了无控、规则控制和24小时经济优化三种策略。仿真结果显示,经济优化策略可使日电费降低32%,光伏自用率从45%提升至89%,尤其在晚高峰时段能显著减少高价购电。文章详细介绍了物理层建模、分时电价实现和控制策略设计方法,并探讨了天气预测、V2H等高级扩展功能,为家庭能源智能管理提供了实用解决方案。

xiaoheshang_123的博客 188

RT-Thread学习:在LCD屏幕上操作msh

看了看源码 ,发现finsh输出是通过rt_ktprintf实现的,那我们只需在rt_ktprintf中添加对lvgl中文本区域的刷新即可,需要注意的是由于在上电初始化的过程中需要调用rt_ktprintf,而此时lvgl仍未初始化,故调用lvgl中的函数会导致程序跑飞,应该加一个标志位,判断lvgl是否已经初始化,使得仅在lvgl初始化后调用其函数,防止程序跑飞。,在文本区域事件中调用msh_exec即可执行命令。我们添加两个文本区域,一个作为命令输入。2.实现finsh的输出。1.实现命令行的输入。

u014420595的博客 692

【人工智能】Open WebUI 安装指南 ( 基于Docker下载和使用Open WebUI 、通过本地运行项目源码进行搭建Open WebUI)

Open WebUI 是一个可扩展、功能丰富且用户友好的自托管 WebUI,旨在完全离线操作。它支持各种 LLM 运行程序,包括 Ollama 和 OpenAI 兼容的 API。社区:https://openwebui.com/

奶爸的编程之路,也就一周冷个三天 2万+

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

RTGUI粗讲(个人见解篇之三、RTGUI WIDGET (1))

终于到RTGUI WIDGET篇了。这个应该就比较重要的一部分了,不过可能一次写不完,只能改成多次分开写,而且会写的很不好。(当然有更重要的,就是相关的一些应用举例,后面可能看情况写一下。)   首先谈下什么是RTGUI WIDGET,RTGUI WIDGET其实是一种控件的基本单位,也就是最底层单位,就好比毫米是厘米的底层单位一样。对于我们来说,要控制一个物体,那么前提是这个物体必须具有实体

xuzhenglim的专栏 2193

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

RT-Thread 学习笔记(十三)--- 开启基于RTGUI的LCD显示功能(3)<触屏屏驱动移植和测试>

软件环境:Win7,Keil MDK 4.72a, IAR EWARM 7.2, GCC 4.2,Python 2.7 ,SCons 2.3.2 硬件环境:Armfly STM32F103ZE-EK v3.0开发板 参考文章:RT-Thread编程指南 RT-Thread_1.2.0+lwip+rtgui0.8.0 移植心得 RT-Thread RTOS组件:RTGUI

aping_cs_dn的专栏 1万+

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

RT-Thread 学习笔记(五)—— RTGUI代码解读

---恢复内容开始--- RT-Thread 版本:2.1.0 RTGUI相关代码解读,仅为自己学习记录,若有错误之处,请告知maoxudong0813@163.com,不胜感激! GUI流程: main() ->rtthread_startup(); ->rt_hw_board_init(); ->rt_components_board_init(); ...

weixin_30354675的博客 734

STM32 + RT Thread OS 学习笔记[三]

RTGUI 据说RTGUI是多线程的,因此与RT-Thread OS的耦合度较高,有可能要访问RT-Thread的线程控制块。如果要移植到其它OS,估计难度较大。目前还处于Alpha状态,最终将会包含进RT-Thread中,成为其中的标准组件。 1、  RTGUI下载 当前,要获取包含RTGUI的源码,需要到SVN库里去拉。 因此,需要先安装SVN客户端。比较简单的就是命令行,当然你也可以

的米-漠石's Blog 1万+

RT-Thread学习--内核基础2

上一篇博客简单介绍了一下实时内核库包含的一些内容:线程调度、时钟管理、内存管理、I/O设备管理、线程间同步、线程间通信,在这篇博客中,继续内核基础的相关学习。 RT-Thread启动流程 rtthread_startup()函数是RT-Thread规定的统一启动入口。一般执行顺序是:系统先从启动文件开始运行,然后进入 RT-Thread 的启动 rtthread_startup() ,最后进入用户入口main(),如下图所示: 在上图中,先从汇编代码startup_xxx.s开始执行,然后进入rtthre

weixin_45865003的博客 2029

RT-Thread: LCD、TFT液晶屏屏驱动框架 U8g2 应用

记录u8g2软件包的使用流程,U8g2图形库是一个用于嵌入式设备的单色图形库,支持多种单色OLED和LCD显示控制器,如SSD1306,ST7920等。U8g2库可以从Arduino IDE的库管理器安装,也可以移植到STM32等平台。U8g2库支持三种绘图模式:全屏缓存模式,页面缓存模式和U8x8字符模式。U8g2库的使用需要选择合适的构造函数,初始化显示器,设置引脚号,编写回调函数和绘图指令。U8g2图形库的优点是可以使用多种字体,支持中文显示,提供丰富的图形程序,如线条,框,圆,位图等。

yutian0606的博客 4097
上一篇: RT_THREAD 使用UART+DMA接收导致数据分包输出问题(自测)
下一篇: 在RT-Thread Studio配置Onchip Flash littlefs文件系统
aping_cs_dn
博客等级 码龄19年 188粉丝 50原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

打赏作者

aping_cs_dn

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

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

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

打赏作者

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

抵扣说明:

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

余额充值