1、 触摸屏校准程序
由于GUI目前在持续变更中,有些函数在新版本中已经不同了,而bsp中的校准程序没有跟进修改,所以无法编译通过。
修正可编译版本:
#include <rtgui/rtgui.h> #include <rtgui/dc.h> #include <rtgui/rtgui_app.h> #include <rtgui/rtgui_system.h> #include <rtgui/widgets/window.h>
#include "touch.h"
// 校准步骤编号 #define CALIBRATION_STEP_LEFTTOP 0 #define CALIBRATION_STEP_RIGHTTOP 1 #define CALIBRATION_STEP_RIGHTBOTTOM 2 #define CALIBRATION_STEP_LEFTBOTTOM 3 #define CALIBRATION_STEP_CENTER 4
// 窗口自定义消息代码 #define TOUCH_WIN_UPDATE 1 #define TOUCH_WIN_CLOSE 2
// 校准点大小 #define CALIBRATION_WIDTH 15 #define CALIBRATION_HEIGHT 15
struct calibration_session { rt_uint8_t step;
struct calibration_data data;
rt_uint16_t width; rt_uint16_t height;
rt_device_t device; rt_thread_t tid;
rtgui_win_t* wid; }; static struct calibration_session* calibration_ptr = RT_NULL;
// 校准回调函数,初化时,设置到touch device 中 static void calibration_data_post(rt_uint16_t x, rt_uint16_t y) { if (calibration_ptr != RT_NULL) { // 取得每次校准点的x, y 坐标值,并与上一次求平均值 switch (calibration_ptr->step) { case CALIBRATION_STEP_LEFTTOP: calibration_ptr->data.min_x = x; calibration_ptr->data.min_y = y; break;
case CALIBRATION_STEP_RIGHTTOP: calibration_ptr->data.max_x = x; calibration_ptr->data.min_y = (calibration_ptr->data.min_y + y)/2; break;
case CALIBRATION_STEP_LEFTBOTTOM: calibration_ptr->data.min_x = (calibration_ptr->data.min_x + x)/2; calibration_ptr->data.max_y = y; break;
case CALIBRATION_STEP_RIGHTBOTTOM: calibration_ptr->data.max_x = (calibration_ptr->data.max_x + x)/2; calibration_ptr->data.max_y = (calibration_ptr->data.max_y + y)/2; break;
case CALIBRATION_STEP_CENTER: /* calibration done */ { rt_uint16_t w, h;
// 创建关闭校准窗口的消息事件 struct rtgui_event_command ecmd; RTGUI_EVENT_COMMAND_INIT(&ecmd); ecmd.wid = calibration_ptr->wid; ecmd.command_id = TOUCH_WIN_CLOSE;
/* calculate calibrated data */ if (calibration_ptr->data.max_x > calibration_ptr->data.min_x) w = calibration_ptr->data.max_x - calibration_ptr->data.min_x; else w = calibration_ptr->data.min_x - calibration_ptr->data.max_x; w = (w/(calibration_ptr->width - 2 * CALIBRATION_WIDTH)) * CALIBRATION_WIDTH;
if (calibration_ptr->data.max_y > calibration_ptr->data.min_y) h = calibration_ptr->data.max_y - calibration_ptr->data.min_y; else h = calibration_ptr->data.min_y - calibration_ptr->data.max_y; h = (h/(calibration_ptr->height - 2 * CALIBRATION_HEIGHT)) * CALIBRATION_HEIGHT;
rt_kprintf("w: %d, h: %d\n", w, h);
if (calibration_ptr->data.max_x > calibration_ptr->data.min_x) { calibration_ptr->data.min_x -= w; calibration_ptr->data.max_x += w; } else { calibration_ptr->data.min_x += w; calibration_ptr->data.max_x -= w; }
if (calibration_ptr->data.max_y > calibration_ptr->data.min_y) { calibration_ptr->data.min_y -= h; calibration_ptr->data.max_y += h; } else { calibration_ptr->data.min_y += h; calibration_ptr->data.max_y -= h; }
rt_kprintf("calibration data: (%d, %d), (%d, %d)\n", calibration_ptr->data.min_x, calibration_ptr->data.max_x, calibration_ptr->data.min_y, calibration_ptr->data.max_y);
// 关闭校准窗口 rtgui_send(calibration_ptr->tid, &ecmd.parent, sizeof(struct rtgui_event_command)); } return; }
calibration_ptr->step ++;
/* post command event */ { // 发送消息,通知窗口画下一个校准点 struct rtgui_event_command ecmd; RTGUI_EVENT_COMMAND_INIT(&ecmd); ecmd.wid = calibration_ptr->wid; ecmd.command_id = TOUCH_WIN_UPDATE;
rtgui_send(calibration_ptr->tid, &ecmd.parent, sizeof(struct rtgui_event_command)); } } }
// 窗口事件处理 // 画校准点,关闭窗口 rt_bool_t calibration_event_handler(struct rtgui_object* widget, struct rtgui_event* event) { switch (event->type) { case RTGUI_EVENT_PAINT: { struct rtgui_dc* dc; struct rtgui_rect rect;
dc = rtgui_dc_begin_drawing((struct rtgui_widget*)widget); if (dc == RT_NULL) break;
/* get rect information */ rtgui_widget_get_rect((struct rtgui_widget*)widget, &rect);
/* clear whole window */ RTGUI_WIDGET_BACKGROUND(widget) = white; rtgui_dc_fill_rect(dc, &rect);
/* reset color */ RTGUI_WIDGET_BACKGROUND(widget) = green; RTGUI_WIDGET_FOREGROUND(widget) = black;
switch (calibration_ptr->step) { case CALIBRATION_STEP_LEFTTOP: rtgui_dc_draw_hline(dc, 0, 2 * CALIBRATION_WIDTH, CALIBRATION_HEIGHT); rtgui_dc_draw_vline(dc, CALIBRATION_WIDTH, 0, 2 * CALIBRATION_HEIGHT); RTGUI_WIDGET_FOREGROUND(widget) = red; rtgui_dc_fill_circle(dc, CALIBRATION_WIDTH, CALIBRATION_HEIGHT, 4); break;
case CALIBRATION_STEP_RIGHTTOP: rtgui_dc_draw_hline(dc, calibration_ptr->width - 2 * CALIBRATION_WIDTH, calibration_ptr->width, CALIBRATION_HEIGHT); rtgui_dc_draw_vline(dc, calibration_ptr->width - CALIBRATION_WIDTH, 0, 2 * CALIBRATION_HEIGHT); RTGUI_WIDGET_FOREGROUND(widget) = red; rtgui_dc_fill_circle(dc, calibration_ptr->width - CALIBRATION_WIDTH, CALIBRATION_HEIGHT, 4); break;
case CALIBRATION_STEP_LEFTBOTTOM: rtgui_dc_draw_hline(dc, 0, 2 * CALIBRATION_WIDTH, calibration_ptr->height - CALIBRATION_HEIGHT); rtgui_dc_draw_vline(dc, CALIBRATION_WIDTH, calibration_ptr->height - 2 * CALIBRATION_HEIGHT, calibration_ptr->height); RTGUI_WIDGET_FOREGROUND(widget) = red; rtgui_dc_fill_circle(dc, CALIBRATION_WIDTH, calibration_ptr->height - CALIBRATION_HEIGHT, 4); break;
case CALIBRATION_STEP_RIGHTBOTTOM: rtgui_dc_draw_hline(dc, calibration_ptr->width - 2 * CALIBRATION_WIDTH, calibration_ptr->width, calibration_ptr->height - CALIBRATION_HEIGHT); rtgui_dc_draw_vline(dc, calibration_ptr->width - CALIBRATION_WIDTH, calibration_ptr->height - 2 * CALIBRATION_HEIGHT, calibration_ptr->height); RTGUI_WIDGET_FOREGROUND(widget) = red; rtgui_dc_fill_circle(dc, calibration_ptr->width - CALIBRATION_WIDTH, calibration_ptr->height - CALIBRATION_HEIGHT, 4); break;
case CALIBRATION_STEP_CENTER: rtgui_dc_draw_hline(dc, calibration_ptr->width/2 - CALIBRATION_WIDTH, calibration_ptr->width/2 + CALIBRATION_WIDTH, calibration_ptr->height/2); rtgui_dc_draw_vline(dc, calibration_ptr->width/2, calibration_ptr->height/2 - CALIBRATION_HEIGHT, calibration_ptr->height/2 + CALIBRATION_HEIGHT); RTGUI_WIDGET_FOREGROUND(widget) = red; rtgui_dc_fill_circle(dc, calibration_ptr->width/2, calibration_ptr->height/2, 4); break; } rtgui_dc_end_drawing(dc); } break;
case RTGUI_EVENT_COMMAND: { struct rtgui_event_command* ecmd = (struct rtgui_event_command*)event;
switch (ecmd->command_id) { case TOUCH_WIN_UPDATE: rtgui_widget_update((struct rtgui_widget*)widget); break; case TOUCH_WIN_CLOSE: rtgui_win_close(RTGUI_WIN(widget)); break; } } return RT_TRUE;
default: rtgui_win_event_handler(widget, event); }
return RT_FALSE; }
void calibration_entry(void* parameter) { struct rtgui_app *application; rtgui_win_t* win; struct rtgui_rect rect;
application = rtgui_app_create(rt_thread_self(), "cali_app"); if (application == RT_NULL) { return; }
// 获取LCD 屏幕分辨率 rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(), &rect);
/* set screen rect */ calibration_ptr->width = rect.x2; calibration_ptr->height = rect.y2;
/* create calibration window */ win = rtgui_win_create(RT_NULL, "calibration", &rect, RTGUI_WIN_STYLE_NO_TITLE | RTGUI_WIN_STYLE_NO_BORDER); if (win == RT_NULL) { rt_kprintf("calibration_win create fail!\r\n"); return; }
calibration_ptr->wid = win; rtgui_object_set_event_handler(RTGUI_OBJECT(win), calibration_event_handler); rtgui_win_show(win, RT_TRUE);
rtgui_app_destroy(application);
/* set calibration data */ rt_device_control(calibration_ptr->device, RT_TOUCH_CALIBRATION_DATA, &calibration_ptr->data);
/* recover to normal */ rt_device_control(calibration_ptr->device, RT_TOUCH_NORMAL, RT_NULL);
/* release memory */ rt_free(calibration_ptr); calibration_ptr = RT_NULL;
}
void calibration_init() { rt_device_t device;
device = rt_device_find("touch"); if (device == RT_NULL) return; /* no this device */
calibration_ptr = (struct calibration_session*)rt_malloc(sizeof(struct calibration_session)); rt_memset(calibration_ptr, 0, sizeof(struct calibration_data)); calibration_ptr->device = device;
// 设置校准回调函数,进入校准状态 rt_device_control(calibration_ptr->device, RT_TOUCH_CALIBRATION, (void*)calibration_data_post);
calibration_ptr->tid = rt_thread_create("cali", calibration_entry, RT_NULL, 2048, 20, 5); if (calibration_ptr->tid != RT_NULL) rt_thread_startup(calibration_ptr->tid); }
#ifdef RT_USING_FINSH #include <finsh.h> void calibration() { calibration_init(); } FINSH_FUNCTION_EXPORT(calibration, perform touch calibration); #endif
|
2、 《贪吃蛇》例程
Step1: 在bsp\simulator\rtgui_demo\snake下有两个.c文件和一个.h文件,添加到stm32f10x项目中。
Step2: 在application.c中rt_init_thread_entry()函数的最后,添加calibration_init();
Step3: 在calibration.c中calibration_entry()函数的最后,添加snake_main(),在触摸屏校准完成后,进入贪吃蛇程序。
Step4: 贪吃蛇程序当前只支持键盘操作,我们还没驱动键盘,要使用触摸屏操作,要添加处理事件(红色部分为添加的代码):
static void snake_mouse_handler(struct rtgui_widget *widget, rtgui_event_t *event) { struct rtgui_event_mouse *emouse; rt_uint32_t x, y;
emouse = (struct rtgui_event_mouse *) event;
if ((emouse->button & RTGUI_MOUSE_BUTTON_UP) == RTGUI_MOUSE_BUTTON_UP) { x = lattice_rect.x1 + (LATTICE_SIZE * second_node.x); y = (lattice_size_y - 1) - second_node.y; y = lattice_rect.y1 + (LATTICE_SIZE * y);
if (run_state == SNAKE_DIR_UP || run_state == SNAKE_DIR_DOWN) { if (emouse->x > x + LATTICE_SIZE) { run_state = SNAKE_DIR_RIGHT; } else { run_state = SNAKE_DIR_LEFT; } } else { if (emouse->y > y + LATTICE_SIZE) { run_state = SNAKE_DIR_DOWN; } else { run_state = SNAKE_DIR_UP; } } } }
static rt_bool_t event_handler(struct rtgui_object *object, rtgui_event_t *event) { struct rtgui_widget *widget = RTGUI_WIDGET(object);
rt_kprintf("event_handler\r\n");
if (event->type == RTGUI_EVENT_PAINT) { rt_kprintf("RTGUI_EVENT_PAINT\r\n"); rtgui_win_event_handler((struct rtgui_object *)object, event); snake_draw(widget); rtgui_timer_start(timer); } else if (event->type == RTGUI_EVENT_SHOW) { rt_kprintf("RTGUI_EVENT_SHOW\r\n"); rtgui_win_event_handler((struct rtgui_object *)object, event); snake_draw(widget); rtgui_timer_start(timer); } else if (event->type == RTGUI_EVENT_HIDE) { rt_kprintf("RTGUI_EVENT_HIDE\r\n"); rtgui_win_event_handler((struct rtgui_object *)object, event); rtgui_timer_stop(timer); } else if (event->type == RTGUI_EVENT_WIN_DEACTIVATE) { rt_kprintf("RTGUI_EVENT_WIN_DEACTIVATE\r\n"); rtgui_win_event_handler((struct rtgui_object *)object, event); rtgui_timer_stop(timer); } else if (event->type == RTGUI_EVENT_KBD) { rtgui_win_event_handler((struct rtgui_object *)object, event); snake_handler(widget, event); } else if (event->type == RTGUI_EVENT_MOUSE_BUTTON) { rtgui_win_event_handler((struct rtgui_object *)object, event); snake_mouse_handler(widget, event); } else { rt_kprintf("event->type:%d\r\n", event->type); |
Step5: 添加文字标题(可选),下图选中代码为新增
Step6: 编译,下载运行