openwrt开发--ILI9341屏幕显示开发

前些天在学习linux下的驱动编写,找到了一块之前淘到的液晶屏,主控芯片是ili9341,分辨率为240*320的屏幕,接口方式是SPI的,心血来潮想搞一下。不过奈何驱动水平不到家,只是开发出了一种杂交方法,来点亮了液晶屏幕,并且显示了仔的图片。

在这里插入图片描述

硬件接口

屏幕接口如下
在这里插入图片描述

接口功能
MISOSPI输出
MOSISPI输入
CLKSPI时钟输入
DC数据/命令 切换控制,低电平表示输入命令,高电平表示输入数据
RES复位屏幕
BLK背光控制
VCC电源
GND接地

开发板上对应找到了5个GPIO为链接了MISO MOSI CLK DC和RES。BLK并没有设置,因为没有口了。

SPI驱动

我的开发板上并没有SPI总线接口,所以只能是用GPIO模拟出来,恰好openwrt内核中有一个模块,叫做spi-gpio-custom,叫做定制用GPIO模拟SPI,简直就是跟我量身定做的啊
在这里插入图片描述
在menuconfig下,位于kernel modules中的SPI Support中。
在这里插入图片描述

然后可以以动态加载的方式编译出来ipk文件,然后安装到开发板中。也可以编译好镜像直接烧写。
命令参数如下

接口功能
<id>ID to used as device_id for the corresponding bus (required)
<sck>GPIO pin ID to be used for bus SCK (required)
<mosi>GPIO pin ID to be used for bus MOSI (required*)
<miso>GPIO pin ID to be used for bus MISO (required*)
<modeX>Mode configuration for slave X in the bus (required) * (see /include/linux/spi/spi.h)
<maxfreqX>Maximum clock frequency in Hz for slave X in the bus (required)
<csX>GPIO pin ID to be used for slave X CS (required**)

举个例子

insmod spi-gpio-custom bus0=1,20,19,22,0,100000
  • 表示位创建SPI总线1,
  • SCK口使用GPIO22,
  • MOSI接口使用GPIO19
  • 工作模式是0
  • 传输速率是100Khz
  • 没有片选

这样,我们就通过模拟的方式,为屏幕提供了SPI接口来传输数据。
执行命令之后,就会创建出对应的SPI设备

/dev/spidev1.0

到这一步,SPI驱动就完成了,其实使用其他SPI设备,例如flash等,都可以这样操作
在这里插入图片描述

GPIO驱动

因为屏幕并不是一个字符设备,直接写入啥就显示啥,需要通过命令开控制写入位置,写入内容。座椅,我们还需要通过前面一章提供的,GPIO驱动,来控制DC和RES引脚。参考前面一章
openwrt开发–驱动程序IPK包开发(GPIO控制)

同样,在安装好模块之后,也会创建出对应的GPIO控制设备

/dev/gpio_control

到这一步,基本的条件就具备了
在这里插入图片描述

屏幕显示

而整个屏幕的点亮,需要按照手册提供的demo,进行初始化操作。
首先需要封装一下初始化接口,分别要初始化SPI设备和GPIO设备

int spi_fd = 0;
int gpio_fd = 0;
int isdata= 0;
void GPIO_Init(void)
{
	/*打开设备文件*/
	gpio_fd = open("/dev/gpio_control", O_RDWR);

	if(gpio_fd <0)
	{
		printf("open dev error \n");
	}
	else
	{
		printf("open dev success \n");
	}
	ioctl(gpio_fd, GPIO_CONTROL_SET_OUT, GPIO_IOCTL_PRAM(GPIO_RES, 0));
	ioctl(gpio_fd, GPIO_CONTROL_SET_OUT, GPIO_IOCTL_PRAM(GPIO_DC, 0));
	isdata=0;
}
void SPI_Init(void)
{
	/*打开设备文件*/
	spi_fd = open("/dev/spidev1.0", O_RDWR);

	if(spi_fd <0)
	{
		printf("open dev error \n");
	}
	else
	{
		printf("open dev success \n");
	}
}

