基于ST7565驱动的12864液晶 GB2312汉字库算法程序

2020-01-25 15:25发布

本帖最后由 犯戒和尚 于 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);
                }
        }         
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。