你的位置:首页 > 技术 > GUI/OS

STM32 HAL库 裸机移植STemwin[转]

2018-12-14 浏览:(263) GUI/OS 评论(0)

一、准备工作

1、STM32CubeMx     我使用的是4.25版本的,软件还没装上的自己去下载安装就可以了

2、下载F103最新的固件库,新建工程的时候,会自动提示让你下载的,不用另行下载

下载保存的地方可以在软件的project -> setting 页面的最底下看到

3、TFT屏幕,了解清楚平模的驱动IC型号(后面会用到),同时准备好此屏幕的驱动。注意这里只说明支持FSMC驱动的LCD屏幕(数据输出最少16个),为避免其它错误操作,应先确保驱动文件和屏幕都是好的,比如先跑个例程之类的。

4、编译环境Keil uVision5

二、添加文件

1、新建工程,我这里是F103VET6的芯片

2、配置FSMC,这里只有NE1可以选,那就选NE1了,不同的选择,会导致不同的代码,后面再说,这里先选上NE1

,寄存器的选择就选A16,也可以选其它,同样,不同的选择,会导致不同的代码,后面再说。注意数据选16位(这里只讲16位,8位的其实一样)。

    注意一定要选上CRC校验,这里是ST的一个保护机制,没什么卵用,强制要求的,选上就是了。

    屏幕一般都是由22个引脚来控制的,其中16个引脚是数据,6个是控制,对应关系:

    FSMC_NOE    LCD_RD    读 
    FSMC_NWE    LCD_WR    写
    FSMC_NEx    LCD_CS    片选
    FSMC_Ax    LCD_RS    寄存器选择,注意不是复位
    FSMC_D00~D15 对应 LCD_D0~D15    数据引脚

    到这里,已经配置了LCD屏幕的20个引脚了,(16个数据引脚,4个控制引脚),还需要在配置LCD的RST和BK引脚,也就是复位和背光灯引脚,没有的话可以不配置,我这里有,配置为输出即可(默认推挽输出)

至此,引脚配置完。把时钟配置一下,就可以生成了。

3、把STemwin复制到工程文件

把整个STemwin复制到工程文件里面,要把SemWin文件夹改个名称,否则的话,在重新生成代码的时候,改文件夹可能会被删除

再工程新建一个分组STemwin,把这几个文件添加到工程:

GUI_X.C:\OS 文件夹

GUIConf.c,LCDConf_FlexColor_Template.c:\Config 文件夹

STemWin522_CM3_Keil.lib :\Lib 文件夹

把LCD驱动文件也放到工程里面,注意驱动文件的名称不能为lcd.c、lcd.h,因为emwin里有一个文件也叫lcd.c,改一下名称就好,我这里改为:

其中,ili9341是我屏幕的驱动IC,再次提醒,记住这个IC芯片的型号,把相应的头文件也加进去(个人习惯把头文件和源文件分开两个文件夹存放)

添加到工程里面,把相应的头文件路径加进去:

然后编译一下:

一堆错误(错误数量跟LCD的驱动文件有关),前面的都是一些体力活,真正要改代码的工作终于开始了。

三、修改代码

1、GUI_X.c

    这里只需要修改一个代码,源码里面由这么一个变量:volatile GUI_TIMER_TIME OS_TimeMS;

这是整个emwin的心跳,必须要让它跳起来(我是直接把它放到了系统时钟里面,由兴趣的朋友可以放在定时器里面,注意是1ms的心跳):

这里系统会报错,提示GUI_TIMER_TIME这个数据类型未定义,很简单,在文件里加上 #include “GUI.h”就可以了

2、GUIConf.c

只需要把这个数据改小一点就可以了,我这里改成10*1024,也就是10K字节,具体看芯片的内存空间大小,大点小点都无所谓。

3、LCDConf_FlexColor_Template.c

先把LCD驱动头文件加进来:#include "bsp_ili9341_lcd.h"

屏幕分辨率,按实际屏幕分辨率大小修改就可以了

然后要修改这4个函数:

static void LcdWriteReg(U16 Data) ;
static void LcdWriteData(U16 Data);
static void LcdWriteDataMultiple(U16 * pData, int NumItems);
static void LcdReadDataMultiple(U16 * pData, int NumItems);

这时候需要回去看我们LCD的驱动代码了,先看头文件bsp_ili9341_lcd.h,找到类似下面定义的东西:

#define      macFSMC_Addr_ILI9341_CMD         ( ( uint32_t ) 0x60000000 )     //FSMC_Bank1_NORSRAM1用于LCD命令操作的地址
#define      macFSMC_Addr_ILI9341_DATA        ( ( uint32_t ) 0x60020000 )      //FSMC_Bank1_NORSRAM1用于LCD数据操作的地址

为何是0x60000000?这又牵连到了一开始我们配置的FSCM了,具体可以查看FSMC的相关时序,我们的LCD驱动协议,实际上跟FSMC是一毛一样的。这里只介绍怎么决定这个值就好:

NE1 0x600000000

NE2 0x640000000

NE3 0x680000000

NE4 0x6C0000000

然后0x60020000的决定方式:

 0x600000000 |  ( 0x1<<( 16 + 1 ) )  = 0x60020000;

其中的16就是A16,如果是A17,那就是17+1,结果为0x60040000

现在只要记住,写LCD命令是小的数值,写LCD数据是大的数值就好了。

然后定义两个宏定义:

#define LCD_WRITE_REG( *(__IO uint16_t *) (macFSMC_Addr_ILI9341_CMD) )
#define LCD_WRITE_DATA( *(__IO uint16_t *) (macFSMC_Addr_ILI9341_DATA) )

然后,写上代码:

static void LcdWriteReg(U16 Data) {
  // ... TBD by user
  LCD_WRITE_REG = Data;
}
static void LcdWriteData(U16 Data) {
  // ... TBD by user
  LCD_WRITE_DATA = Data;
}
static void LcdWriteDataMultiple(U16 * pData, int NumItems) {
  while (NumItems--) {
    // ... TBD by user
    LCD_WRITE_DATA = *pData++;
  }
}
static void LcdReadDataMultiple(U16 * pData, int NumItems) {
  while (NumItems--) {
    // ... TBD by user
    *pData++ = LCD_WRITE_DATA;
  }
}

在LCD_X_Config函数里面,加入一行代码

Config.NumDummyReads = 2;

表示第二个数据才是真实数据(不理解的话就先记住,以后慢慢会清楚)

第二个红框的就是由驱动芯片决定的,打开这个文档:

在1127页左右,找到你对应的芯片驱动IC,然后决定红框中的值取什么:

我这里是ili9341,所以要改成GUIDRV_FLEXCOLOR_F66709

GUIDRV_FLEXCOLOR_M16C0B16的意思页可以在文档中找到:

然后,把驱动文件的初始化函数放在这里:

剩下的,就是把LCD的驱动代码修改为HAL库的了,没什么难度,自行修改吧,注意要细心点。

至此,移植代码做完了,写个测试代码

四、测试代码

先加入头文件  #include "GUI.h"和lcd驱动#include "bsp_ili9341_lcd.h"

写入代码: