|
控制器7920
代碼沒(méi)啥好說(shuō),我盡量多寫了注釋,播放動(dòng)畫也很流暢的
亮點(diǎn)就是支持中英文混合輸出,其他沒(méi)啥
昨天發(fā)現(xiàn)座的公交車上用的也是這種12864 ,顯示溫度和時(shí)間...
完整源碼下載:
lcd12864源碼.rar
(7.58 KB, 下載次數(shù): 32)
2017-2-9 22:24 上傳
點(diǎn)擊文件名下載附件
c語(yǔ)言程序:
- #ifndef _LCD12864_H
- #define _LCD12864_H
- #include "my51.h"
- #define LCD_dataBus P0 //總線
- sbit LCD_EN = P3^4; //使能控制
- sbit LCD_RS = P3^5; //數(shù)據(jù)_命令選擇端
- sbit LCD_RW = P3^6; //讀寫控制
- sbit LCD_PSB= P3^7; //串并選擇,H并行,L串行
- extern bool bShowPicFlag; //繪圖時(shí)圖像顯示控制(僅控制GDRAM)
- /*************************基本功能函數(shù)*********************************************/
- extern void LCD12864_init(); //初始化,必須置頂調(diào)用
- extern void LCD12864_setPos(u8 row, u8 cols); //設(shè)置光標(biāo)位置
- extern void LCD12864_writeByte(u8 dat); //寫一個(gè)字節(jié)
- extern void LCD12864_writeCmd(u8 cmd); //寫指令
- extern u8 LCD12864_readByte(); //讀一個(gè)字節(jié)ram
- extern u8 LCD12864_readIR(); //讀暫存器
- extern bool LCD12864_isBusy(); //判忙
- /*************************調(diào)用基本字庫(kù)顯示文字**************************************/
- //獨(dú)創(chuàng)支持全角半角字符及中英混合的字符串,或字符串的子串,起始行號(hào)row(0-3)和列坐標(biāo)cols(0-15),寫滿屏幕為止
- //行號(hào)4-7行是滾動(dòng)區(qū)
- extern void LCD12864_writeData(u8 row, u8 cols,u8* pBuf,u8 dataSize);//寫一堆數(shù)據(jù)
- extern void LCD12864_earseSomeDDRam(u8 row,u8 cols,u8 dataSize); //擦除N字節(jié)DDRam
- /*************************用戶自定義圖標(biāo)字體****************************************/
- extern void LCD12864_writeCGRAM(u8 userRamNum,u8* pCGRAM_userCode); //寫自定義圖標(biāo)字體
- extern void LCD12864_showCGRAM(u8 row,u8 cols,u8 num) ; //顯示自定義圖標(biāo)字體,row(0-3),cols(0-15)
- extern void LCD12864_clearCGRAM(u8 CGRAM_groupNum) ; //CGRAM清零(初始化也可清0)
- /*************************圖像顯示功能函數(shù)**********************************************/
- extern void LCD12864_showGDRAM(bool bShowImage); //GDRAM繪圖顯示開關(guān)
- extern void LCD12864_clearGDRAM(); //液晶整個(gè)可視區(qū)的GDRAM快速清0
- //前4參數(shù):起始點(diǎn)x(0-7)位址,y(0-63)坐標(biāo),要顯示的寬度(1-128)和高度(1-64)[可顯示從圖像左上角開始的部分區(qū)域]
- //后4參數(shù):圖像代碼地址,圖像本身的寬度(1-128)和高度(1-64), 反白(true反白,false不反白)
- //畫圖填充GDRAM ,注:顯示的區(qū)域或者圖像本身寬度必須是8的倍數(shù)
- extern u8 LCD12864_drawGDRAM(u8 x,u8 y,u8 width,u8 height,u8 *pImageCode,u8 imageWidth,u8 imageHight,bool bReverse);
- extern void LCD12864_drawDot(u8 x,u8 y,u8 flag); //打點(diǎn),x(0-127),y(0-63),flag(0正常,1反白,2清0)
- extern bool LCD12864_drawXYLine(u8 x1, u8 y1,u8 x2, u8 y2,u8 flag); //畫水平或垂直直線
- extern void LCD12864_drawAnyLine(u8 x1, u8 y1,u8 x2, u8 y2,u8 flag) ; //畫任意直線
- extern void LCD12864_drawRectangle(u8 x,u8 y ,u8 width,u8 height,u8 flag);//畫矩形
- extern void LCD12864_drawFillRect(u8 x,u8 y, u8 width,u8 hight,u8 flag); //填充矩形,可對(duì)矩形區(qū)反白或清0
- extern void LCD12864_drawVerticalSquare(u8 x,u8 y,u8 r,u8 flag) ; //畫站立的正方形
- extern void LCD12864_drawCircle(u8 x0,u8 y0,u8 r,u8 flag); //畫圓
- //打點(diǎn)法全屏畫圖有點(diǎn)慢了,打點(diǎn)法反白矩形區(qū)還可以,建議矩形范圍小一些,不然比較慢
- //打點(diǎn)法效果最好,因?yàn)槲淖值木匦螀^(qū)比較小,速度很快
- //不過(guò)繪圖法反白文字效率高,flash空間充裕的建議用繪圖法
- /***************************全屏滾動(dòng)*******************************************/
- //需要滾動(dòng)時(shí),用LCD12864_writeScrollData()函數(shù),參數(shù)和LCD12864_writeData()一樣
- extern void LCD12864_writeScrollData(u8 row,u8 cols,u8* pBuf,u8 dataSize);//寫數(shù)據(jù) (滾動(dòng)模式)
- extern void LCD12864_setScrollPos(u8 row, u8 cols); //設(shè)置滾動(dòng)模式的坐標(biāo)
- extern void LCD12864_showScrollCGRAM(u8 row,u8 cols,u8 CGRAM_groupNum);//用于CGRAM滾動(dòng)顯示前執(zhí)行
- extern void LCD12864_startScroll(u8 scrollNum,u16 delay_ms); //滾動(dòng)開始
- #endif
復(fù)制代碼- #include "lcd12864.h"
- //圖像與文字,圖像與用戶圖標(biāo),像素重合時(shí)是異或關(guān)系
- //文字與用戶圖標(biāo)是覆蓋關(guān)系
- bool bShowPicFlag=false; //繪圖時(shí)圖像顯示控制
- /*
- u8 LCD12864_table[]={"123456789"};
- */
- void LCD12864_drawFillRect(u8 x,u8 y, u8 width,u8 hight,u8 flag)//填充任意位置的整個(gè)矩形
- {//矩形起始坐標(biāo)x(0-127),y(0-63),寬(1-128)高(1-64),flag有3種值,0正常填充,1反色,2清0
- u8 i=0;
- u8 j=0;
- if(0==width||0==hight) //矩形寬度或高度為0時(shí)返回
- {
- return ;
- }
- if( (x+width>128 ||(y+hight)>64) )
- {
- led2=0;
- return;
- }
- for(j=0;j<hight;j++)
- {
- for(i=0;i<width;i++)
- {
- LCD12864_drawDot(x+i, y+j,flag);
- }
- }
- }
- void LCD12864_drawRectangle(u8 x,u8 y, u8 width,u8 hight,u8 flag)//畫矩形
- { //矩形起始坐標(biāo)x(0-127),y(0-63),寬度(1-128)和高度(1-64) flag有3種值,0正常寫1,1反色,2清0
- if(0==width||0==hight) //矩形寬度或高度為0時(shí)返回
- {
- return ;
- }
- width--;hight--;
- LCD12864_drawXYLine(x, y,x+width, y, flag);
- LCD12864_drawXYLine(x+width, y,x+width, y+hight, flag);
- LCD12864_drawXYLine(x, y,x, y+hight, flag);
- LCD12864_drawXYLine(x, y+hight,x+width, y+hight, flag);
- }
- bool LCD12864_drawXYLine(u8 x1,u8 y1, u8 x2, u8 y2, u8 flag)//畫水平或垂直直線
- { //起始點(diǎn)坐標(biāo)和終點(diǎn)坐標(biāo),x(0-127),y(0-63), flag有3種值,0正常寫1,1反色,2清0
- u8 n=0;
- if(flag>2|| x1>127||x2>127||y1>63||y2>63)
- {
- return false;
- }
- if(x1==x2)
- {
- for(n=0;n<abs(y2-y1)+1;n++)
- {
- LCD12864_drawDot( x1,y1+(y2>=y1?n:-n) ,flag);
- }
- }
- if(y1==y2)
- {
- for(n=0;n<abs(x2-x1)+1;n++)
- {
- LCD12864_drawDot(x1+(x2>=x1?n:-n),y1,flag) ;
- }
- }
- return true;
- }
- void LCD12864_drawCircle(u8 x0,u8 y0,u8 r,u8 flag)
- {
- s8 a,b;
- s8 di;
- if(r>31 ||r==0) return; //參數(shù)過(guò)濾,次液晶顯示的最大圓半徑為31
- a=0;
- b=r;
- di=3-2*r; //判斷下個(gè)點(diǎn)位置的標(biāo)志
- while(a<=b)
- {
- LCD12864_drawDot(x0-b,y0-a,flag); //3
- LCD12864_drawDot(x0+b,y0-a,flag); //0
- LCD12864_drawDot(x0-a,y0+b,flag); //1
- LCD12864_drawDot(x0-b,y0-a,flag); //7
- LCD12864_drawDot(x0-a,y0-b,flag); //2
- LCD12864_drawDot(x0+b,y0+a,flag); //4
- LCD12864_drawDot(x0+a,y0-b,flag); //5
- LCD12864_drawDot(x0+a,y0+b,flag); //6
- LCD12864_drawDot(x0-b,y0+a,flag);
- a++;
- //使用Bresenham算法畫圓
- if(di<0)
- di +=4*a+6;
- else
- {
- di +=10+4*(a-b);
- b--;
- }
- LCD12864_drawDot(x0+a,y0+b,flag);
- }
- }
- void LCD12864_drawVerticalSquare(u8 x,u8 y,u8 r,u8 flag) //畫站立的正方形
- {
- u8 a,b;
- float c=0;
- a = 0;
- b = r;
- c = 3 - 2*r;
- while(a < b)
- {
- LCD12864_drawDot(x+a,y+b,flag);
- LCD12864_drawDot(x-a,y+b,flag);
- LCD12864_drawDot(x+a,y-b,flag);
- LCD12864_drawDot(x-a,y-b,flag);
-
- LCD12864_drawDot(x+b,y+a,flag);
- LCD12864_drawDot(x-b,y+a,flag);
- LCD12864_drawDot(x+b,y-a,flag);
- LCD12864_drawDot(x-b,y-a,flag);
-
- if(c < 0)
- {
- c = c+4*a + 6;
- }
- else
- {
- c= c + 4*(a - b) + 10;
- b-=1;
- }
- a = a + 1; //控制打點(diǎn)間隔
-
- }
- if(a == b)
- {
- LCD12864_drawDot(x+a,y+b,flag);
- LCD12864_drawDot(x-a,y+b,flag);
- LCD12864_drawDot(x+a,y-b,flag);
- LCD12864_drawDot(x-a,y+b,flag);
-
- LCD12864_drawDot(x+b,y+a,flag);
- LCD12864_drawDot(x-b,y+a,flag);
- LCD12864_drawDot(x+b,y-a,flag);
- LCD12864_drawDot(x-b,y-a,flag);
- }
- }
- void LCD12864_drawAnyLine(u8 StartX, u8 StartY,u8 EndX, u8 EndY, u8 flag) //畫任意直線
- {
- u8 t, distance ; /*根據(jù)屏幕大小改變變量類型(如改為int型)*/
- s16 x = 0 , y = 0 ;
- s8 incx, incy, dx, dy ;
- if((StartX==EndX) ||(StartY==EndY))
- {
- LCD12864_drawXYLine(StartX,StartY,EndX,EndY,flag);
- return;
- }
- dx = EndX - StartX ;
- dy = EndY - StartY ;
- incx = dx > 0 ?1:-1;
- incy = dy > 0 ?1:-1;
- dx = abs( dx );
- dy = abs( dy );
- if( dx > dy )
- {
- distance = dx ;
- }
- else
- {
- distance = dy ;
- }
- LCD12864_drawDot( StartX, StartY, flag ) ; //反白補(bǔ)點(diǎn)
- for( t = 0 ; t <= distance+1 ; t++ )
- {
- LCD12864_drawDot( StartX, StartY, flag ) ;
- x += dx ;
- y += dy ;
- if( x > distance )
- {
- x -= distance ;
- StartX += incx ;
- }
- if( y > distance )
- {
- y -= distance ;
- StartY += incy ;
- }
- }
- }
- void LCD12864_drawDot(u8 x, u8 y,u8 flag) //畫點(diǎn),0打點(diǎn),1反色,2清0
- { //x(0-127),y(0-63),flag有3種值,0正常寫1,1反色,2清0
- u8 x_word=0; //水平(0-127)個(gè)像素中的哪個(gè)字,一字16位
- u8 x_mode=0; //取余
- u8 y_part=0;
- u8 y_bit=0;
- u8 tempH=0;
- u8 tempL=0;
- x_word=x>>4; //在哪一個(gè)字(0-7) ,x_word=x/16
- x_mode=x&0x0f; //在該字的哪一位 ,x_mode= x%16
- y_part=y>>5; //在哪個(gè)屏0或1 ,y_part=y/32
- y_bit= y&0x1f; //垂直方向,y_bit范圍(0-31),y_bit=y%32
- bShowPicFlag?LCD12864_writeCmd(0x36):LCD12864_writeCmd(0x34);
- LCD12864_writeCmd(0x80+y_bit); //垂直坐標(biāo)
- LCD12864_writeCmd(0x80+8*y_part+x_word); //水平位址
-
- LCD12864_readByte();
- tempH=LCD12864_readByte(); //先將該字16位數(shù)據(jù)保存
- tempL= LCD12864_readByte();
-
- LCD12864_writeCmd(0x80+y_bit); //重設(shè)地址,因?yàn)锳C計(jì)數(shù)器變了
- LCD12864_writeCmd(0x80+8*y_part+x_word); //水平位址
- if(0==flag) //不反白,打1,
- {
- if(x_mode<8) //如果x_mode小于8,說(shuō)明點(diǎn)應(yīng)位于該字的左邊高8位中
- {
- LCD12864_writeByte( tempH | bit(7- x_mode) );
- //LCD12864_writeByte(tempL);
- }
- else
- {
- //LCD12864_writeByte(tempH);
- LCD12864_readByte(); //讓AC走半步
- LCD12864_writeByte(tempL|bit(15-x_mode));
- }
- }
- else if(1==flag) //反白,該點(diǎn)與原來(lái)的狀態(tài)相反
- {
- if(x_mode<8) //如果x_mode小于8,說(shuō)明點(diǎn)應(yīng)位于該字的左邊高8位中
- {
- if(tempH & bit(7- x_mode)) //原來(lái)是1
- {
- LCD12864_writeByte( tempH&~bit(7- x_mode) ); //寫0
- }
- else //原來(lái)是0
- {
- LCD12864_writeByte( tempH | bit(7- x_mode) ); //寫1
- }
-
- }
- else
- {
- LCD12864_readByte(); //讓AC走半字
- if(tempL& bit(15-x_mode)) //原來(lái)是1的寫0
- {
-
- LCD12864_writeByte(tempL&~bit(15-x_mode)); //寫0
- }
- else
- {
- LCD12864_writeByte(tempL|bit(15-x_mode)); //寫0
- }
-
- }
- }
- else if(2==flag) //清0
- {
- if(x_mode<8) //如果x_mode小于8,說(shuō)明點(diǎn)應(yīng)位于該字的左邊高8位中
- {
- LCD12864_writeByte( tempH&~bit(7- x_mode) );
- }
- else
- {
- LCD12864_readByte(); //讓AC走半字
- LCD12864_writeByte(tempL&~bit(15-x_mode));
- }
- }
- }
- void LCD12864_showGDRAM(bool bShowImage) //GDRAM圖像顯示開關(guān)
- {
- if(bShowImage) //開啟顯示
- {
- LCD12864_writeCmd(0x36);
- LCD12864_writeCmd(0x30);
- }
- else //關(guān)閉顯示
- {
- LCD12864_writeCmd(0x34);
- LCD12864_writeCmd(0x30);
- }
- }
- //填充GDRAM
- u8 LCD12864_drawGDRAM(u8 x,u8 y,u8 width,u8 height,u8* pImageCode,u8 imageWidth,u8 imageHight,bool bReverse)
- {//前4參數(shù):起始點(diǎn)x(0-7)位址,y(0-63)坐標(biāo),要顯示的寬度(1-128)和高度(1-64)[可顯示從圖像左上角開始的部分區(qū)域]
- //后4參數(shù):圖像代碼地址,圖像本身的寬度(1-128)和高度(1-64), 反白(true反白,false不反白)
- u8 i=0;
- u8 j=0;
- if( height > imageHight ) //檢測(cè)顯示高度,寬度不檢測(cè)不會(huì)亂碼
- { //顯示的高度不能超過(guò)圖片本身高度
- return 0x01; //也就是說(shuō)可顯示圖像的部分區(qū)域(從圖像左上角開始的部分區(qū)域)
- }
- width>>=3; //像素寬度轉(zhuǎn)化為字節(jié)個(gè)數(shù),所以width必須是8的整數(shù)倍
- imageWidth>>=3; //像素寬度轉(zhuǎn)化為字節(jié)個(gè)數(shù),所以width必須是8的整數(shù)倍
- if(bShowPicFlag)
- {
- LCD12864_writeCmd(0x36); //改寫GDRAM時(shí),開啟繪圖顯示,可防止動(dòng)畫顯示時(shí)閃動(dòng)
- }
- else
- {
- LCD12864_writeCmd(0x34); //改寫GDRAM時(shí),關(guān)閉繪圖顯示
- }
- for(j=0;j<height;j++) //寫GDRAM
- {
- if(y+j>31) //地址變換
- {
- LCD12864_writeCmd(0x80+y+j-32); //垂直坐標(biāo)
- LCD12864_writeCmd(0x88+x); //水平位址
- }
- else
- {
- LCD12864_writeCmd(0x80+y+j);
- LCD12864_writeCmd(0x80+x);
- }
- for(i=0;i<width;i++) //水平方向?qū)憯?shù)據(jù),帶反白控制
- {
- LCD12864_writeByte(bReverse?~pImageCode[imageWidth*j+i]:pImageCode[imageWidth*j+i]);
- }
- }
- LCD12864_writeCmd(0x30);
- return 0x02;
- }
- void LCD12864_clearGDRAM() //液晶可視區(qū)的繪圖GDRAM清0
- {
- u8 j=0;
- u8 i=0;
- LCD12864_writeCmd(0x34); //擴(kuò)展指令
- for(j=0;j<64;j++) //垂直方向地址手動(dòng)增加,當(dāng)j=64時(shí)清整個(gè)GDram
- { //我們只要清可視區(qū)的GDRAM就可以了
- LCD12864_writeCmd(0x80+j); //y軸坐標(biāo)
- LCD12864_writeCmd(0x80); //x軸坐標(biāo)
- for(i=0;i<32;i++) //水平方向位址自動(dòng)增加
- {
- LCD12864_writeByte(0x00);
- }
- }
- LCD12864_writeCmd(0x30); //回到基本指令
- }
- /*--------------------------------CGRAM start----------------------------------------------*/
- void LCD12864_clearCGRAM(u8 CGRAM_groupNum)//將用戶自定義編碼區(qū)CGRAM清0
- { //參數(shù)一是CGRAM的4組用戶空間組號(hào)碼(0~3) ,參數(shù)二是用戶自定義圖表或漢字的編碼
- u8 i,addr=0;
- bShowPicFlag?LCD12864_writeCmd(0x36):LCD12864_writeCmd(0x34);//擴(kuò)展指令,繪圖開關(guān)保持
- LCD12864_writeCmd(0x02); //SR等于0,允許設(shè)置卷動(dòng)地址
- LCD12864_writeCmd(0x30); //恢復(fù)為8位并行,基本指令集
- addr=(CGRAM_groupNum<<4)|0x40; //將CGRAM空間號(hào)轉(zhuǎn)換為相應(yīng)存儲(chǔ)地址
- LCD12864_writeCmd(addr); //定位到該位址(用戶空間位址范圍0x40-0x7F共128字節(jié))
- for(i=0;i<16;i++) //將用戶自定義編碼寫入該16*16位元組空間
- {
- LCD12864_writeByte(0); //連續(xù)寫2個(gè)字節(jié)共16位
- LCD12864_writeByte(0);
- }
- }
- void LCD12864_writeScrollCGRAM(u8 CGRAM_groupNum, u8* pUserCode)//將用戶自定義編碼寫入CGRAM
- { //參數(shù)一是CGRAM的4組用戶空間組號(hào)碼(0~3) ,參數(shù)二是用戶自定義圖表或漢字的編碼
- u8 i,addr=0;
- if(bShowPicFlag)
- {
- LCD12864_writeCmd(0x36); //開啟繪圖顯示,可流暢播放動(dòng)畫
- }
- else
- {
- LCD12864_writeCmd(0x34); //默認(rèn)關(guān)閉繪圖顯示
- }
- LCD12864_writeCmd(0x02); //SR等于0,允許設(shè)置卷動(dòng)地址
- LCD12864_writeCmd(0x30); //恢復(fù)為8位并行,基本指令集
- addr=(CGRAM_groupNum<<4)|0x40; //將CGRAM空間號(hào)轉(zhuǎn)換為相應(yīng)存儲(chǔ)地址
- LCD12864_writeCmd(addr); //定位到該位址(用戶空間位址范圍0x40-0x7F共128字節(jié))
- for(i=0;i<16;i++) //將用戶自定義編碼寫入該16*16位元組空間
- {
- LCD12864_writeByte(pUserCode[i*2]); //連續(xù)寫2個(gè)字節(jié)共16位
- LCD12864_writeByte(pUserCode[i*2+1]);
- }
- }
- void LCD12864_writeCGRAM(u8 CGRAM_groupNum, u8* pUserCode)//將用戶自定義編碼寫入CGRAM
- { //參數(shù)一是CGRAM的4組用戶空間組號(hào)碼(0~3) ,參數(shù)二是用戶自定義圖表或漢字的編碼
- u8 i,addr=0;
- if(bShowPicFlag)
- {
- LCD12864_writeCmd(0x36); //開啟繪圖顯示,可流暢播放動(dòng)畫
- }
- else
- {
- LCD12864_writeCmd(0x34); //默認(rèn)關(guān)閉繪圖顯示
- }
- LCD12864_writeCmd(0x02); //SR等于0,允許設(shè)置卷動(dòng)地址
- LCD12864_writeCmd(0x30); //恢復(fù)為8位并行,基本指令集
- addr=(CGRAM_groupNum<<4)|0x40; //將CGRAM空間號(hào)轉(zhuǎn)換為相應(yīng)存儲(chǔ)地址
- LCD12864_writeCmd(addr); //定位到該位址(用戶空間位址范圍0x40-0x7F共128字節(jié))
- for(i=0;i<16;i++) //將用戶自定義編碼寫入該16*16位元組空間
- {
- LCD12864_writeByte(pUserCode[i*2]); //連續(xù)寫2個(gè)字節(jié)共16位
- LCD12864_writeByte(pUserCode[i*2+1]);
- }
- }
- void LCD12864_showScrollCGRAM(u8 row,u8 cols,u8 CGRAM_groupNum)//滾動(dòng)CGRAM
- { //row(0-3), cols(0-15)
- //第三個(gè)參數(shù)是用戶空間號(hào)碼(0~3共4組空間號(hào)碼),該號(hào)碼乘2就是它所對(duì)應(yīng)的[調(diào)用用戶空間編碼]
- LCD12864_setScrollPos(row,cols);
- LCD12864_writeByte(0x00);//4組用戶空間的編碼的高字節(jié)都固定為0,我猜這是為和E文ASCII碼區(qū)分開
- LCD12864_writeByte(CGRAM_groupNum*2); //對(duì)應(yīng)編碼00h,02h,04h,06h
- LCD12864_showCGRAM(row,cols,CGRAM_groupNum);
- }
- void LCD12864_showCGRAM(u8 row,u8 cols,u8 CGRAM_groupNum)//定位液晶光標(biāo),并顯示自定義內(nèi)容
- { //row(0-3), cols(0-15)
- //第三個(gè)參數(shù)是用戶空間號(hào)碼(0~3共4組空間號(hào)碼),該號(hào)碼乘2就是它所對(duì)應(yīng)的[調(diào)用用戶空間編碼]
- LCD12864_setPos(row,cols);
- LCD12864_writeByte(0x00);//4組用戶空間的編碼的高字節(jié)都固定為0,我猜這是為和E文ASCII碼區(qū)分開
- LCD12864_writeByte(CGRAM_groupNum*2); //對(duì)應(yīng)編碼00h,02h,04h,06h
- }
- /*--------------------------------CGRAM end----------------------------------------------*/
- /*--------------------------------DDRAM start----------------------------------------------*/
- void LCD12864_earseSomeDDRam(u8 row,u8 cols,u8 dataSize) //擦除N個(gè)字節(jié)DDRam
- { //row(0-3),cols(0-15),如果起始地址是漢字的低字節(jié),則會(huì)一同擦除漢字的高字節(jié)
- LCD12864_setPos(row, cols); //定位
- if(cols%2!=0) //如果從奇數(shù)列開始
- {
- LCD12864_readByte(); //空讀一次,讓位址指針移動(dòng)半字
- if(LCD12864_readByte()>127) //檢測(cè)高位是否是漢字碼
- {
- LCD12864_setPos(row, cols); //是漢字碼的話要擦除,不然要亂碼
- LCD12864_writeByte(' '); //其實(shí)是寫空格,看不到了就等于擦除了
- } //連續(xù)寫2個(gè)0的話是亂碼
- }
- while(dataSize--) //擦除
- {
- if(cols) //cols>0
- {
- if(0==cols%16) //如果一行滿了
- {
- row++; //準(zhǔn)備將光標(biāo)移到下一行
- cols=0; //列坐標(biāo)置于行首
- LCD12864_setPos(row, cols); //設(shè)置新光標(biāo)
- }
- }
- LCD12864_writeByte(' '); //其實(shí)是寫空格,但為啥不寫0呢
- cols++; //因?yàn)?與是CGRAM重碼了,寫2個(gè)0會(huì)亂碼的
- }
-
- }
- /*****************************************************************************************
- pBuf如果用來(lái)修飾字符串,dataSize=strlen(pBuf);
- pBuf如果是一個(gè)字符數(shù)組,dataSize=sizeof(pBuf);
- strlen()雖然也可以用來(lái)計(jì)算字符數(shù)組長(zhǎng)度,但遇到'\0'時(shí)就會(huì)返回,不會(huì)再計(jì)算后面的其他字符
- 在VC中strlen()只能計(jì)算字符串長(zhǎng)度,不能計(jì)算字符數(shù)組,否則編譯出錯(cuò)
- sizeof("你好5"),sizeof("你好56"),最終液晶光標(biāo)位置是一樣的,故不要用sizeof計(jì)算字符串
- *****************************************************************************************/
- void LCD12864_writeData(u8 row,u8 cols,u8* pBuf,u8 dataSize)//寫數(shù)據(jù)
- { //支持全角半角字符及中英混合的字符串,也可寫入字符串的子串,(行坐標(biāo)0~3,列坐標(biāo)0~15)
- u8 flag=0; //液晶低字節(jié)ram數(shù)據(jù)檢測(cè)標(biāo)志,0不檢測(cè)
- LCD12864_setPos(row, cols); //設(shè)置光標(biāo)
- if(cols%2!=0) //列號(hào)不為偶數(shù)(漢字在液晶上要偶對(duì)齊)
- { //要讓位址空移一個(gè)字節(jié),執(zhí)行下面這句讀操作后,效果是達(dá)到了
- LCD12864_readByte();//但AC值沒(méi)變,我懷疑除了這個(gè)AC字型指針,另有一個(gè)標(biāo)志位沒(méi)公開)
- flag=1; //此時(shí)需要檢測(cè)液晶低位字節(jié)ram
- } //因?yàn)楦呶蛔止?jié)現(xiàn)在可能是漢字碼
- while(dataSize--) //循環(huán)處理目標(biāo)字節(jié)流
- {
- if(0==cols%2) //偶對(duì)齊時(shí),對(duì)于ram高字節(jié)
- {
- if(*pBuf>127) //如果寫入ram的高字節(jié)是漢字碼
- {
- flag=0; //下一次不要檢測(cè)低字節(jié),因?yàn)榭隙ㄊ菨h字了
- }
- else //如果高字節(jié)是半角字符
- {
- flag=1; //若在低字節(jié)ram寫入漢字就亂碼了,故檢測(cè)
- }
- }
- if(cols%2!=0) //對(duì)于液晶低字節(jié)
- {
- if(flag) //如果要檢測(cè)低字節(jié)
- {
- if(*pBuf>127) //如果低字節(jié)是漢字碼
- {
- LCD12864_writeByte(0x20); //插入一個(gè)空格
- cols++; //字節(jié)計(jì)數(shù)器++
- flag=0; //清檢測(cè)標(biāo)志
- }
- }
- }
-
- if(cols) //行尾檢測(cè)
- {
- if(0==cols%16) //如果一行滿了
- {
- row++; //準(zhǔn)備將光標(biāo)移到下一行
- cols=0; //列坐標(biāo)置于行首
- LCD12864_setPos(row, cols); //設(shè)置新位址
- }
- }
- LCD12864_writeByte(*pBuf++); //終于可以寫數(shù)據(jù)了
- cols++; //列號(hào)累加
- }
- }
- //滾屏模式的寫數(shù)據(jù)函數(shù)
- void LCD12864_writeScrollData(u8 row,u8 cols,u8* pBuf,u8 dataSize)//寫數(shù)據(jù),卷動(dòng)模式
- { //支持全角半角字符及中英混合的字符串,也可寫入字符串的子串,(行坐標(biāo)0~3,列坐標(biāo)0~15)
- u8 flag=0; //液晶低字節(jié)ram數(shù)據(jù)檢測(cè)標(biāo)志,0不檢測(cè)
- LCD12864_writeData(row,cols,pBuf,dataSize);
- LCD12864_setScrollPos(row, cols); //設(shè)置光標(biāo)
- if(cols%2!=0) //列號(hào)不為偶數(shù)(漢字在液晶上要偶對(duì)齊)
- { //要讓位址空移一個(gè)字節(jié),執(zhí)行下面這句讀操作后,效果是達(dá)到了
- LCD12864_readByte();//但AC值沒(méi)變,我懷疑除了這個(gè)AC字型指針,另有一個(gè)標(biāo)志位沒(méi)公開)
- flag=1; //此時(shí)需要檢測(cè)液晶低位字節(jié)ram
- } //因?yàn)楦呶蛔止?jié)現(xiàn)在可能是漢字碼
- while(dataSize--) //循環(huán)處理目標(biāo)字節(jié)流
- {
- if(0==cols%2) //偶對(duì)齊時(shí),對(duì)于ram高字節(jié)
- {
- if(*pBuf>127) //如果寫入ram的高字節(jié)是漢字碼
- {
- flag=0; //下一次不要檢測(cè)低字節(jié),因?yàn)榭隙ㄊ菨h字了
- }
- else //如果高字節(jié)是半角字符
- {
- flag=1; //若在低字節(jié)ram寫入漢字就亂碼了,故檢測(cè)
- }
- }
- if(cols%2!=0) //對(duì)于液晶低字節(jié)
- {
- if(flag) //如果要檢測(cè)低字節(jié)
- {
- if(*pBuf>127) //如果低字節(jié)是漢字碼
- {
- LCD12864_writeByte(0x20); //插入一個(gè)空格
- cols++; //字節(jié)計(jì)數(shù)器++
- flag=0; //清檢測(cè)標(biāo)志
- }
- }
- }
-
- if(cols) //行尾檢測(cè)
- {
- if(0==cols%16) //如果一行滿了
- {
- row++; //準(zhǔn)備將光標(biāo)移到下一行
- cols=0; //列坐標(biāo)置于行首
- LCD12864_setScrollPos(row, cols); //設(shè)置新位址
- }
- }
- LCD12864_writeByte(*pBuf++); //終于可以寫數(shù)據(jù)了
- cols++; //列號(hào)累加
- }
- }
- void LCD12864_startScroll(u8 scrollNum,u16 delay_ms) //滾動(dòng)
- { //scrollNum建議值為64
- u8 i;
- LCD12864_writeCmd(0x34);
- LCD12864_writeCmd(0x03);
- for(i=0x40;i<0x40+scrollNum;i++)
- {
- LCD12864_writeCmd(i); //設(shè)置卷動(dòng)地址
- delayms(delay_ms); //實(shí)際使用時(shí)建議用定時(shí)器處理
- }
- LCD12864_writeCmd(0x40); //補(bǔ)滾一行
- LCD12864_writeCmd(0x30);
- }
- void LCD12864_setScrollPos(u8 row, u8 cols) //設(shè)置光標(biāo)位置 ,卷動(dòng)模式
- { //row行坐標(biāo)0~3
- u8 newPos=0; //cols列坐標(biāo)0~15
- switch(row)
- {
- case 0:
- {
- row=0xa8;
- }
- break;
- case 1:
- {
- row=0xb8;
- }
- break;
- case 2:
- {
- row=0xa0;
- }
- break;
- case 3:
- {
- row=0xb0;
- }
- break;
- default: //如果需要檢測(cè)行坐標(biāo)范圍,可在這里加代碼
- break;
- }
- newPos=row+cols/2; //液晶寫指令坐標(biāo)只能8級(jí),我的函數(shù)中列坐標(biāo)是16級(jí)的,支持半角全角混合
- LCD12864_writeCmd(newPos);
- }
- void LCD12864_setPos(u8 row, u8 cols) //設(shè)置光標(biāo)位置
- { //row行坐標(biāo)0~3
- u8 newPos=0; //cols列坐標(biāo)0~15
- switch(row)
- {
- case 0:
- {
- row=0x80;
- }
- break;
- case 1:
- {
- row=0x90;
- }
- break;
- case 2:
- {
- row=0x88;
- }
- break;
- case 3:
- {
- row=0x98;
- }
- break;
- case 4:
- {
- row=0xa0;
- }
- break;
- case 5:
- {
- row=0xb0;
- }
- break;
- case 6:
- {
- row=0xa8;
- }
- break;
- case 7:
- {
- row=0xb8;
- }
- break;
- default: //如果需要檢測(cè)行坐標(biāo)范圍,可在這里加代碼
- break;
- }
- newPos=row+cols/2; //液晶寫指令坐標(biāo)只能8級(jí),我的函數(shù)中列坐標(biāo)是16級(jí)的,支持半角全角混合
- LCD12864_writeCmd(newPos);
- }
- /*
- void LCD12864_setPos(u8 row, u8 cols) //設(shè)置光標(biāo)位置
- { //row行坐標(biāo)0~3
- u8 newPos=0; //cols列坐標(biāo)0~15
- switch(row)
- {
- case 0:
- {
- row=0x80;
- }
- break;
- case 1:
- {
- row=0x90;
- }
- break;
- case 2:
- {
- row=0x88;
- }
- break;
- case 3:
- {
- row=0x98;
- }
- break;
- default: //如果需要檢測(cè)行坐標(biāo)范圍,可在這里加代碼
- break;
- }
- newPos=row+cols/2; //液晶寫指令坐標(biāo)只能8級(jí),我的函數(shù)中列坐標(biāo)是16級(jí)的,支持半角全角混合
- LCD12864_writeCmd(newPos);
- }
- */
- void LCD12864_init() //初始化
- {
- delayms(40); //rst由低到高后保持40ms以上,我們的rst接VCC
- LCD_PSB= 1; //選擇并口方式
- LCD12864_writeCmd( B(110000) ); //0x30,啟用基本指令集
- delayXus(15); //要求延時(shí)100us以上,(8+6x)*1.085=106us
- LCD12864_writeCmd( B(110000) ); //0x30,要求寫2次該指令
- delayXus(5); //要求延時(shí)37us以上,(8+6x)*1.085=41us
- LCD12864_writeCmd( B(1100) ); //0x0f,整體顯示,游標(biāo),游標(biāo)反白
- delayXus(15); //要求延時(shí)100us以上
- LCD12864_writeCmd( B(0001) ); //0x01,清屏指令,整屏幕寫滿空格
- delayms(10); //要求延時(shí)10ms以上
- LCD12864_writeCmd( B(110) ); //0x06,進(jìn)入模式設(shè)置,游標(biāo)自動(dòng)指向下一位置,
-
- delayms(5); //手冊(cè)上沒(méi)說(shuō)這里要延時(shí),額,還是加上吧
- }
- void LCD12864_writeCmd(u8 cmd) //寫指令
- {
- while(LCD12864_isBusy());
- LCD_EN=0; //使能 拉低
- LCD_RW=0; //寫
- LCD_RS=0;_nop_(); //命令
-
- LCD_EN=1; //使能
- LCD_dataBus=cmd; //送指令
- _nop_();_nop_(); //穩(wěn)定
- LCD_EN=0;_nop_(); //取走
- }
- void LCD12864_writeByte(u8 dat) //寫一個(gè)字節(jié)
- {
- while(LCD12864_isBusy());
- LCD_EN=0; //使能先拉低
- LCD_RW=0; //寫
- LCD_RS=1;_nop_(); //數(shù)據(jù)
-
- LCD_EN=1;
- LCD_dataBus=dat;
- _nop_();_nop_(); //延時(shí)大于1.5us
- LCD_EN=0;_nop_(); //下降沿取走數(shù)據(jù)
- }
- u8 LCD12864_readByte() //讀數(shù)據(jù)暫存器Data Register
- { //用的時(shí)候要空操作一次
- u8 temp=0;
- while(LCD12864_isBusy());//忙檢測(cè)
- LCD_dataBus=0xff; //用總線讀數(shù)據(jù)時(shí)必須先置為輸入模式
- LCD_EN=0; //使能線拉低
- LCD_RW=1; //讀
- LCD_RS=1;_nop_(); //數(shù)據(jù)
- LCD_EN=1;_nop_(); //使能
- temp=LCD_dataBus; //取走數(shù)據(jù)
-
- _nop_();
- LCD_EN=0; //使能恢復(fù)
- return temp;
- }
- bool LCD12864_isBusy() //檢測(cè)液晶是否忙
- {
- if(LCD12864_readIR() & 0x80) //檢測(cè)BF位
- {
- return TRUE; //忙
- }
- return FALSE; //不忙
- }
- u8 LCD12864_readIR() //讀指令暫存器Instruction Register
- {
- u8 temp=0;
- LCD_EN=0; //使能準(zhǔn)備
- LCD_RW=1; //讀
- LCD_RS=0;_nop_(); //命令字
- LCD_dataBus=0xff; //準(zhǔn)備輸入
- LCD_EN=1;_nop_(); //使能
- temp=LCD_dataBus; //提取數(shù)據(jù)
- _nop_();
- LCD_EN=0; //使能拉低
- return temp;
- }
復(fù)制代碼
|
|