您现在的位置: 主页 > MCU > 单片机学习 > 第74节:在液晶屏中让字体可以跨区域无缝对接显示的算法程序 -
本文所属标签:
为本文创立个标签吧:

第74节:在液晶屏中让字体可以跨区域无缝对接显示的算法程序 -

来源: 网络用户发布,如有版权联系网管删除 2018-08-31 

[导读]从业近十年!手把手教你单片机程序框架 第74讲开场白:细心的网友会发现,这种12864液晶屏在显示自造字库时普遍有个毛病,在坐标轴x方向上是以每16个点阵为一个单位的,如果显示两个8x16字符”V”和”

从业近十年!手把手教你单片机程序框架 第74讲

开场白:

细心的网友会发现,这种12864液晶屏在显示自造字库时普遍有个毛病,在坐标轴x方向上是以每16个点阵为一个单位的,如果显示两个8x16字符”V”和”5”,虽然它们的x坐标轴是相邻的,但是实际显示的效果是中间隔了8个点阵。另外,这种12864液晶屏是由上半屏和下半屏组成的,软件上的坐标体系并没有做到跟物理的坐标体系一致,需要转换的。如果我们想把一个整体字符的一半显示在上半屏,另一半显示在下半屏,那怎么办?

这一节就要教给大家这个算法程序:

为了实现跨区域无缝显示,就先在某个区域显示一块画布,我们只要在这块画布数组中插入字模数组,就可以达到跨区域无缝显示的目的。

具体内容,请看源代码讲解。

(1)硬件平台:

基于朱兆祺51单片机学习板。

(2)实现功能:开机上电后,看到液晶屏所有的点阵都显示。正中间露出一小方块空白的32x16点阵画布,从左到右分别显示“V5”两个字符。这两个字符是紧紧挨在一起的,中间并没有8个点阵的空格,同时这两个字符的上半部分显示在上半屏,下半部分显示在下半屏。实现了真正的跨区域无缝对接显示。

(3)源代码讲解如下:

#include "REG52.H"

sbit LCDCS_dr = P1^6; //片选线

sbit LCDSID_dr = P1^7; //串行数据线

sbit LCDCLK_dr = P3^2; //串行时钟线

sbit LCDRST_dr = P3^4; //复位线

void SendByteToLcd(unsigned char ucData); //发送一个字节数据到液晶模块

void SPIWrite(unsigned char ucWData, unsigned char ucWRS); //模拟SPI发送一个字节的命令或者数据给液晶模块的底层驱动

void WriteCommand(unsigned char ucCommand); //发送一个字节的命令给液晶模块

void LCDWriteData(unsigned char ucData); //发送一个字节的数据给液晶模块

void LCDInit(void); //初始化 函数内部包括液晶模块的复位

void display_clear(unsigned char ucFillDate); // 清屏 全部显示空填充0x00 全部显示点阵用0xff

void insert_buffer_to_canvas(unsigned int x,unsigned int y,const unsigned char *ucArray,unsigned char ucFbFlag,unsigned int x_amount,unsigned int y_amount);//把字模插入画布.

void display_lattice(unsigned int x,unsigned int y,const unsigned char *ucArray,unsigned char ucFbFlag,unsigned int x_amount,unsigned int y_amount,unsigned int uiOffSetAddr); //显示任意点阵函数

void delay_short(unsigned int uiDelayshort); //延时

code unsigned char Zf816_V[]= /*V 横向取模 8x16点阵 每一行只要1个字节,共16行 */

{

0x00,

0x00,

0x00,

0xE7,

0x42,

0x42,

0x44,

0x24,

0x24,

0x28,

0x28,

0x18,

0x10,

0x10,

0x00,

0x00,

};

code unsigned char Zf816_5[]= /*5 横向取模 8x16点阵 每一行只要1个字节,共16行 */

