STM32F103学习笔记之STemWin图形库移植

LCD    都看到图形库移植了,相信对图形库也有了解了。我选择这个图形库也是网上查的,机缘巧合就选择了他(看来我的选择是不会出错的)。这个图形库都叫Win了界面自然是像电脑的操作界面了。

    我用的是     STemWin

    直接进入正题,STemWin下载   点这里下载   

    编程工具还是  Keil   不变

一  移植前

    1.那肯定是先下载啦。

    2.我们要先了解一下里面有什么,打开解压后的目录

    3.Libraries目录下

    4.STemWinLibrary532目录下

以上就是大致的分布情况,就是把暂时用到的画出来了。

二 开始拷贝文件

    1.首先用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个文件,并且改动量都不大。

    3.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

下载完成后解压,找到适用自己版本的库,添加的工程里就可以了,真就只需要添加就可以,记得要在工程里设置头文件目录。

四 总结

    1.放源码: 提取码:8uzs

    2.我个人认为这个图形库移植一下玩玩还是可以的,可以学到不少东西。但我发现图形库加PNG库要占用挺大的资源的,我的F103ZET6板子没有外部RAM,感觉这一套下来内存就快要满了,以后还要移植别的库,感觉有点吃力,如果不是制作比较复杂,比较多界面,我感觉自己手动代码构图也不是不可以。再说这个GUIBuilder也不是这么好用,用GUIBuilde还无法显示图片,自己调用函数GUI_JPEG_Draw(_acImage_0, sizeof(_acImage_0), 20, 20);是可以正常显示的,但是一旦显示PNG图片就不行了,单片机直接卡死,一开机就黑屏,没有任何变化,感觉是是内存爆了一样,也不知道是不是要改什么,没有深入了。希望有大佬指点了。

                  学习笔记

 

 

谢谢!!

 

 

  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 16
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值