stm32 UCGUI 完美移植
- void LCD_L0_SetPixelIndex(int x, int y, int PixelIndex) LCD画点函数, 用指定颜色填充一个像素
- unsigned int LCD_L0_GetPixelIndex(int x, int y) LCD读取定点颜色函数,读取一个像素点的16位RGB颜色值
- void LCD_L0_FillRect(int x0, int y0, int x1, int y1) 矩形填充函数,用指定颜色填充一个矩形 。这个函数也可以不改 使用UCGUI的函数,用一个一个的像素点填充成一个矩形。也可以在底层驱动根据像素个数直接往GRAM 中写数据,封装成函数,供这个函数调用。速度会快很多。其他的画线画图形函数,也可以同样优化。LCDDriver 下有三个文件, LCDDummy.c 、 LCDNull.c 和LCDWin.c。 这三个都是UCGUI LCD接口模板文件。功能一样,只是移植时修改的细节不一样。我们可以选用其中一个,稍作修改作为接口文件。以LCDDummy.c为例:
#include “LCD_Private.h” / private modul definitions & config /
#include “GUI_Private.h”
#include “GUIDebug.h”
/#if (LCD_CONTROLLER == -1) \
&& (!defined(WIN32) | defined(LCD_SIMCONTROLLER))/ //必须注释,否则不会编译
#include “ili93xx.h” //包含你的LCD驱动函数声明
#if (LCD_CONTROLLER == -1) //这句对应Config/LCDConf.h
……..
……..
void LCD_L0_SetPixelIndex(int x, int y, int PixelIndex) {
POINT_COLOR = PixelIndex; //我的画点函数使用了一个全局变量设定颜色
LCD_DrawPoint(x,y); //画点函数
}
……..
……..
unsigned int LCD_L0_GetPixelIndex(int x, int y) {
return LCD_ReadPoint(x,y); //我的读取像素颜色函数
}
……..
……..
void LCD_L0_FillRect(int x0, int y0, int x1, int y1) {
LCD_Fill(x0,y0,x1,y1,LCD_COLORINDEX); //填充矩形函数
/for (; y0 <= y1; y0++) {
LCD_L0_DrawHLine(x0, y0, x1);
}/
}
#ifndef GUICONF_H
#define GUICONF_H
#define GUI_OS (0) / 操作系统的支持,当用到ucos 时需要打开 Compile with multitasking support /
#define GUI_SUPPORT_TOUCH (1) / 触摸屏的支持 Support a touch screen (req. win-manager) /
#define GUI_SUPPORT_UNICODE (0) / 用汉字库时再打开 Support mixed ASCII/UNICODE strings /
#define GUI_DEFAULT_FONT &GUI_Font6x8 / 定义字体大小 /
#define GUI_ALLOC_SIZE 12500 /分配的动态内存空间 Size of dynamic memory … For WM and memory devices/
/*
*
- Configuration of available packages
*/
#define GUI_WINSUPPORT 1 / 窗口功能支持 要使用指针图标 必须打开 Window manager package available /
#define GUI_SUPPORT_MEMDEV 1 / 内存管理 Memory devices available /
#define GUI_SUPPORT_AA 1 / 抗锯齿功能,打开后可以提高显示效果 Anti aliasing available /
#endif / Avoid multiple inclusion /
#ifndef LCDCONF_H
#define LCDCONF_H
#define LCD_XSIZE (240) / lcd 的水平分辨率 X-resolution of LCD, Logical coor. /
#define LCD_YSIZE (320) / lcd 的垂直分辨率 Y-resolution of LCD, Logical coor. /
#define LCD_BITSPERPIXEL (16) / 16位颜色RGB值 颜色深度/
#define LCD_SWAP_RB (1) /红蓝反色交换 /
/ lcd 控制器的具体型号
- 设置为 -1时 会编译LCDDriver 下 LCDDummy.c
- 设置为 -2时 会编译LCDDriver 下 LCDNull.c
* - 还需要修改LCDDriver 下文件的宏定义 才可以被编译
- eg. LCDDummy.c:
* - #if (LCD_CONTROLLER == -1) && (!defined(WIN32) |defined(LCD_SIMCONTROLLER))
- 改为
- #if (LCD_CONTROLLER == -1)
*/
#define LCD_CONTROLLER -1 //设置为-1-2,因为UCGUI没有相应LCD 控制IC驱动
#define LCD_INIT_CONTROLLER() LCD_Config(); //绑定相关LCD底层驱动的初始化函数
#ifndef GUITOUCH_CONF_H
#define GUITOUCH_CONF_H
/ 正点原子LCD相关参数,不同LCD值不同,需另测 /
#define GUI_TOUCH_AD_LEFT 120 //最左边x轴的AD值,非坐标值
#define GUI_TOUCH_AD_RIGHT 1870 //最右边x轴的AD值
#define GUI_TOUCH_AD_TOP 90 //最上边y轴的AD值
#define GUI_TOUCH_AD_BOTTOM 1850 //最下边y轴的AD值
#define GUI_TOUCH_SWAP_XY 0 //不允许翻转
#define GUI_TOUCH_MIRROR_X 0
#define GUI_TOUCH_MIRROR_Y 0
#endif / GUITOUCH_CONF_H /
#include “GUI.h”
#include “GUI_X.h”
#include “xpt2046.h”
//#include “stdio.h”
void GUI_TOUCH_X_ActivateX(void) { //不用配置
}
void GUI_TOUCH_X_ActivateY(void) { //不用配置
}
int GUI_TOUCH_X_MeasureX(void) {
u16 var = ADS_Read_XY(CMD_RDX); //读取X轴的AD转换值 不是坐标值
//printf("\r\n MeasureX is %d \r\n",var);
return var;
}
int GUI_TOUCH_X_MeasureY(void) {
u16 var = ADS_Read_XY(CMD_RDY); //读取Y轴的AD转换值
//printf("\r\n MeasureY is %d \r\n",var);
return var;
}
- 设定触摸屏的一个引脚为外部触发,触摸点击时,电平变化触发中断,在中断函数中调用GUI_TOUCH_Exec()函数,让UCGUI更新TOUCH时间数据。
- 设定一个10ms的定时器中断不断查询,在中断函数中调用GUI_TOUCH_Exec()。其实第一个方案,看似更为合适,不占用CPU,让CPU可以处理其他事情。但是UCGUI的触摸事件,一次触摸只会读取一个轴的AD值,也就是说一次读取X轴AD,下一次在读取Y轴AD值。这样导致获得的数据都是错误的。uCGUI 有处理的抖动的函数_StoreUnstable(x, y),会将误差较大的数据过滤,两次点击事件时间很短的话,也至少会是一次正确坐标,一次错误坐标 ..eg.点击事件1: MeasureY AD is 736 , coordinate is X = 134261972 ,Y= 134261972点击事件2: MeasureX AD is 576 , coordinate is X = 62 ,Y= 117而且外部中断的方法,只能获得触摸点击的事件,无法获得触摸移动的事件。所以采用了查询的方法。。使用Stm32的滴答定时器 产生一个10ms的中断,在中断函数中调用UCGUI更新函数。。stm32f10x_it.c:
#include “stm32f10x_it.h”
#include “GUI.h”
void SysTick_Handler(void)
{
GUI_TOUCH_Exec(); //调用UCGUI TOUCH相关函数
GUI_Exec(); //GUI事件更新
}
#include “common.h”
#include “GUI.h”
void Delay(u32 us)
{
u32 time=100*us/7;
while(–time);
}
int main(void)
{
//stm32 初始化
RCC_Configuration();
NVIC_Configuration();
USART_Configuration();
SPI_Configuration();
GPIO_Configuration();
GUI_Init();
Delay(100000);
GUI_SetBkColor(GUI_RED); //设置背景颜色
GUI_SetColor(GUI_WHITE); //设置前景颜色,及字体和绘图的颜色
GUI_Clear(); //按指定颜色清屏
GUI_DispStringAt("Hello World ..",10,10); //显示字符
GUI_CURSOR_Show(); //显示鼠标,测试触摸屏 必须打开窗口功能 GUI_WINSUPPORT
Delay(1000000); //必须稍加延时,否则会白屏
SysTick_Config(720000); //10ms
while(1);
}