两线串行控制的图形点阵LCD 128x64 ,程序软件上如何画点和线 ?
有没有做过的高手,请教一下~
我正好以前用过串行驱动的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();
}
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |