基于小凌派RK2206开发板LCD液晶

一、简介

LCD的应用很广泛,简单如手表上的液晶显示屏,仪表仪器上的液晶显示器或者是电脑笔记本上的液晶显示器,都使用了LCD。在一般的办公设备上也很常见,如传真机,复印机,以及一些娱乐器材玩具等也常常见到LCD的足迹。

本小节使用的是STV,用于单片驱动K色图像TFT-LCD,包含(*3色)x线输出,可以直接以SPI协议,或者8位/9位/16位/18位并行连接外部控制器。STV显示数据存储在片内xx18bits内存中,显示内存的读写不需要外部时钟驱动。

接下来先看本案例的实际操作视频。

二、硬件电路设计

模块整体硬件电路如图1所示,电路中包含了电源电路、液晶接口以及小凌派-RK开发板连接的相关引脚。

图1硬件电路图

其中,液晶屏STV的相关引脚资源如图2所示。

图2液晶屏STV硬件资源示意图

其中,LCD液晶屏引脚功能描述,如下表1所示。

表1LCD液晶屏引脚功能表

其中,LCD液晶屏与小凌派-RK开发板连接如图3所示。

图32.4寸液晶屏和小凌派-RK开发板

三、软件设计

本章节将利用小凌派-RK开发板上的GPIO和SPI接口方式来点亮2.4寸液晶屏,并实现ASCII字符的显示及汉字的显示。

1.主程序设计

如图4所示为LCD液晶屏主程序流程图,开机LiteOS系统初始化后,进入主程序。主程序首先进行GPIO和SPI总线初始化,然后配置LCD液晶屏设备,最后进入循环中。在循环中,主程序控制SPI对LCD液晶屏进行ASCII字符和汉字显示。

图4主程序流程图

2.LCD初始化程序设计

LCD初始化程序主要分为GPIO和SPI总线初始化,配置LCD两部分。

其中,GPIO初始化首先用LzGpioInit()函数将GPIO0_PC3初始化为GPIO引脚,然后用LzGpioSetDir()将引脚设置为输出模式,最后调用LzGpioSetVal()输出低电平。

/*初始化GPIO0_C3*/

LzGpioInit(LCD_PIN_RES);

LzGpioSetDir(LCD_PIN_RES,LZGPIO_DIR_OUT);

LzGpioSetVal(LCD_PIN_RES,LZGPIO_LEVEL_HIGH);

/*初始化GPIO0_C6*/

LzGpioInit(LCD_PIN_DC);

LzGpioSetDir(LCD_PIN_DC,LZGPIO_DIR_OUT);

LzGpioSetVal(LCD_PIN_DC,LZGPIO_LEVEL_LOW);

SPI初始化首先用SpiIoInit()函数将GPIO0_PC0复用为SPI0_CS0n_M1,GPIO0_PC1复用为SPI0_CLK_M1,GPIO0_PC2复用为SPI0_MOSI_M1。其次调用LzI2cInit()函数初始化SPI0端口。

LzSpiDeinit(LCD_SPI_BUS);

if(SpiIoInit(m_spiBus)!=LZ_HARDWARE_SUCCESS){

printf("%s,%d:SpiIoInitfailed!\n",__FILE__,__LINE__);

return__LINE__;

}

if(LzSpiInit(LCD_SPI_BUS,m_spiConf)!=LZ_HARDWARE_SUCCESS){

printf("%s,%d:LzSpiInitfailed!\n",__FILE__,__LINE__);

return__LINE__;

}

配置LCD主要是配置STV的工作模式,具体代码如下所示:

/*重启lcd*/

LCD_RES_Clr();

LOS_Msleep();

LCD_RES_Set();

LOS_Msleep();

LOS_Msleep();

lcd_wr_reg(0x11);

/*等待LCDms*/

LOS_Msleep();

/*启动LCD配置,设置显示和颜色配置*/

lcd_wr_reg(0X36);

if(USE_HORIZONTAL==0)

{

lcd_wr_data8(0x00);

}

elseif(USE_HORIZONTAL==1)

{

lcd_wr_data8(0xC0);

}