然后需要封装出命令写入和数据写入,这两个是驱动屏幕显示最基础的操作,另外还有一个绘图区域的配置函数,用来控制输入的位置。


/******************************************************************************
      函数说明:LCD写入数据
      入口数据:dat 写入的数据
      返回值:  无
******************************************************************************/
void ILI9341_WR_DATA(u16 dat)
{
	GPIO_DATA();//写数据
	ILI9341_Writ_Bus(dat>>8);
	ILI9341_Writ_Bus(dat);
}
/******************************************************************************
      函数说明:LCD写入命令
      入口数据:dat 写入的命令
      返回值:  无
******************************************************************************/
void ILI9341_WR_REG(unsigned char dat)
{
	GPIO_CMD();//写命令
	ILI9341_Writ_Bus(dat);
}
/******************************************************************************
      函数说明:设置起始和结束地址
      入口数据:x1,x2 设置列的起始和结束地址
                y1,y2 设置行的起始和结束地址
      返回值:  无
******************************************************************************/
void ILI9341_Address_Set(u16 x1,u16 y1,u16 x2,u16 y2)
{
	ILI9341_WR_REG(0x2a);//列地址设置
	ILI9341_WR_DATA(x1);
	ILI9341_WR_DATA(x2);
	ILI9341_WR_REG(0x2b);//行地址设置
	ILI9341_WR_DATA(y1);
	ILI9341_WR_DATA(y2);
	ILI9341_WR_REG(0x2c);//储存器写
}

然后就是初始化屏幕的操作,是一组命令和数据的写入

/******************************************************************************
      函数说明:LCD初始化函数
      入口数据:无
      返回值:  无
******************************************************************************/
void ILI9341_Init(void)
{
	GPIO_OFF(GPIO_RES);
	ILI9341_delay_ms(20);
	GPIO_ON(GPIO_RES);
	ILI9341_delay_ms(20);
	//OLED_BLK_Set();
	……
	初始化模板代码
	……	
	ILI9341_WR_REG(0x11); //Exit Sleep
	ILI9341_delay_ms(120);
	ILI9341_WR_REG(0x29); //Display on
}

最后就是一系列操作的二次封装,例如显示圆,线,字符串,小数,图片等

/******************************************************************************
      函数说明:LCD清屏函数
      入口数据:无
      返回值:  无
******************************************************************************/
void ILI9341_Clear(u16 Color)
/******************************************************************************
      函数说明:在指定区域填充颜色
      入口数据:xsta,ysta   起始坐标
                xend,yend   终止坐标
      返回值:  无
******************************************************************************/
void ILI9341_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 color)
/******************************************************************************
      函数说明:LCD显示汉字
      入口数据:x,y   起始坐标
                index 汉字的序号
                size1  字号
      返回值:  无
******************************************************************************/
void ILI9341_ShowChinese(u16 x,u16 y,unsigned char index,unsigned char size1,u16 color)	
/******************************************************************************
      函数说明:LCD显示汉字
      入口数据:x,y   起始坐标
      返回值:  无
******************************************************************************/
void ILI9341_DrawPoint(u16 x,u16 y,u16 color)
/******************************************************************************
      函数说明:LCD画一个大的点
      入口数据:x,y   起始坐标
      返回值:  无
******************************************************************************/
void ILI9341_DrawPoint_big(u16 x,u16 y,u16 color)
{
	ILI9341_Fill(x-1,y-1,x+1,y+1,color);
} 
/******************************************************************************
      函数说明:画线
      入口数据:x1,y1   起始坐标
                x2,y2   终止坐标
      返回值:  无
******************************************************************************/
void ILI9341_DrawLine(u16 x1,u16 y1,u16 x2,u16 y2,u16 color)
/******************************************************************************
      函数说明:画矩形
      入口数据:x1,y1   起始坐标
                x2,y2   终止坐标
      返回值:  无
******************************************************************************/
void ILI9341_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2,u16 color)
/******************************************************************************
      函数说明:画圆
      入口数据:x0,y0   圆心坐标
                r       半径
      返回值:  无
******************************************************************************/
void Draw_Circle(u16 x0,u16 y0,unsigned char r,u16 color)
/******************************************************************************
      函数说明:显示字符
      入口数据:x,y    起点坐标
                num    要显示的字符
                mode   1叠加方式  0非叠加方式
      返回值:  无
******************************************************************************/
void ILI9341_ShowChar(u16 x,u16 y,unsigned char num,unsigned char mode,u16 color)
/******************************************************************************
      函数说明:显示字符串
      入口数据:x,y    起点坐标
                *p     字符串起始地址
      返回值:  无
******************************************************************************/
void ILI9341_ShowString(u16 x,u16 y,char *p,u16 color)
/******************************************************************************
      函数说明:显示数字
      入口数据:m底数,n指数
      返回值:  无
******************************************************************************/
u32 mypow(unsigned char m,unsigned char n)
/******************************************************************************
      函数说明:显示数字
      入口数据:x,y    起点坐标
                num    要显示的数字
                len    要显示的数字个数
      返回值:  无
******************************************************************************/
void ILI9341_ShowNum(u16 x,u16 y,u16 num,unsigned char len,u16 color)
/******************************************************************************
      函数说明:显示小数
      入口数据:x,y    起点坐标
                num    要显示的小数
                len    要显示的数字个数
      返回值:  无
******************************************************************************/
void ILI9341_ShowNum1(u16 x,u16 y,float num,unsigned char len,u16 color)
/******************************************************************************
      函数说明:显示40x40图片
      入口数据:x,y    起点坐标
      返回值:  无
******************************************************************************/
void ILI9341_ShowPicture(u16 x1,u16 y1,u16 x2,u16 y2) 
/******************************************************************************
      函数说明:显示图片
      入口数据:x,y    起点坐标
      返回值:  无
******************************************************************************/
void ILI9341_ShowFullPicture(unsigned char* pic,int len) 

这些接口能够达到下面的效果
在这里插入图片描述

如果需要显示一些图片或者汉字,需要利用一些工具,将图片转化为c文件中的数组
在这里插入图片描述
完整的源文件及修改工具,都可以在这里下载
下载地址

不过到这里来看,这个屏幕已经能够显示一些信息了,例如我们 用来显示我们程序中的内容,一些简单的运行结果,不追求高刷新率的情况,已经足够了。并且这种借口易于对接程序,尤其是嵌入式的应用上面。你可以为你的openwrt设备开发一个小窗口,显示想看的内容。
在这里插入图片描述

但是如果要显示视频类的东西,就涉及到了framebuf了,这块内容后续再讲。
别问。问就是整在学习
在这里插入图片描述
好了,今天的内容就写到这里。

结束语

今天去找仔的班主任要了一下仔的幼儿园的时刻表,大概也是从7:30-17:00吧,九个多小时在学校中度过。跟大人上班的时间还真差不多少。
这还不包括以后要上的一些课外班。
子非鱼,焉知鱼之乐。我也不知道鱼乐不乐,只是昨天晚上仔在床上说:明天我想休息一天。

罗翔老师说:“我们登上并非我们所选择的舞台”,在座的有谁的剧本是你自己设定的,其实不是的。
仔细想一想,我们这一生中其实自己能决定的东西很少,我们可能只能决定5%的东西,但有95%的东西是我们决定不了的,我们决定不了我们的出身,我们决定不了我们的智商,我们更决定不了我们这一生的贵人相助。
很多时候我们经常会羡慕别人的剧本,我自己有时候也非常羡慕别人的剧本,但是(其实)没有谁的剧本值得羡慕,你只能把你自己的剧本演好。如果在你的一生中真的遭遇到这些挫折,那对不起,这就是你的剧本。有两种选择,一种选择是弃演,一种选择是把既定的剧本给演好。所以希望大家能够演好自己的剧本。

我还做不到给娃放假,也只能是买点好吃的,偷偷买个小玩具给他,让他在枯燥的生活中,遇到一点发光的东西。在这里插入图片描述

  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

胖哥王老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值