{

0x00,

0x00,

0x00,

0x7E,

0x40,

0x40,

0x40,

0x58,

0x64,

0x02,

0x02,

0x42,

0x44,

0x38,

0x00,

0x00,

};

/* 注释一:

* 为了实现跨区域无缝显示,就先在某个区域显示一块画布,我们只要在这块画布数组中插入字模数组,

* 就可以达到跨区域无缝显示的目的。根据上几节的介绍,12864液晶屏由上下两半屏组成,以下这块画布

* 显示在上半屏和下半屏之间。横向4个字节,纵向16行。其中上半屏显示8行,下半屏显示8行。注意,这个数组

* 不带code关键字,是全局变量,这样可读可写。画布的横向x坐标范围是0至3,因为画布的横向只要4个字节。

* 画布的纵向y坐标范围是0至15,因为画布的纵向只有16行。

*/

unsigned char ucCanvasBuffer[]= //画布显示数组。注意,这里没有code关键字,是全局变量。初始化全部填充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,0x00,

0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,

};

void main()

{

LCDInit(); //初始化12864 内部包含液晶模块的复位

display_clear(0xff); // 清屏 全部显示空填充0x00 全部显示点阵用0xff

insert_buffer_to_canvas(0,0,Zf816_V,0,1,16);//把的字模插入画布

insert_buffer_to_canvas(1,0,Zf816_5,0,1,16);//把<5>的字模插入画布

display_lattice(3,24,ucCanvasBuffer,0,4,8,0); //显示上半屏的画布,最后的参数0是偏移量

display_lattice(11,0,ucCanvasBuffer,0,4,8,32); //显示下半屏的画布,最后的参数32是偏移量

while(1)

{

;

}

}

void display_clear(unsigned char ucFillDate) // 清屏 全部显示空填充0x00 全部显示点阵用0xff

{

unsigned char x,y;

WriteCommand(0x34); //关显示缓冲指令

WriteCommand(0x34); //关显示缓冲指令 故意写2次,怕1次关不了 这个是因为我参考到某厂家的驱动程序也是这样写的

y=0;

while(y<32) //y轴的范围0至31

{

WriteCommand(y+0x80); //垂直地址

WriteCommand(0x80); //水平地址

for(x=0;x<32;x++) //256个横向点,有32个字节

{

LCDWriteData(ucFillDate);

}

y++;

}

WriteCommand(0x36); //开显示缓冲指令

}

/* 注释二:

* 把字模插入画布的函数.

* 这是本节的核心函数,读者尤其要搞懂x_amount和y_amount对应的显示关系。

* 第1,2个参数x,y是在画布中的坐标体系。

* x的范围是0至3,因为画布的横向只要4个字节。y的范围是0至15,因为画布的纵向只有16行。

* 第3个参数*ucArray是字模的数组。

* 第4个参数ucFbFlag是反白显示标志。0代表正常显示,1代表反白显示。

* 第5,6个参数x_amount,y_amount分别代表字模数组的横向有多少个字节,纵向有几横。

*/

void insert_buffer_to_canvas(unsigned int x,unsigned int y,const unsigned char *ucArray,unsigned char ucFbFlag,unsigned int x_amount,unsigned int y_amount)

