STM32CubeIDE中移植STemwin(芯片为RA8875)

这次的移植并不算成功,只是显示没有问题了,可以创建按钮,可以显示图片,可以触摸。但是!!!只要一使用的float型数据,就会进入硬件错误。本来以为FPU使能的不好,可以只要把触摸去掉,就可以正常使用float型数据,感觉是不是跟GUI_PID_StoreState()函数有冲突?可是之前用MDK做的没有问题呀。网上没有什么用IDE的例程,努力了好几天试了很多方法也没有成功。虽然很不甘心,但是项目进度不等人,所以只能放弃了。

希望如果有人成功了或者找到原因了,可以来告诉我。非常期待。

1、使能FPU并添加DSP库

接着上一篇文章,因为我用的stm32f407,对于STM32F4XX等M4内核的芯片移植STemwin的话,就要使能芯片的FPU,并将其DSP库添加到工程中。

2、使能CRC校验

这一点是必须的,否则不能使用STemwin
在这里插入图片描述

3、准备STemwin源文件

在电脑的安装目录下,有最新的源文件,我的路径为:
C:\Users\Administrator\STM32Cube\Repository\STM32Cube_FW_F4_V1.25.0\Middlewares\ST\STemWin
把相关文件添加到工程中
在这里插入图片描述
这里要着重说一下添加库文件,这个软件添加库文件真的好难呀!!!
STemwin5.44版本中的库文件全部变为.a 格式, 文件名中不再直接写出编译器的类型
在这里插入图片描述
在这里插入图片描述
选好库文件之后,要添加到工程中,添加方式为
在这里插入图片描述
注意库文件名前面要加冒号 :STemWin_CM4_wc16.a

4、修改文件

3.1 GUIConf.c


#include "GUI.h"

/*********************************************************************
*
*       Defines
*
**********************************************************************
*/
//
// Define the available number of bytes available for the GUI
//
#define GUI_NUMBYTES  (20*1024)			//设置EMWIN内存大小
#define GUI_BLOCKSIZE 0x80				//块大小

/*********************************************************************
*
*       Public code
*
**********************************************************************
*/
/*********************************************************************
*
*       GUI_X_Config
*
* Purpose:
*   Called during the initialization process in order to set up the
*   available memory for the GUI.
*/
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);
  GUI_ALLOC_SetAvBlockSize(GUI_BLOCKSIZE);
  //
  // Set default font
  //
  GUI_SetDefaultFont(GUI_FONT_6X8);
}

3.2 GUIConf.h

#ifndef GUICONF_H
#define GUICONF_H

/*********************************************************************
*
*       Multi layer/display support
*/
#define GUI_NUM_LAYERS            2    // Maximum number of available layers

/*********************************************************************
*
*       Multi tasking support
*/
#ifdef OS_SUPPORT
 #define GUI_OS                    (1)  // Compile with multitasking support
#else
 #define GUI_OS                    (0)
#endif

/*********************************************************************
*
*       Configuration of touch support
*/
#ifndef   GUI_SUPPORT_TOUCH
  #define GUI_SUPPORT_TOUCH       (1)  // Support touchscreen
#endif

/*********************************************************************
*
*       Default font
*/
#define GUI_DEFAULT_FONT          &GUI_Font6x8

/*********************************************************************
*
*         Configuration of available packages
*/
#define GUI_SUPPORT_MOUSE             (1)    /* Support a mouse */
#define GUI_WINSUPPORT                (1)    /* Use window manager */
#define GUI_SUPPORT_MEMDEV            (1)    /* Memory device package available */
#define GUI_SUPPORT_DEVICES           (1)    /* Enable use of device pointers */

#endif  /* Avoid multiple inclusion */

3.3 关于GUIDRV_Template.c文件

好多的移植教程用的都不是STemwin自带的驱动程序,所以会用到这个文件,自己写的LCD驱动程序,我这次用的是STemwin自带的驱动程序,所以用不到这个文件。

3.4LCDConf_FlexColor_Template.c

GUI的初始化函数 GUI_Init(),一次调用了三个函数,分别是GUI_X_Config()、LCD_X_Config()、LCD_X_DisplayDriver(),这三个函数都要做相应的修改。

void LCD_X_Config(void) {
  GUI_DEVICE * pDevice;
  CONFIG_FLEXCOLOR Config = {0};
  GUI_PORT_API PortAPI = {0};
  //
  // Set display driver and color conversion
  //
  pDevice = GUI_DEVICE_CreateAndLink(GUIDRV_FLEXCOLOR, GUICC_M565, 0, 0);
  //
  // Display driver configuration, required for Lin-driver
  //
  LCD_SetSizeEx (0, XSIZE_PHYS , YSIZE_PHYS);
  LCD_SetVSizeEx(0, VXSIZE_PHYS, VYSIZE_PHYS);
  //
  // Orientation
  //
  Config.Orientation = GUI_ROTATION_0;
  GUIDRV_FlexColor_Config(pDevice, &Config);
  //
  // Set controller and operation mode
  //
//把emWin接口函数全部实现了,RA8875不像ili9325,ili9341之类的仅需4个接口函数,RA8875必须用到其中6个接口函数(具体哪6个就忘了,所以最好全部实现)。
/*
 * RS  WR#
 * 0	0	Data Write
 * 0	1	Data Read
 * 1	0	Command Write
 * 1	1	Status Read
 * 根据这个表格,再参考STemwin说明书中大概1163页的函数说明,实现对应的接口函数
 */
  PortAPI.pfWrite16_A0  = LcdWriteData;
  PortAPI.pfWrite16_A1  = LcdWriteReg;
  PortAPI.pfRead16_A0 = LcdReadData;
  PortAPI.pfRead16_A1 = LcdReadReg;
  PortAPI.pfWriteM16_A0 = LcdWriteDataMultiple;
  PortAPI.pfWriteM16_A1 = LcdWriteRegMultiple;
  PortAPI.pfReadM16_A1  = LcdReadREGMultiple;
  PortAPI.pfReadM16_A0 = LcdReadDataMultiple;

  GUIDRV_FlexColor_SetFunc(pDevice, &PortAPI, GUIDRV_FLEXCOLOR_F66721, GUIDRV_FLEXCOLOR_M16C0B16);
}

这个函数需要注意的是:把emWin接口函数全部实现了,RA8875不像ili9325,ili9341之类的仅需4个接口函数,RA8875必须用到其中6个接口函数(具体哪6个就忘了,所以最好全部实现),我在这里面卡了很长时间,因为一般的都只实现4个接口函数,然后执行完GUI_Init()后,就会进入硬件错误,后来在其他一个论坛里面看到有网友解释,才算解决了这个问题。

在这里插入图片描述
在这里插入图片描述

/********************************************************************
*
*       LcdWriteReg
*
* Function description:
*   Sets display register A16=1
*/
void LcdWriteReg(U16 Data) {
  // ... TBD by user
	RA8875_REG = Data;
}

/********************************************************************
*
*       LcdWriteData
*
* Function description:
*   Writes a value to a display register  A16=0
*/
void LcdWriteData(U16 Data) {
  // ... TBD by user
	RA8875_RAM = Data;
}

U16 LcdReadReg(void){		//A16=1
	U16 Data;
	Data = RA8875_REG;
	return Data;
}

U16 LcdReadData(void){		//A16=0
	U16 Data;
	Data = RA8875_RAM;
	return Data;
}
/********************************************************************
*
*       LcdWriteRegMultiple
*
* Function description:
*   Writes multiple values to a display register. A16=1
*/
void LcdWriteRegMultiple(U16 * pData, int NumItems){
  while (NumItems--) {
	// ... TBD by user
	  RA8875_REG = *pData++;
  }

}

/********************************************************************
*
*       LcdWriteDataMultiple
*
* Function description:
*   Writes multiple values to a display register.  A16=0
*/
void LcdWriteDataMultiple(U16 * pData, int NumItems) {
  while (NumItems--) {
    // ... TBD by user
	  RA8875_RAM = *pData++;
  }
}

/********************************************************************
*
*       LcdReadDataMultiple
*
* Function description:
*   Reads multiple values from a display register.
*/
void LcdReadDataMultiple(U16 * pData, int NumItems) {		//A16=0
  while (NumItems--) {
    // ... TBD by user
	  *pData++ = RA8875_RAM;
  }
}

