这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » 软件与操作系统 » 两线串行控制的图形点阵LCD128x64,程序软件上如何画点和线?

共5条 1/1 1 跳转至

两线串行控制的图形点阵LCD128x64,程序软件上如何画点和线?

工程师
2020-04-16 22:16:01     打赏

两线串行控制的图形点阵LCD 128x64 ,程序软件上如何画点和线 ?

有没有做过的高手,请教一下~





关键词: 128x64     12864     图形点阵     LCD     GUI    

工程师
2020-04-16 23:05:04     打赏
2楼

不能读数据的话,只能在MCU里面划分一段1K RAM,对应屏幕上的点,更新RAM后全屏刷新


工程师
2020-04-16 23:10:15     打赏
3楼

我正好以前用过串行驱动的LCD,参考我下面的源码吧!

#include "Globals.h"


#define LCD_RST_1                GPIO_SetBits(GPIOA,GPIO_Pin_11)

#define LCD_RST_0                GPIO_ResetBits(GPIOA,GPIO_Pin_11)


#define LCD_CS_1                GPIO_SetBits(GPIOC,GPIO_Pin_8)

#define LCD_CS_0                GPIO_ResetBits(GPIOC,GPIO_Pin_8)


#define LCD_CLK_1                GPIO_SetBits(GPIOA,GPIO_Pin_8)

#define LCD_CLK_0                GPIO_ResetBits(GPIOA,GPIO_Pin_8)


#define LCD_SID_1                GPIO_SetBits(GPIOC,GPIO_Pin_9)

#define LCD_SID_0                GPIO_ResetBits(GPIOC,GPIO_Pin_9)


void Mmemcpy(unsigned char *Out,const char *In, unsigned char L)

{        unsigned char i;for(i=0;i<L;i++)Out[i]=In[i];        

}


unsigned char LCDdat[64];//此处不能用 idata 显示缓存


void write(char cmd, unsigned char dat) //写指令或数据

{        unsigned char i,j,Temp;

        

        LCD_CS_1;

        LCD_CLK_0; 

        

        for(j=0;j<3;j++)    

        {             

                         if (j==0){ Temp =( cmd? 0xfa:0xf8);} //数据cmd=1:0xfa 命令cmd=0:0xf8

                else if (j==1){ Temp =((dat<<0) & 0xf0);}

                else if (j==2){ Temp =((dat<<4) & 0xf0);}

                

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

                {  

                        (Temp&0x80)?(LCD_SID_1):(LCD_SID_0);  Temp<<=1; delay_us(1); //左移

                        LCD_CLK_1; delay_us(1);   //_nop_();_nop_();//移入  

                        LCD_CLK_0; delay_us(1);   //_nop_();_nop_();_nop_(); //读出

                }                      //_nop_();_nop_();_nop_();_nop_(); //延时

        }   

        LCD_CS_0; 

}        


void LCD_setWhite2(unsigned char x,unsigned char y,unsigned char left,unsigned char right)

{

        unsigned char i;

        if(y>1)

        {

                y-=2;

                x+=8;

        }

        write(0,0x34); 

        write(0,0x36); 

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

        {

                write(0,0x80+i+y*16);

                write(0,0x80+x); 

                write(1,left);

                write(1,right); 

        }

//        write(0,0x36);

        write(0,0x30);

}


void LCD_ClearGM(void)

{

        unsigned char i,j;

        write(0,0x34); 

        write(0,0x36); 

        for(j=0;j<32;j++)

        {

                write(0,0x80+j);

                write(0,0x80); 

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

                {

                        write(1,0x00);

                }

        }

        for(j=0;j<32;j++)

        {

                write(0,0x80+j);

                write(0,0x88); 

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

                {

                        write(1,0x00);

                }

        }

        write(0,0x30);

}



void LCD_RefreshALL(void) //模拟刷屏12864

{        

        unsigned char X,Y,Addr; 

        

        for(X=0;X<4;X++) //送四行汉字

        {        switch(X)   //一次送一个汉字 

                {        case 0: Addr=0x80;break;

                        case 1: Addr=0x90;break;

                        case 2: Addr=0x88;break;

                        case 3: Addr=0x98;break;        

                        default:Addr=0x80;break;

                }   write(0,Addr); //先送地址后送16个字符

                for(Y=0;Y<16;Y++){write(1,LCDdat[(X*16)+Y]);} 

        }

}



//测试

void LCD_Test(void)

{

        const char Tab[][16]={

                {"                "},

                {"                "},

                {"                "},

                {"                "},

                }; 


         

        Mmemcpy(LCDdat+0, Tab[0],16); //送出

        Mmemcpy(LCDdat+16,Tab[1],16); //送出

        Mmemcpy(LCDdat+32,Tab[2],16); //送出

        Mmemcpy(LCDdat+48,Tab[3],16); //送出

        

        LCD_RefreshALL(); //更新显示

        

}


void LCD_Clear(void)