elseif(USE_HORIZONTAL==2)

{

lcd_wr_data8(0x70);

}

else

{

lcd_wr_data8(0xA0);

}

lcd_wr_reg(0X3A);

lcd_wr_data8(0X05);

/*STS帧刷屏率设置*/

lcd_wr_reg(0xb2);

lcd_wr_data8(0x0c);

lcd_wr_data8(0x0c);

lcd_wr_data8(0x00);

lcd_wr_data8(0x33);

lcd_wr_data8(0x33);

lcd_wr_reg(0xb7);

lcd_wr_data8(0x35);

/*STS电源设置*/

lcd_wr_reg(0xbb);

lcd_wr_data8(0x35);

lcd_wr_reg(0xc0);

lcd_wr_data8(0x2c);

lcd_wr_reg(0xc2);

lcd_wr_data8(0x01);

lcd_wr_reg(0xc3);

lcd_wr_data8(0x13);

lcd_wr_reg(0xc4);

lcd_wr_data8(0x20);

lcd_wr_reg(0xc6);

lcd_wr_data8(0x0f);

lcd_wr_reg(0xca);

lcd_wr_data8(0x0f);

lcd_wr_reg(0xc8);

lcd_wr_data8(0x08);

lcd_wr_reg(0x55);

lcd_wr_data8(0x90);

lcd_wr_reg(0xd0);

lcd_wr_data8(0xa4);

lcd_wr_data8(0xa1);

/*STSgamma设置*/

lcd_wr_reg(0xe0);

lcd_wr_data8(0xd0);

lcd_wr_data8(0x00);

lcd_wr_data8(0x06);

lcd_wr_data8(0x09);

lcd_wr_data8(0x0b);

lcd_wr_data8(0x2a);

lcd_wr_data8(0x3c);

lcd_wr_data8(0x55);

lcd_wr_data8(0x4b);

lcd_wr_data8(0x08);

lcd_wr_data8(0x16);

lcd_wr_data8(0x14);

lcd_wr_data8(0x19);

lcd_wr_data8(0x20);

lcd_wr_reg(0xe1);

lcd_wr_data8(0xd0);

lcd_wr_data8(0x00);

lcd_wr_data8(0x06);

lcd_wr_data8(0x09);

lcd_wr_data8(0x0b);

lcd_wr_data8(0x29);

lcd_wr_data8(0x36);

lcd_wr_data8(0x54);

lcd_wr_data8(0x4b);

lcd_wr_data8(0x0d);

lcd_wr_data8(0x16);

lcd_wr_data8(0x14);

lcd_wr_data8(0x21);

lcd_wr_data8(0x20);

lcd_wr_reg(0x29);

3.LCD的点数据设计

STV采用SPI通信方式,数据传输协议如下:

4-LineSerialInterface=16-bit/pixel(RGB5-6-5-bitinput),65K-Color,3Ah="05h"

数据传输时序图如图5所示。

图5STV液晶屏SPI数据传输时序图

也就是每个像素占用2个字节,RGB为5+6+5。因此,往LCD液晶屏发送某一个像素信息的程序如下所示:

staticvoidlcd_write_bus(uint8_tdat)

{

LzSpiWrite(LCD_SPI_BUS,0,dat,1);

}

staticvoidlcd_wr_data(uint16_tdat)

{

lcd_write_bus(dat8);

lcd_write_bus(dat);

}

staticvoidlcd_wr_reg(uint8_tdat)

{

LCD_DC_Clr();

lcd_write_bus(dat);

LCD_DC_Set();

}

staticvoidlcd_address_set(uint16_tx1,uint16_ty1,uint16_tx2,uint16_ty2)

{

/*列地址设置*/

lcd_wr_reg(0x2a);

lcd_wr_data(x1);

lcd_wr_data(x2);

/*行地址设置*/

lcd_wr_reg(0x2b);

lcd_wr_data(y1);

lcd_wr_data(y2);

/*储存器写*/

lcd_wr_reg(0x2c);

}

staticvoidlcd_wr_data(uint16_tdat)

{

lcd_write_bus(dat8);

lcd_write_bus(dat);

}