{

unsigned int j=0;

unsigned int i=0;

unsigned char ucTemp;

for(j=0;j

{

for(i=0;i

{

ucTemp=ucArray[j*x_amount+i];

if(ucFbFlag==0)

{

ucCanvasBuffer[(y+j)*4+x+i]=ucTemp; //这里的4代表画布每一行只有4个字节

}

else

{

ucCanvasBuffer[(y+j)*4+x+i]=~ucTemp; //这里的4代表画布每一行只有4个字节

}

}

}

}

/* 注释三:

* 显示任意点阵函数.

* 注意,本函数在前几节的基础上多增加了第7个参数uiOffSetAddr,它是偏移地址。

* 对于这个函数,读者尤其要搞懂x_amount和y_amount对应的显示关系。

* 第1,2个参数x,y是坐标体系。x的范围是0至15,y的范围是0至31.

* 第3个参数*ucArray是字模的数组。

* 第4个参数ucFbFlag是反白显示标志。0代表正常显示,1代表反白显示。

* 第5,6个参数x_amount,y_amount分别代表字模数组的横向有多少个字节,纵向有几横。

* 第7个参数uiOffSetAddr是偏移地址,代表字模数组的从第几个数据开始显示。

*/

void display_lattice(unsigned int x,unsigned int y,const unsigned char *ucArray,unsigned char ucFbFlag,unsigned int x_amount,unsigned int y_amount,unsigned int uiOffSetAddr)

{

unsigned int j=0;

unsigned int i=0;

unsigned char ucTemp;

WriteCommand(0x34); //关显示缓冲指令

WriteCommand(0x34); //关显示缓冲指令 故意写2次,怕1次关不了 这个是因为我参考到某厂家的驱动程序也是这样写的

for(j=0;j

{

WriteCommand(y+j+0x80); //垂直地址

WriteCommand(x+0x80); //水平地址

for(i=0;i

{

ucTemp=ucArray[j*x_amount+i+uiOffSetAddr]; //uiOffSetAddr是字模数组的偏移地址

if(ucFbFlag==1) //反白显示

{

ucTemp=~ucTemp;

}

LCDWriteData(ucTemp);

// delay_short(30000); //把上一节这个延时函数去掉,加快刷屏速度

}

}

WriteCommand(0x36); //开显示缓冲指令

}

void SendByteToLcd(unsigned char ucData) //发送一个字节数据到液晶模块

{

unsigned char i;

for ( i = 0; i < 8; i++ )

{

if ( (ucData << i) & 0x80 )

{

LCDSID_dr = 1;

}

else

{

LCDSID_dr = 0;

}

LCDCLK_dr = 0;

LCDCLK_dr = 1;

}

}

void SPIWrite(unsigned char ucWData, unsigned char ucWRS) //模拟SPI发送一个字节的命令或者数据给液晶模块的底层驱动

{

SendByteToLcd( 0xf8 + (ucWRS << 1) );

SendByteToLcd( ucWData & 0xf0 );

SendByteToLcd( (ucWData << 4) & 0xf0);

}

void WriteCommand(unsigned char ucCommand) //发送一个字节的命令给液晶模块

{

LCDCS_dr = 0;

LCDCS_dr = 1;

SPIWrite(ucCommand, 0);

delay_short(90);

}

void LCDWriteData(unsigned char ucData) //发送一个字节的数据给液晶模块

{

LCDCS_dr = 0;

LCDCS_dr = 1;

SPIWrite(ucData, 1);

}

void LCDInit(void) //初始化 函数内部包括液晶模块的复位

{

LCDRST_dr = 1; //复位

LCDRST_dr = 0;

LCDRST_dr = 1;

}

void delay_short(unsigned int uiDelayShort) //延时函数

{

unsigned int i;

for(i=0;i

{

;

}

}

总结陈词:

经过这一节的算法处理后,字符终于可以在x轴上紧紧挨着显示了。也就是把原来x坐标是16个点阵为一个单位,改成了以8个点阵为一个单位。如果要求以1个点阵为单位显示,那该怎么办?这个还真有点难度,因为横向的最小显示单位就是一个字节8个点,不过鸿哥在下一节中照样有办法实现这个功能。欲知详情,请听下回分解-----在12864液晶屏中让字体以1个点阵为单位进行移动显示的算法程序。



              查看评论 回复



嵌入式交流网主页 > MCU > 单片机学习 > 第74节:在液晶屏中让字体可以跨区域无缝对接显示的算法程序 -
 

"第74节:在液晶屏中让字体可以跨区域无缝对接显示的算法程序 -"的相关文章

网站地图

围观()