{

        const char Tab[][16]={

                {"                "},

                {"                "},

                {"                "},

                {"                "},

                }; 


         

        Mmemcpy(LCDdat+0, Tab[0],16); //送出

        Mmemcpy(LCDdat+16,Tab[1],16); //送出

        Mmemcpy(LCDdat+32,Tab[2],16); //送出

        Mmemcpy(LCDdat+48,Tab[3],16); //送出

        

        LCD_RefreshALL(); //更新显示

        LCD_ClearGM();

}


//显示一行

void LCD_ShowLine(unsigned char y,char *pStr)

{

        Mmemcpy(LCDdat+16*y, pStr,16); //送出

//        printf("==%s \r\n",pStr);


        LCD_RefreshALL(); //更新显示

}


//此函数有个缺陷,就是无法知道二维字符串的一维的长度,会把后面的字符串也显示出来

void LCD_ShowString(unsigned char x,unsigned char y,const char *pStr)

{

        unsigned char i;

        unsigned int strLen;

//        unsigned char strBuff[16];        //一行字符缓存

        strLen = strlen(pStr);        //字符串长度用 strlen(); 类型长度 sizeof();

//        if(strLen>16) strLen = 16;

//        strLen = (sizeof(pStr)/sizeof(pStr[0]));

//        printf("Str Len=%d \r\n",strLen);

        if(strLen>16) strLen = 16;        //一行总长度最多显示16个字符,多余的不显示

        else if(strLen==0) return;        //空

        

//        memset(strBuff,' ',sizeof(strBuff));

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

        {

                LCDdat[16*y+x+i] = pStr[i];

        }

        LCD_RefreshALL(); //更新显示

}


void LCD_ShowStringLen(unsigned char x,unsigned char y,const char *pStr,unsigned char len)

{

        unsigned char i;

        unsigned int strLen;

//        unsigned char strBuff[16];        //一行字符缓存

        strLen = len;        //字符串长度用 strlen(); 类型长度 sizeof();

//        if(strLen>16) strLen = 16;

//        strLen = (sizeof(pStr)/sizeof(pStr[0]));

//        printf("Str Len=%d \r\n",strLen);

        if(strLen>16) strLen = 16;        //一行总长度最多显示16个字符,多余的不显示

        else if(strLen==0) return;        //空

        

//        memset(strBuff,' ',sizeof(strBuff));

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

        {

                LCDdat[16*y+x+i] = pStr[i];

        }

        LCD_RefreshALL(); //更新显示

}


void LCD_ShowNumber(unsigned char x,unsigned char y,long num,unsigned char disLen,unsigned char align)

{

        unsigned char i;

        char strBuff[16];        //一行字符缓存

        char disBuff[16];        //一行字符缓存用于显示

        unsigned int strLen;        //字符串长度用 strlen(); 类型长度 sizeof();

        

        if(disLen>16 || disLen==0) return;

        

        memset(strBuff,0,sizeof(strBuff));

        memset(disBuff,0,sizeof(disBuff));

        sprintf(strBuff,"%ld",num);

        strLen = strlen(strBuff);

//        printf("%s : ",strBuff);

//        printf("%d \r\n",strLen);

        

        if(align==0)        //左对齐

        {

                if(strLen>=disLen)        //当数字位数大于要显示的长度时,显示高位

                {

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

                        {

                                disBuff[i] = strBuff[i];

                        }

                }

                else

                {

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

                        {

                                if(i<strLen)

                                        disBuff[i] = strBuff[i];

                                else

                                        disBuff[i] = ' ';        //后面补空格

                        }

                }

        }

        else        //右对齐

        {

                if(strLen>=disLen)        //当数字位数大于要显示的长度时,显示高位

                {

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

                        {

                                disBuff[i] = strBuff[i];

                        }

                }

                else

                {

                        unsigned char dx = disLen-strLen;

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

                        {

                                if(i<dx)

                                        disBuff[i] = ' ';        //前面补空格

                                else

                                        disBuff[i] = strBuff[i-dx];

                        }

                }

        }

        

        LCD_ShowString(x,y,disBuff);

        

        

        LCD_RefreshALL(); //更新显示

}


/**********************************

          LCD初始化 

**********************************/


void LCD_Config(void)

{

        GPIO_InitTypeDef GPIO_InitStructure;

        

//        RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC, ENABLE );

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9;

        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;

        GPIO_Init(GPIOC, &GPIO_InitStructure);

        

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_11;

        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;

        GPIO_Init(GPIOA, &GPIO_InitStructure);

        

        LCD_RST_0;         delay_ms(500);

        LCD_RST_1;         delay_ms(500);//复位 

        write(0,0x30);  //8 位介面,基本指令集

        write(0,0x0c);  //显示打开,光标关,反白关

        write(0,0x01);  //清屏,将DDRAM的地址计数器归零 


        delay_ms(500);

        LCD_Clear();

        LCD_Test();

        

 }




工程师
2020-04-16 23:14:15     打赏
4楼

Bresenham算法是点阵屏上画直线的基础方法,可以找找看。


工程师
2020-04-16 23:19:17     打赏
5楼

2线的优势就是  省io  ,但是耗时(+耗ram+耗flash)


共5条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]