voidlcd_draw_point(uint16_tx,uint16_ty,uint16_tcolor)

{

/*设置光标位置*/

lcd_address_set(x,y,x,y);

lcd_wr_data(color);

}

4.LCD的ASCII字符显示设计

预先将规定字号的ASCII字符的LCD液晶屏像素信息存放于在lcd_font.h源代码文件中。该表格依照ASCII的数值来存放像素信息。例如:空格的ASCII数值是0x0,则程序将像素放到第一行像素中,如下源代码所示。

/*12*6的ASCII码显示*/

constunsignedcharascii_[][12]=

{

{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"",0*/

{0x00,0x00,0x04,0x04,0x04,0x04,0x04,0x00,0x00,0x04,0x00,0x00},/*"!",1*/

{0x14,0x14,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*""",2*/

{0x00,0x00,0x0A,0x0A,0x1F,0x0A,0x0A,0x1F,0x0A,0x0A,0x00,0x00},/*"#",3*/

{0x00,0x04,0x0E,0x15,0x05,0x06,0x0C,0x14,0x15,0x0E,0x04,0x00},/*"$",4*/

.......

};

/*16*8的ASCII码显示*/

constunsignedcharascii_[][16]=

{

{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"",0*/

{0x00,0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x00,0x00,0x18,0x18,0x00,0x00},/*"!",1*/

{0x00,0x48,0x6C,0x24,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*""",2*/

{0x00,0x00,0x00,0x24,0x24,0x24,0x7F,0x12,0x12,0x12,0x7F,0x12,0x12,0x12,0x00,0x00},/*"#",3*/

......

};

/*24*12的ASCII码显示*/

constunsignedcharascii_[][48]=

{

{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"",0*/

{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x40,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"!",1*/

{0x00,0x00,0x00,0x00,0x60,0x06,0x60,0x06,0x30,0x03,0x98,0x01,0x88,0x00,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*""",2*/

......

};

当需要将某一个字号的ASCII字符投射到LCD液晶屏时,程序根据字号大小找到对应的字号的ASCII字符像素表,然后根据ASCII字符的数值找到对应的像素行,最后将该像素行数据依次通过SPI总线发送给LCD液晶屏。如下源代码所示。

voidlcd_show_char(uint16_tx,uint16_ty,uint8_tnum,uint16_tfc,uint16_tbc,uint8_tsizey,uint8_tmode)

{

uint8_ttemp,sizex,t,m=0;

uint16_ti;

uint16_tTypefaceNum;//一个字符所占字节大小

uint16_tx0=x;

sizex=sizey/2;

TypefaceNum=(sizex/8+((sizex%8)?1:0))*sizey;

/*得到偏移后的值*/

num=num-;

/*设置光标位置*/

lcd_address_set(x,y,x+sizex-1,y+sizey-1);

for(i=0;iTypefaceNum;i++)

{

if(sizey==12)

{

/*调用6x12字体*/

temp=ascii_[num][i];

}

elseif(sizey==16)

{

/*调用8x16字体*/

temp=ascii_[num][i];

}

elseif(sizey==24)

{

/*调用12x24字体*/

temp=ascii_[num][i];

}

elseif(sizey==32)

{

/*调用16x32字体*/

temp=ascii_[num][i];

}

else

{

return;

}

for(t=0;t8;t++)

{

if(!mode)

{/*非叠加模式*/

if(temp(0x01t))

{

lcd_wr_data(fc);

}

else

{

lcd_wr_data(bc);

}

m++;

if(m%sizex==0)

{

m=0;

break;

}

}

else

{/*叠加模式*/

if(temp(0x01t))

{

/*画一个点*/

lcd_draw_point(x,y,fc);

}

x++;

if((x-x0)==sizex)

{

x=x0;

y++;

break;

}

}

}

}

}

5.LCD的汉字显示设计

同上原理,程序将某一个特定字号的汉字信息存放于一个数据结构体数组中。该数据结构体包含字体编码Index和像素数据Msk。具体原代码如下所示。

/*定义中文字符12*12*/

typedefstruct

{

unsignedcharIndex[2];

unsignedcharMsk[24];

}typFNT_GB12;

/*定义中文字符16*16*/

typedefstruct

{

unsignedcharIndex[2];

unsignedcharMsk[32];

}typFNT_GB16;

/*定义中文字符24*24*/

typedefstruct

{

unsignedcharIndex[2];

unsignedcharMsk[72];

}typFNT_GB24;

......

通过汉字像素软件将对应的汉字和像素存放于lcd_font.h文件中。具体源代码如下所示。

consttypFNT_GB12tfont12[]=

{

"小",0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x24,0x01,0x24,0x02,0x22,0x02,0x22,0x04,

0x21,0x04,0x20,0x00,0x20,0x00,0x38,0x00,/*"小"*/

"凌",0x40,0x00,0xF9,0x03,0x42,0x00,0xFC,0x07,0x10,0x01,0x28,0x02,0xE0,0x01,0x14,0x01,

0xAA,0x00,0x41,0x00,0xB0,0x01,0x0C,0x06,/*"凌"*/

"派",0x00,0x03,0xF2,0x00,0x14,0x02,0xD0,0x01,0x51,0x01,0x52,0x05,0x50,0x03,0x50,0x01,

0x54,0x01,0x52,0x02,0xD1,0x02,0x48,0x04,/*"派"*/

};

consttypFNT_GB16tfont16[]=

{

"小",0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x88,0x08,0x88,0x10,0x88,0x20,

0x84,0x20,0x84,0x40,0x82,0x40,0x81,0x40,0x80,0x00,0x80,0x00,0xA0,0x00,0x40,0x00,/*"小",0*/

"凌",0x00,0x02,0x02,0x02,0xC4,0x1F,0x04,0x02,0x00,0x02,0xE0,0x7F,0x88,0x08,0x48,0x11,

0x24,0x21,0x87,0x0F,0xC4,0x08,0x24,0x05,0x04,0x02,0x04,0x05,0xC4,0x08,0x30,0x30,/*"凌",1*/

"派",0x00,0x10,0x04,0x3C,0xE8,0x03,0x28,0x00,0x21,0x38,0xA2,0x07,0xA2,0x04,0xA8,0x44,

0xA8,0x24,0xA4,0x14,0xA7,0x08,0xA4,0x08,0xA4,0x10,0x94,0x22,0x94,0x41,0x88,0x00,/*"派",2*/

};

......

当程序需要将某一个特定字号的汉字投射到LCD液晶屏时,程序就根据对应的字号查找对应字号的tfontXX数组,并将对应的像素行数据发送给LCD液晶屏。具体源代码如下所示。

voidlcd_show_chinese(uint16_tx,uint16_ty,uint8_t*s,uint16_tfc,uint16_tbc,uint8_tsizey,uint8_tmode)

{

uint8_tbuffer[];

uint32_tbuffer_len=0;

uint32_tlen=strlen(s);

memset(buffer,0,sizeof(buffer));

/*utf8格式汉字转化为ascii格式*/

chinese_utf8_to_ascii(s,strlen(s),buffer,buffer_len);

for(uint32_ti=0;ibuffer_len;i+=2,x+=sizey)

{

if(sizey==12)

{

lcd_show_chinese_12x12(x,y,buffer[i],fc,bc,sizey,mode);

}

elseif(sizey==16)

{

lcd_show_chinese_16x16(x,y,buffer[i],fc,bc,sizey,mode);

}

elseif(sizey==24)

{

lcd_show_chinese_24x24(x,y,buffer[i],fc,bc,sizey,mode);

}

elseif(sizey==32)

{

lcd_show_chinese_32x32(x,y,buffer[i],fc,bc,sizey,mode);

}

else

{

return;

}

}

}

四、编译过程

1、打开sdk下面路径的文件

/vendor/lockzhiner/rk/samples/b4_lcd/lcd_example.c

注意:Gitee已有相关源代码,请大家根据上述的需求修改相关源代码。

网址:

转载请注明:http://www.abuoumao.com/hyls/2428.html

网站简介| 发布优势| 服务条款| 隐私保护| 广告合作| 网站地图| 版权申明

当前时间: 冀ICP备19029570号-7