lkdGUI移植(STM32F407+SPI屏幕)

1.前言

前面刚把SPI的2.42寸OLED点亮,看的效果还是比0.96寸OLED舒服,想来做项目经常要做菜单,每次没有GUI辅助,着实麻烦,都要徒手写GUI,多级菜单更是麻烦。于是就想移植一个GUI,主要目的就是给STM32F103,F407之类的没有LCD接口的显示器做一个GUI。

因为都是串行协议(SPI或是IIC)通信速率不是很快,再就是基本都是单色屏幕,就更没有必要上LVGL之类的大型GUI,过于复杂了。只不过就是每次写屏幕的时候能简化一点流程。

2.GUI选择

关于GUI选择问题,最开始想搞U8g2的,但是死活搞不出来,而且貌似对u8g2对硬件SPI,IIC支持不是很好,这就很头疼了。

开源轻量化GUI主要还有SimpleGUI,LiteGUI

622401656b2b476eba462e7dbc40cfcc.png

b1b4fae866204284ae2c34925612b72f.png

不过这两款GUI移植起来非常麻烦,我都没移植成功(应该是我的问题),没办法于是再找GUI也就是lkdGUI了。

936712a69e43498f92a4e683241dc7fe.png

 

最开始我是先移植SimpleGUI的,结果发现也是过于复杂了。于是又搞lkdGUI了,lkdGUI相较于其他GUI的好处是程序的耦合性极低,相较于U8g2与SimpleGUI来说,lkdGUI和驱动层分离的非常开,我几乎不用动驱动层的东西。

3.前期准备

首先我们要先准备一个屏幕和STM32的板子,这里我选择STM32F407和一个2.42寸的OLED

bceebdf5bc1244fd9f06a2904e27c3ed.jpeg

连接好线之后就要把驱动写好,保证你的OLED能正常点亮,一般厂家都是有写这些驱动,稍微改改就行。

之后我们要下载GuiLite的源码,这个gitee上就有

地址:lkdGui: 单片机单色屏GUI库 (gitee.com)

8b851218c26b4b64898793ac0f33a342.png

4.移植

我们需要的所有文件都在lkdgui source这个文件夹下面

d6807b5451174d8fa52e72c86d736d2d.png

把整个文件夹放到我们STM32的文件夹下面

eb3e1cf50d534c0e93e20cdf7df951a4.png

添加好文件夹路径后,我们在工程里加入GUI的文件,首先是port文件夹下面的这三个文件

84f842cfbbf04226a0e336792a08cd11.png

在port文件夹下面还有两个文件夹,font是字库,lcd是一些屏幕的驱动,驱动如果有你用的屏幕你可以试着用用,但我还是建议你自己写驱动。

7ed1065bdd4d47fa85385dd1865c5205.png

在font文件夹下面,有几种字库,我们一般用的是6x12的ASCII与12x12的汉字,在里面也有,我们将这两个加入工程。

69237bce5123494c871140b0da799e5e.png

然后是sourse文件夹下面,都添加进去

ed90bbc8d3894217b446e1d30c899724.png

最后工程里应该是这样

04bb38587b3c4bff91bcedb05c3b4b70.png

编译后应该是0错误

585f5a72a5a44bbcab40124877f4c501.png

如果报告没有发现lkdgui.h就说明你的头文件路径没加

46b86d928cb846e290200ae46466b1c4.png

在这里记得加一下

5.底层接口

下面我们需要把操作OLED的底层函数告诉GUI

我们需要在lcddriverport这个文件里写,这里我来一个个解释

cd02c7ff267e45d3b0ab2a3891e3b8f4.png

首先是guiupdate

becaf9b93f9c4f2387837c010383bdc2.png

这个一般商家都会提供这个函数,也就是Refresh这个函数

52faa323e4d14311a50c72ed6d474121.png

这个RangeRefresh函数是区域刷新不写也没关系

2bfde7a3e1d5430ba8efd3e09f1acf99.png

之后是画点函数

5cabefc337624362aa4de420142f1ab6.png

这个函数商家也提供,就是DrawPoint和ClearPoint

4e009bd552ea46d8bfa79365374f0b1c.png

这里稍微注意一下,color是颜色,需要按照一下这种写法就可实现反显的效果。

ab2c1af217c7405abf70281d763c7a7d.png

之后的3个函数可以不用写,开关显示商家也提供了,大家可以自行添加

634cb3898f7a496f941cbb580719cbfc.png

最终程序

/**
  * @file   lcdDriverPort.c
  * @author  guoweilkd
  * @version V0.0.0
  * @date    2018/04/18
  * @brief  lkdGui液晶显示屏驱动接口,由移植者填充函数的具体内容。
  */

