分类: LINUX
2008-05-06 01:17:54
前
一段时间想搞一下点阵LCD,于是就到本网站上寻找,找到了好多资料,xiaotanlan朋友的资料很好,http:
//
但是看了已后,觉得自已做的时候还是有很多要注意的地方.于是就写了下面的内容: LCD12864液晶说明(个人跟椐datasheet的理解): lcd12864分为左半屏和右半屏,每半个屏幕竖着排列着64(0~63)个字节,每个字节最低位在最上面,高位在最下面,一个字节的8位构成了lcd12864一页中一列的8个点,而它共有8页,即在y方向有8*8=64个点.如下图: 画点的重点: 1,通过x坐标所属的左右半屏. 2,通过y坐标算出点所属的页,及一页内y坐标(即一个字节中一位的位置). 3,读出原来要画点位字节内容,再设要画的点(否则会擦除原来画的点). 程序如下: 环境:ATmega8L, WinAVR GCC, LCD12864, Proteus6.7 /* ATmega8L LCD12864 作者:zhb2000 */ #include #define uchar unsigned char #define uint unsigned int #define bool unsigned char #define true 1 #define false 0 #define setbit(sfr,bit) (sfr|=(1< #define RW 1 #define CS1 2 #define CS2 3 #define E 4 #define RST 5 #define DATA PORTB #define CTRL PORTC void init(void); uchar getState(void); //得到LCD状态字 bool lcdBusy(void); void lcdCommand(uchar command); //发送命令字 void lcdOpen(void); //打开LCD void lcdStartLine(uchar line); //设置起始行 void lcdSetPage(uchar page); //设置页地址 void lcdSetRow(uchar row); //设置列地址 void lcdWrite(uchar dat,uchar cs); //写显示数据,注'0'亮'1'暗 uchar lcdRead(uchar cs); //读数据 void pixel(uchar x,uchar y); //画点 int main(void) { init(); lcdOpen(); lcdStartLine(0); lcdSetPage(0); lcdSetRow(0); pixel(30,30); pixel(100,50); pixel(15,40); while(1) { } return 0; } void init() { PORTB=0xff; DDRB=0xff; PORTC=0xff; DDRC=0xff; PORTD=0xff; DDRD=0xff; } uchar getState() { PORTB=0xff; DDRB=0x0; clrbit(CTRL,CS1); clrbit(CTRL,CS2); clrbit(CTRL,RS); setbit(CTRL,RW); setbit(CTRL,E); //下降沿 clrbit(CTRL,E); return PINB; } bool lcdBusy() { uchar state=0; state=getState(); if(state&0x80) { //BUSY return true; } else { //idle return false; } } void lcdCommand(uchar command) { DDRB=0xff; clrbit(CTRL,CS1); clrbit(CTRL,CS2); clrbit(CTRL,RS); clrbit(CTRL,RW); DATA=command; setbit(CTRL,E); //下降沿 clrbit(CTRL,E); } void lcdOpen() { while(lcdBusy()); lcdCommand(0x3f); } void lcdStartLine(uchar line) { line|=0xc0; while(lcdBusy()); lcdCommand(line); } void lcdSetPage(uchar page) { page&=0x7; page|=0xb8; while(lcdBusy()); lcdCommand(page); } void lcdSetRow(uchar row) { //设置列地址 row&=0x3f; row|=0x40; while(lcdBusy()); lcdCommand(row); } void lcdWrite(uchar dat,uchar cs) { //写显示数据 while(lcdBusy()); DDRB=0xff; if(cs==1) { //选择左半屏 clrbit(CTRL,CS1); setbit(CTRL,CS2); } else { //选择右半屏 clrbit(CTRL,CS2); setbit(CTRL,CS1); } setbit(CTRL,RS); clrbit(CTRL,RW); DATA=dat; setbit(CTRL,E); //下降沿 clrbit(CTRL,E); } uchar lcdRead(uchar cs) { //读数据 uchar dat; while(lcdBusy()); DDRB=0x00; PORTB=0xff; if(cs==1) { //选择左半屏 clrbit(CTRL,CS1); setbit(CTRL,CS2); } else { //选择右半屏 clrbit(CTRL,CS2); setbit(CTRL,CS1); } setbit(CTRL,RS); setbit(CTRL,RW); setbit(CTRL,E); //下降沿 clrbit(CTRL,E); setbit(CTRL,E); //高 dat=PINB; return dat; } void pixel(uchar x,uchar y) { uchar page,dX,dY; uchar cs=2; uchar dot=0; if(x>=64) { x-=64; } else { cs=1; } dX=x; //算出x坐标 page=y/8; //算出页号 dY=y%8; //算出y坐标 lcdSetPage(page); lcdSetRow(dX); dot=lcdRead(cs); clrbit(dot,dY); lcdSetPage(page); lcdSetRow(dX); lcdWrite(dot,cs); } Proteus6.7仿真: 原程序及仿真文件: 希望对想学LCD12864点阵液晶的朋友有所帮助. -----此内容被zhb2000于2006-03-01,10:56:12编辑过 |
|||
2006-03-01,10:40:49 |
|
【1楼】 benladn911 AVR猎手 积分:1613 派别: 等级:------ 来自:福建厦门 |
好贴,顶。 | ||
__________________________ MSN: lanbing51#hotmail.com Email: lanbing51#126.com (把#号改成@号即可) QQ:149910798 我的 AVR猎手的地盘 : 目前工作:Altium designer 6 现场技术支持(Protel FAE),欢迎和广大工程师交流软件的功能应用 A secret makes a man man... A wound makes a man man... |
|||
2006-03-01,12:22:37 |
|
【2楼】 SKYdai 天空 积分:276 派别: 等级:------ 来自:四川成都 |
好呀!谢谢!! | ||
2006-03-01,20:24:02 |
|
【3楼】 zhb2000 积分:246 派别: 等级:------ 来自: |
今天花了一整天时间才搞好LCD12863显示2色BMP图片(累啊 :) )。
自已还写了一个2色BMP图片到程序数组的转换小程序bmp2txt.exe 读取2色BMP图片,BMP的头结构我就不多说了,很多书上都有。 这里我们主要注意以下几个地方。 BMP文件偏移 0x0a 图像数据的开始位置 0x12 图像的宽度 0x16 图像的高度 0x1e 图像是否压缩 (这里我们只讨论不压缩的,用windows的画笔画一幅画存盘的时候选单色就行了) BMP的2色图像是倒着存放的,即第一个数据字节表示是的图像最后一行的前8 个点"1"表示白色,"0"表示黑色(当然也可跟椐调色板来设置) BMP图片数据每行要DWORD对齐,也是一行的字节数必须为4的倍数,如一行的数 据只有8个点为0xff 而BMP表示为 0xff 0x00 0x00 0x00 然后用bmp2txt.exe 将所画的2色图转为程序代码,copy到程序中编译就OK了。 关键代码: /* 读BMP图像 2色 未压缩 */ #define BMP_HEIGHT 0x16 #define BMP_WIDTH 0x12 #define BMP_COMPRESSION 0x1e #define BMP_bfOffBits 0x0a //COMPRESSION #define BI_RGB 0 #define BI_RLE8 1 #define BI_RLE4 2 #define BI_BITFIELDS 3 const unsigned char Bitmap[1070] PROGMEM={ //bmp2txt.exe生成的图像数据 ...... }; void drawBitmap(const uchar *bmp) { //画图像 signed char x,y; uchar bmpHeight,bmpWidth,wByte; uint lpOffset; uchar dat; uchar nx=0; uchar i; uint numb; lpOffset=pgm_read_byte(bmp+BMP_COMPRESSION); //bmp[BMP_COMPRESSION]; if(lpOffset!=0) return; //只处理未压缩的图像 bmpHeight=pgm_read_byte(bmp+BMP_HEIGHT); //bmp[BMP_HEIGHT]; bmpWidth=pgm_read_byte(bmp+BMP_WIDTH); //bmp[BMP_WIDTH]; lpOffset=pgm_read_byte(bmp+BMP_bfOffBits); //bmp[BMP_bfOffBits] 得到图像数据的偏移量 /* 1.BMP图象为到着存放的:即最后一行的数据存放在最前面 2.2色为一个字节表示一行中的8个像素点 */ if(bmpWidth%8!=0) { wByte=bmpWidth/8+1; } else { wByte=bmpWidth/8; } if(wByte%4!=0) { wByte=(wByte/4+1)*4; //DWORD对齐 } numb=0; for(y=(bmpHeight-1);y>=0;y--) { for(nx=0;nx dat=pgm_read_byte(bmp+lpOffset+numb);// bmp[lpOffset+numb]; numb++; for(i=0;i<8;i++) { if(tstbit(dat,(7-i))==0) { x=nx*8+i; if(x pixel(x,y); } } } } } } 仿真图: 源程序&工具&说明: |