void LcdReadREGMultiple(U16 * pData, int NumItems) {		//A16=1
  while (NumItems--) {
	// ... TBD by user
	  *pData++ = RA8875_REG;
  }
}

我的程序中,用的是NE1,A16,LCD驱动器的访问地址如下:

/*把第一个区分成4个地址区
			(0x60000000 + (0 << 23))
			(0x60000000 + (1 << 23))
			(0x60000000 + (2 << 23))
			(0x60000000 + (3 << 23))*/
#define RA8875_BASE		((uint32_t)0x60000000)

#define RA8875_REG		*(volatile uint16_t *)(RA8875_BASE +  (1 << (0 + 17)))	/* FSMC 16位总线模式下 FSMC_A0口线对应物理地址A1 */  // A16
#define RA8875_RAM		*(volatile uint16_t *)(RA8875_BASE)
int LCD_X_DisplayDriver(unsigned LayerIndex, unsigned Cmd, void * pData) {
  int r;
  (void) LayerIndex;
  (void) pData;

  switch (Cmd) {
  case LCD_X_INITCONTROLLER: {
    //
    // Called during the initialization process in order to set up the
    // display controller and put it into operation. If the display
    // controller is not initialized by any external routine this needs
    // to be adapted by the customer...
    //
    // ...
	  RA8875_Init();
    return 0;
  }
  default:
    r = -1;
  }
  return r;
}

3.5 GUI_X.C

#include "GUI.h"

/*********************************************************************
*
*       Global data
*/
volatile GUI_TIMER_TIME OS_TimeMS;

/*********************************************************************
*
*      Timing:
*                 GUI_X_GetTime()
*                 GUI_X_Delay(int)

  Some timing dependent routines require a GetTime
  and delay function. Default time unit (tick), normally is
  1 ms.
*/

GUI_TIMER_TIME GUI_X_GetTime(void) { 
  return OS_TimeMS; 
}

void GUI_X_Delay(int ms) { 
  int tEnd = OS_TimeMS + ms;
  while ((tEnd - OS_TimeMS) > 0);
}

/*********************************************************************
*
*       GUI_X_Init()
*
* Note:
*     GUI_X_Init() is called from GUI_Init is a possibility to init
*     some hardware which needs to be up and running before the GUI.
*     If not required, leave this routine blank.
*/

void GUI_X_Init(void) {}


/*********************************************************************
*
*       GUI_X_ExecIdle
*
* Note:
*  Called if WM is in idle state
*/

void GUI_X_ExecIdle(void) {}

/*********************************************************************
*
*      Logging: OS dependent

Note:
  Logging is used in higher debug levels only. The typical target
  build does not use logging and does therefor not require any of
  the logging routines below. For a release build without logging
  the routines below may be eliminated to save some space.
  (If the linker is not function aware and eliminates unreferenced
  functions automatically)

*/

void GUI_X_Log     (const char *s) { GUI_USE_PARA(s); }
void GUI_X_Warn    (const char *s) { GUI_USE_PARA(s); }
void GUI_X_ErrorOut(const char *s) { GUI_USE_PARA(s); }

4、编写主函数

static void StartupTask (void *p_arg)
{
	CPU_INT32U cpu_clk;
	OS_ERR os_err;
	(void)p_arg;
	cpu_clk = HAL_RCC_GetHCLKFreq();
	/* Initialize and enable System Tick timer */
	OS_CPU_SysTickInit(cpu_clk);
	__HAL_RCC_CRC_CLK_ENABLE();			//移植STemwin必须开启CRC校验
	GUI_Init();
	GUI_SetBkColor(GUI_WHITE);
	GUI_SetColor(GUI_RED);
	GUI_SetFont(&GUI_Font32B_1);
	GUI_DispStringAt("Hello world!", 1, 1);
	GUI_DispStringAt("Hello world!", 200, 1);
	GUI_DispStringAt("Hello world!", 100, 200);
	GUI_DispStringAt("Hello world!", 300, 200);
	while (DEF_TRUE)
	{
//		 HAL_GPIO_TogglePin(BUZZER_GPIO_Port,BUZZER_Pin);
		 OSTimeDlyHMSM(0u, 0u, 0u, 100u,OS_OPT_TIME_HMSM_STRICT,&os_err);
	}
}

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值