#include "lkdGui.h"
#include "oled7.h"

/**
  *@brief 将Gui缓冲区数据显示到lcd上
  *@param  None
  *@retval None
  */
void GuiUpdateDisplayAll(void)
{
  /* 添加用户代码 */
	OLED7_Refresh();
}

/**
  *@brief 将Gui指定缓冲区数据显示到lcd上
  *@param  beginx,beginy,endx,endy 坐标
  *@retval None
  */
void GuiRangeUpdateDisplay(lkdCoord beginx, lkdCoord beginy,lkdCoord endx, lkdCoord endy)
{
	/* 添加用户代码 */
}

/**
  *@brief 向缓冲区画点
  *@param  x,y 坐标
  *@param  color 颜色 <目前只有黑:CBLACK 白:CWHITLE>
  *@retval None
  */
void GuiDrawPoint(lkdCoord x, lkdCoord y, lkdColour color)
{
  /* 添加用户代码 */
	if(color)
		OLED7_DrawPoint(x,y);
	else
		OLED7_ClearPoint(x,y);
}

/**
  *@brief 读取当前显示的点
  *@param  x,y 坐标
  *@param  color 颜色 <目前只有黑:CBLACK 白:CWHITLE>
  *@retval None
  */
void  GuiReadPoint(lkdCoord x, lkdCoord y, lkdColour *pColor)
{
	/* 添加用户代码 */
}

/**
  *@brief 关显示
  *@param  None
  *@retval None
  */
void CloseLcdDisplay(void)
{
  /* 添加用户代码 */
}

/**
  *@brief 开显示
  *@param  None
  *@retval None
  */
void OpenLcdDisplay(void)
{
  /* 添加用户代码 */
}

6.字体驱动接口

下面我们需要告诉gui我们的字模信息

我们先打开userfontport这个文件,别打开错了

27299a80aa784f70a7b4d43882d3de3e.png

首先是汉字字模

e29f64ff70254c779098d96af92387d4.png

这个函数在GBK2312这个C文件中,我们把文件拉到最底下就能看见这个函数了

a95252228642493faa6d7a5bd51da098.png

在接口文件里我们首先要声明这个函数,之后调用即可

b0b31dffc9fa40b2abac57cf4867d8ff.png

同理也是ASCII字模

515f6aeabdbe48c488051f5c5267b9b8.png

然后是字体初始化函数,我们改几个数字即可

8dbdf0af733f4508a3de71dc67b77a42.png

修改成你想要字体的大小

d5e9922eeaa940f3a86e12277c379a17.png

最后程序

/**
  * @file   userFontPort.c
  * @author  guoweilkd
  * @version V0.0.0
  * @date    2018/04/18
  * @brief  lkdGui字体驱动接口,由移植者填充函数的具体内容。
  */

#include "lkdGui.h"

/* 字体控制实体 */
static lkdFont defaultFont;

/**
  *@brief 获取汉字字模
  *@param  code1,code2 汉字编码[H,L] 
  *@param  pBuff 字模buff
  *@retval 0
  */
static uint8_t GetDfontData(uint8_t code1, uint8_t code2,uint8_t *pBuff)
{
    /* 添加用户代码 */
		uint8_t GetFontGb2312_12_12(uint8_t codeH, uint8_t codeL, uint8_t *pBuff);
		GetFontGb2312_12_12(code1,code2,pBuff);
    return 0;
}

/**
  *@brief 获取ASCII字模
  *@param  code1, 编码 
  *@param  pBuff 字模buff
  *@retval 0
  */
static uint8_t GetSfontData(uint8_t code1, uint8_t *pBuff)
{
    /* 添加用户代码 */
		uint8_t GetFontASCII_6_12(uint8_t code1, uint8_t *pBuff);
		GetFontASCII_6_12(code1,pBuff);
    return 0;
}

/**
  *@brief 字体初始化
  *@param  None
  *@retval None
  */
void defaultFontInit(void)
{
	/* 根据字体要求做相应的修改 */

	/* 此buff的大小由最大字模大小决定 */
	static uint8_t dataBuff[12*2];

	defaultFont.name = "汉字字模为12*12的GB2312,ASCII字模为12*6";
	defaultFont.dhigh = 12;
	defaultFont.dwide = 12;
	defaultFont.shigh = 12;
	defaultFont.swide = 6;
	defaultFont.pZmBuff = dataBuff;
	defaultFont.getDfont = GetDfontData;
	defaultFont.getSfont = GetSfontData;

    /* 设置为系统默认字体 */
	GuiFontSet(&defaultFont);
  GuiSetbackcolor(CWHITLE);
  GuiSetForecolor(CBLACK);
}

