本帖最后由 犯戒和尚 于 2013-5-27 11:14 编辑
基于ST7565驱动的12864液晶 GB2312汉字库算法程序
ST7565液晶驱动芯片工作原理:
在16*16的点阵中先竖着写8位,然后写完16列,再到第二行竖着写8位,写完16列。
GB2312字库是横着写16位,然后写16行。
所以ST7565驱动GB1312字库需要写一个算法函数,具体如下:
/*
*********************************************************************************************************
*函数名称: WR_CMD
*功能描述: 向已指向的寄存器写命令
*输入参数:
* LCD_cmd : 写入的内容 16位数据
*返 回 值: 无
*********************************************************************************************************
*/
void WR_CMD(unsigned int LCD_cmd)
{
CLEAR_LCD_CS;
DELAY_NOP();
DELAY_NOP();
CLEAR_LCD_RS;
DELAY_NOP();
DELAY_NOP();
CLEAR_LCD_RD;
DELAY_NOP();
DELAY_NOP();
CLEAR_LCD_WR;
DELAY_NOP();
DELAY_NOP();
P1=LCD_cmd;
DELAY_NOP();
DELAY_NOP();
SET_LCD_RD;
DELAY_NOP();
DELAY_NOP();
SET_LCD_CS;
DELAY_NOP();
DELAY_NOP();
CLEAR_LCD_RD;
DELAY_NOP();
DELAY_NOP();
}
/*
*********************************************************************************************************
*函数名称: WR_DATA
*功能描述: 向RAM中写显示数据
*输入参数:
* LCD_data : 写入的内容 16位数据
*返 回 值: 无
*********************************************************************************************************
*/
void WR_DATA(unsigned int LCD_data)
{
CLEAR_LCD_CS;
DELAY_NOP();
DELAY_NOP();
SET_LCD_RS;
DELAY_NOP();
DELAY_NOP();
CLEAR_LCD_RD;
DELAY_NOP();
DELAY_NOP();
CLEAR_LCD_WR;
DELAY_NOP();
DELAY_NOP();
P1=LCD_data;
DELAY_NOP();
DELAY_NOP();
SET_LCD_RD;
DELAY_NOP();
DELAY_NOP();
SET_LCD_CS;
DELAY_NOP();
DELAY_NOP();
CLEAR_LCD_RD;
DELAY_NOP();
DELAY_NOP();
}
/*
*********************************************************************************************************
*函数名称: LCD_delayms
*功能描述: 延时多少ms,在40Mhz,首先计算1ms的间隔然后进行多次循环
*输入参数:
* delay : 延时多少时间
*返 回 值: 无
*********************************************************************************************************
*/
void LCD_delayms(unsigned int delay)
{
unsigned int opp=0, p=0;
for(p=0;p<delay;p++)
{
opp=2860;
do opp--;
while(opp>0);
}
}
/*
*********************************************************************************************************
*函数名称: Mlcd_Init
*功能描述: 液晶屏初始化
*输入参数: 无
*返 回 值: 无
*********************************************************************************************************
*/
void Mlcd_Init(void)
{
SET_LCD_LED;
CLEAR_LCD_CS ;
DELAY_NOP();
DELAY_NOP();
CLEAR_LCD_RESET; /*低电平复位*/
LCD_delayms(100);
SET_LCD_RESET; /*复位完毕*/
LCD_delayms(20);
WR_CMD(0x00E2); /*软复位*/
LCD_delayms(50);
WR_CMD(0x002C); /*升压步聚*/
LCD_delayms(50);
WR_CMD(0x002E); /*升压步聚*/
LCD_delayms(50);
WR_CMD(0x002F); /*升压步聚*/
LCD_delayms(50);
WR_CMD(0x0024); /*粗调对比度,可设置范围x20~x27*/
WR_CMD(0x0081); /*微调对比度*/
WR_CMD(0x002C);
/*0x1a,微调对比度的值,可设置范围x00~x3f*/
WR_CMD(0x00A2); /*1/9偏压比(bias)*/
WR_CMD(0x00C8); /*行扫描顺序:从上到下*/
WR_CMD(0x00A0); /*列扫描顺序:从左到右*/
WR_CMD(0x0060); /*起始行:第一行开始*/
WR_CMD(0x00AF); /*开显示*/
LCD_delayms(10);
SET_LCD_CS;
}
/*
*********************************************************************************************************
*函数名称: lcd_address
*功能描述: 设置地址
*输入参数: hang lie
*返回值 : 无
*********************************************************************************************************
*/
void lcd_address(unsigned char hang,unsigned char lie)
{
CLEAR_LCD_CS;
lie=(lie<<3);
WR_CMD(0xb0+hang); //设置行地址。每行是 8 小行。一个画面的 64 小行被分成 8 个行。
WR_CMD(((lie>>4)&0x0f)+0x10); //设置列地址的高 4 位
WR_CMD(lie&0x0f); //设置列地址的低 4 位
}
/*
*********************************************************************************************************
*函数名称: clear_screen()
*功能描述: 全屏清屏
*输入参数: 无
*返回值 : 无
*********************************************************************************************************
*/
void clear_screen(void)
{
unsigned char i,j;
CLEAR_LCD_CS;
for(i=0;i<9;i++)
{
lcd_address(i,0);
for(j=0;j<132;j++)
{
WR_DATA(0x00);
}
}
SET_LCD_CS;
}
/*
*********************************************************************************************************
*函数名称: wr_word
*功能描述: 在某行某列插入某个汉字
*输入参数:
* hang, lie: 决定显示位置
* data[32] : 显示内容
*返 回 值: 无
*********************************************************************************************************
*/
void wr_word(unsigned char hang,unsigned char lie,unsigned char data[32])
{
unsigned int i=0,j=0,k=0,m=0,addr=0;
unsigned int a=0;
hang=hang*2;
if(hang>3)
{
hang=hang-4;
}
else
{
hang=hang+4;
}
CLEAR_LCD_CS;
for(j=0;j<2;j++)
{
lcd_address(hang+j,lie);
for(m=0;m<2;m++)
{
for (i=0;i<8;i++) //转换8位数据
{
addr+=14; //从第14个字节第一位开始
for (k=0;k<8;k++)
{
a|=(data[addr]&0x80); //取最高位
data[addr]=(data[addr]<<1); //数据左移,为下次做准备
addr=addr-2; //减两个字节
a=(a<<1);
}
a=(a>>8);
WR_DATA(a);
a=0;
addr+=2; //此处addr已经减为-2,所以要加2
}
addr++; //写完前8列,开始写后8列
}
addr+=14; //写完第一行,开始写第二行
}
addr=0;
SET_LCD_CS;
}
/*
*********************************************************************************************************
*函数名称: wr_byte
*功能描述: 在某行某列插入某个数字或者字母或者其他特殊符号
*输入参数:
* hang, lie: 决定显示位置
* data[32] : 显示内容
*返 回 值: 无
*********************************************************************************************************
*/
void wr_byte(unsigned char hang,unsigned char lie,unsigned char data[32])
{
unsigned int i=0,j=0,k=0,addr=0;
unsigned int a=0;
hang=hang*2;
if(hang>3)
{
hang=hang-4;
}
else
{
hang=hang+4;
}
CLEAR_LCD_CS;
for(j=0;j<2;j++)
{
lcd_address(hang+j,lie);
for (i=0;i<8;i++)
{
addr+=7;
for (k=0;k<8;k++)
{
a|=(data[addr]&0x80);
data[addr]=(data[addr]<<1);
addr--;
a=(a<<1);
}
a=(a>>8);
WR_DATA(a);
a=0;
addr++;
}
addr+=8;
}
addr=0;
SET_LCD_CS;
}
/*
*********************************************************************************************************
*函数名称: test_display
*功能描述: LCD测试函数,雪花测试
*输入参数: data1,data2
*返 回 值: 无
*********************************************************************************************************
*/
void test_display(unsigned char data1,unsigned char data2)
{
int i,j;
for(j=0;j<8;j++)
{
CLEAR_LCD_CS;
lcd_address(j,0);
for(i=0;i<128;i++)
{
WR_DATA(data1);
WR_DATA(data2);
}
}
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
一周热门 更多>