LCD 都看到图形库移植了,相信对图形库也有了解了。我选择这个图形库也是网上查的,机缘巧合就选择了他(看来我的选择是不会出错的)。这个图形库都叫Win了界面自然是像电脑的操作界面了。
一 移植前
1.那肯定是先下载啦。
2.我们要先了解一下里面有什么,打开解压后的目录
Libraries目录下
STemWinLibrary532目录下
以上就是大致的分布情况,就是把暂时用到的画出来了。
二 开始拷贝文件
Keil 创建一个新的工程,然后把STM32F103的标准函数库移植到工程(这个都会吧),然后在工程目录下新建一个目录:STemWin。
2.然后开始拷贝文件
Config 目录下拷贝时不需要拷贝 LCDConf_Lin_Template.c LCDConf_Lin_Template.h 这两个文件,我们这次移植不用官方提供的LCD驱动程序,而是使用自己的LCD驱动程序。因为我们的LCD不一定是官方所支持的型号。然后再新建一个 LCDConf.h 文件要不然编译的时候会报错。
OS 目录下只拷贝 GUI_X.c 这个文件。这个文件是不启用系统,也就是不能多任务操作。
然后回到Keil 开始添加头文件目录
这个时候编译一下应该不会有报错的。
三 修改文件
1.复制完文件并把文件添加到工程之后,先编译一下,检查一下有没有错误。
2.这里我用的是自己的LCD初始化函数,不使用官方提供的,这里我们一共要修改4个文件,并且改动量都不大。
LCDConf_FlexColor_Template.c 负责配置LCD的初始化和控制,在里面有6个函数,前面四个是LCD寄存器的读写函数,如果是用的官方提供的LCD初始化,这四个函数就要补全。如果是使用自己的初始化函数就把这四个函数注释掉。重点是第五个函数 void LCD_X_Config(void) {} 如果使用官方初始化就按模板进行配置,需要查看手册。自己的初始化就按下面的进行配置,哦对了文件开头的分辨率根据自己的屏幕修改,
#define XSIZE_PHYS 240 // 屏幕分辨率,本来是在文件开头的根据屏幕实际分辨率修改
#define YSIZE_PHYS 320 //
void LCD_X_Config(void) {
GUI_DEVICE * pDevice;
//这是重点,自定义LCD一定要是 GUIDRV_TEMPLATE
pDevice = GUI_DEVICE_CreateAndLink(GUIDRV_TEMPLATE, GUICC_M565, 0, 0);
/*GUICC_M565 和 GUICC_565 的差别是很大的,如果颜色显示不正确
就是这个参数不正确*/
LCD_SetSizeEx(0, XSIZE_PHYS, YSIZE_PHYS);
LCD_SetVSizeEx(0, VXSIZE_PHYS, VYSIZE_PHYS);
}
GUIConf.h 配置GUI的一些基础功能,
#ifndef GUICONF_H
#define GUICONF_H
#define GUI_NUM_LAYERS 2 // 最大显示层数
#define GUI_OS (0) //不支持多任务
#define GUI_SUPPORT_TOUCH (0) // 暂时不支持触摸屏
#define GUI_DEFAULT_FONT &GUI_Font6x8 //默认字体
#define GUI_SUPPORT_MOUSE (1) /* 支持鼠标 */
#define GUI_WINSUPPORT (1) /* 支持窗口管理 */
#define GUI_SUPPORT_MEMDEV (1) /* 支持存储器 */
#define GUI_SUPPORT_DEVICES (1) /* 打开设备指针 */
#endif /* Avoid multiple inclusion */
GUIConf.c 给GUI分配可以使用的内存,GUI图形处理和图像显示使用,说白了就是显存(也不知道这样说对不对,),默认的是通过创建数组的形式分配内存,如果有外部RAM可以在这里进行分配,这样就可以多分配内存给GUI,我这里没有外部内存。
#define GUI_NUMBYTES 1024*50 /* 1024*50=50KB */
#define USE_EXRAM 0 //不使用外部SRAM
void GUI_X_Config(void) {
//
// 32 bit aligned memory area
//
static U32 aMemory[GUI_NUMBYTES / 4];
//
// Assign memory to emWin
//
GUI_ALLOC_AssignMemory(aMemory, GUI_NUMBYTES);
//
// Set default font
//
GUI_SetDefaultFont(GUI_FONT_6X8);
}
GUIDRV_Template.c GUI的基本绘制函数,有很多大佬通过修改这个文件来优化显示效率,我不会 不乱改。我这在这里添加画点函数和读点函数,我在这个文件里直接添加了自己的LCD头文件,在画点和读点函数里直接编写功能代码,没有使用调用函数的方式。
//画点
static void _SetPixelIndex(GUI_DEVICE * pDevice, int x, int y, int PixelIndex) {
//
// Convert logical into physical coordinates (Dep. on LCDConf.h)
//
#if (LCD_MIRROR_X == 1) || (LCD_MIRROR_Y == 1) || (LCD_SWAP_XY == 1)
int xPhys, yPhys;
xPhys = LOG2PHYS_X(x, y);
yPhys = LOG2PHYS_Y(x, y);
#else
#define xPhys x
#define yPhys y
#endif
GUI_USE_PARA(pDevice);
GUI_USE_PARA(x);
GUI_USE_PARA(y);
GUI_USE_PARA(PixelIndex);
{
//
// Write into hardware ... Adapt to your system
//LCD_Window(x,x,y,y); //设置窗口
LCD_X_Y(x, y); //设置光标坐标
KS_GRAM; //开始写入GRAM
W_GRAM = PixelIndex; //写入颜色
// TBD by customer...
}
#if (LCD_MIRROR_X == 0) && (LCD_MIRROR_Y == 0) && (LCD_SWAP_XY == 0)
#undef xPhys
#undef yPhys
#endif
}
//读点
static unsigned int _GetPixelIndex(GUI_DEVICE * pDevice, int x, int y) {
unsigned int PixelIndex;
//
// Convert logical into physical coordinates (Dep. on LCDConf.h)
//
#if (LCD_MIRROR_X == 1) || (LCD_MIRROR_Y == 1) || (LCD_SWAP_XY == 1)
int xPhys, yPhys;
xPhys = LOG2PHYS_X(x, y);
yPhys = LOG2PHYS_Y(x, y);
#else
#define xPhys x
#define yPhys y
#endif
GUI_USE_PARA(pDevice);
GUI_USE_PARA(x);
GUI_USE_PARA(y);
{
//
// Write into hardware ... Adapt to your system
//
// TBD by customer...
//
PixelIndex = 0;
if(x>=240||y>=320) return PixelIndex;
LCD_X_Y(x,y);
PixelIndex = W_GRAM;
return PixelIndex;
}
#if (LCD_MIRROR_X == 0) && (LCD_MIRROR_Y == 0) && (LCD_SWAP_XY == 0)
#undef xPhys
#undef yPhys
#endif
return PixelIndex;
}
然后是就是在main.c里添加头文件GGUI.h,然后打开CRC时钟,然后添加初始化函数,再编写测试代码。然后调试(因为我不是一次性移植成功的,途中有不少折腾
#include "stm32f10x.h"
#include <GUI.h>
#include "app.h" //这是用GUIBuilder软件制作界面时自动生成的代码,我这里改名字了
int main(void){
Deley_Init(); //SysTick初始化
init_usart1(); //串口打印
LCD_init(); //LCD初始化,自己写的
Deley(100);
//以上初始化是我之前写的,
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE);
GUI_Init();/*如果初始化成功了会自动清屏(默认是黑色的),默认的清屏函数比较慢
如果看到屏幕从上到下白色变成黑色,说明已经初始化成功了并且打点函数
编写正确。如果屏幕一开机就是白色的多半是初始化没有完成,这时候可以
利用串口打印来放一个“探针”打印的内容不要重复,在GUI_Init()后面放
一个,打点函数里放一个,GUI初始化时会调用的函数里各放一个,如果调用
成功了串口是有相应的打印。这样就知道哪里卡死了 。如果卡在GUI_Init();
极有可能是LCD_X_Config(void)这个函数没有配置好。*/
USART1_SendString("STemWin初始化完成/n");
CreateFramewin(); //用来测试移植是否成功
GUI_DispStringAt("Hello World!",0,0); //用来测试移植是否成功
//GUI_JPEG_Draw(_acImage_0, sizeof(_acImage_0), 20, 20);
while(1){
GUI_Delay(50); //使用GUIBuilder 软件制作画面时一定要在无锡喜欢中调用这个延时函数
}
}
)使用GUIBuilder制作的画面在显示时要在主函数的无锡循环里调用 GUI_Delay(50); 并且还有配置好SysTick,代码如下
SysTick_Config(9000);
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
stm32f10x_it.c
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x_it.h"
extern volatile GUI_TIMER_TIME OS_TimeMS;//在文件开头声明
//找到这个函数,SysTick的中断函数
void SysTick_Handler(void)
{
OS_TimeMS--; ///加入这段代码。GUI的延时变量
}
三 GUIBuilder画面显示
1.STemWin_Library_V1.2.0\Libraries\STemWinLibrary532\Software 里可以找到GUIBuilder。
2.制作好画面后按CTRL+A保存组合键就会在当前目录下生成从c源文件。
3.把原文件加入到工程中,我是把名字改成app.c,然后写了一个app.h文件,方便调用。然后在main.c中添加头文件app.h
这是我随便画的
#include "DIALOG.h"
/*********************************************************************
*
* Defines
*
**********************************************************************
*/
#define ID_FRAMEWIN_0 (GUI_ID_USER + 0x00)
// USER START (Optionally insert additional defines)
// USER END
/*********************************************************************
*
* Static data
*
**********************************************************************
*/
// USER START (Optionally insert additional static data)
// USER END
/*********************************************************************
*
* _aDialogCreate
*/
static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
{ FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 2, 240, 320, 0, 0x0, 0 },
// USER START (Optionally insert additional widgets)
// USER END
};
/*********************************************************************
*
* Static code
*
**********************************************************************
*/
// USER START (Optionally insert additional static code)
// USER END
/*********************************************************************
*
* _cbDialog
*/
static void _cbDialog(WM_MESSAGE * pMsg) {
// USER START (Optionally insert additional variables)
// USER END
switch (pMsg->MsgId) {
// USER START (Optionally insert additional message handling)
// USER END
default:
WM_DefaultProc(pMsg);
break;
}
}
/*********************************************************************
*
* Public code
*
**********************************************************************
*/
/*********************************************************************
*
* CreateFramewin
*/
WM_HWIN CreateFramewin(void);
WM_HWIN CreateFramewin(void) { //在主函数里调用这个函数就可以显示画面了
WM_HWIN hWin;
hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
return hWin;
}
如果在编译过程中碰到:Objects\STemWin.axf: Error: L6218E: Undefined symbol IMAGE_SetPNG (referred from app.o).
说明你没有emWin_PNG库,这个图像库是要单独下载的,
下载链接: 点这里 提取码:klum
下载完成后解压,找到适用自己版本的库,添加的工程里就可以了,真就只需要添加就可以,记得要在工程里设置头文件目录。