7.主函数

至此gui正式移植成功了,下面我们开始写主函数

首先加入lkdgui.h

df689a3769da4f938a3cfb39847be735.png

之后依次初始化spi,oled,gui即可

e45c07d9cbed491ea2eb903e034ff732.png

我们首先显示一串字符吧,程序比较简洁,也都有注释

d22030e6e25c4ef5931afdccbcf45e67.png

我们把需要显示的字符添加到testStr这个数组里,然后把用GuiText显示,最后刷新页面即可,其中的几个参数大家可以自行根据需要调节,也都有注释。

a60f03b6bec542deaed2a57367766a6a.jpeg

8.显示中文

ASCII比较好处理,那中文怎么办呢?这里我们遵循的GB2312编码方式,我们可以到网上去找汉字对应的编码,或是直接在C文件里看。

这里以“你好”为例,可以看到“你”对应的编码为0xC4E3,“好”则是0xBAC3

ad8a1644d36b4bca824804716ba9030f.png

6898fcdc0e004bad9609d80a52c2aad1.png

我们在程序里可以以将4个16位拆为两组,程序会自行判断汉字

1caaec4a729e4431b800fa3dade12e3a.png

8269d42c2e4d454793a92c4b0a464ee2.jpeg

没毛病

程序

#include "key.h"


void defaultFontInit(void);


void testLkdGUI(void)
{
	unsigned char textStr[8]={0xC4,0xE3,0xBA,0xC3,'A'};
	
	/* -----------显示文字--------------- */
	fontTextInfo textInfo;
	textInfo.x = 0;/* 文本起始坐标 */
	textInfo.y = 0;
	textInfo.wide = 128;/* 文本范围大小 */
	textInfo.high = 64;
	textInfo.wInterval = 0;/* 字符间距 */
	textInfo.hInterval = 0;/* 行间距 */
	textInfo.flag = 0;/* 反显 */
	textInfo.beginOffset = textInfo.wide * 0;/* 开始偏移,首行缩进 */
	GuiText(&textInfo, textStr);
	GuiUpdateDisplayAll();
}



int main(void)
{ 
	Stm32_Clock_Init(336,8,2,7);//设置时钟,168Mhz
	NVIC_SetGroup(1);//设置中断分组,分组1
	init_PinClock();//初始化所有时钟
	delay_init(168);//初始化延时
	init_spi2();//初始化SPI2
	OLED7_242_Init();//0.96寸7针SPI的oled初始化																		
	defaultFontInit();/* 字库初始化 */
	testLkdGUI();

	while(1)
	{
	}	
}



9.结语

lkdGUI移植还是非常简单的,在本来的文件里有更复杂的功能,比如进度条和多级菜单等功能,大家可以自己进行测试,我已经都移植成功了。大家根据项目需要进行学习和测试。那还是老样子,有问题发在评论区,我会尽力解答,我们下篇文章见。

STM32F407是一款32位ARM Cortex-M4内核的微控制器,拥有丰富的周边设备和高性能。FreeRTOS是一款用于嵌入式系统的实时操作系统,提供了任务调度、内存管理、定时器等功能,使得开发者能够创建复杂的多任务应用程序。TCP客户端是指在TCP/IP协议栈的应用层,通过TCP协议与服务器进行通信的客户端程序。 将STM32F407与FreeRTOS和TCP客户端结合起来,可以创建一个具有实时性能的TCP客户端应用。首先,我们需要将FreeRTOS移植STM32F407上,这可以通过使用STM32CubeMX和FreeRTOS内核文件进行配置和生成来实现。接下来,我们需要编写TCP客户端代码,使用TCP/IP协议栈的相关API进行连接服务器、发送和接收数据等操作。在编写TCP客户端代码时,我们需要创建一个或多个任务,用于处理与服务器的TCP连接和数据通信。这些任务可以使用FreeRTOS提供的任务调度器进行管理和调度。 在使用STM32F407、FreeRTOS和TCP客户端时,还需要注意一些重要的方面。首先,需要根据应用需求进行系统资源的合理配置,包括内存大小、任务优先级等。其次,需要注意任务之间的同步和通信,以避免竞争条件和数据一致性的问题。还需要考虑网络连接的稳定性,处理网络异常和错误情况的方法。最后,还需要进行性能测试和调优,以确保系统在给定约束条件下的稳定工作。 综上所述,将STM32F407、FreeRTOS和TCP客户端结合起来,可以实现一个具有实时性能的嵌入式TCP客户端应用程序。这种应用可以广泛应用于物联网、智能家居、远程监测等领域。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值