欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 3163|回復(fù): 1
打印 上一主題 下一主題
收起左側(cè)

lcd12864液晶驅(qū)動(dòng)源碼,獨(dú)創(chuàng)中英文混合輸出 控制器7920

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:161768 發(fā)表于 2017-1-14 17:55 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
控制器7920
代碼沒(méi)啥好說(shuō),我盡量多寫(xiě)了注釋,播放動(dòng)畫(huà)也很流暢的
亮點(diǎn)就是支持中英文混合輸出,其他沒(méi)啥

昨天發(fā)現(xiàn)座的公交車(chē)上用的也是這種12864 ,顯示溫度和時(shí)間...

完整源碼下載:
lcd12864源碼.rar (7.58 KB, 下載次數(shù): 32)


c語(yǔ)言程序:
  1. #ifndef  _LCD12864_H
  2. #define         _LCD12864_H
  3. #include "my51.h"

  4. #define LCD_dataBus  P0           //總線
  5. sbit LCD_EN = P3^4;                   //使能控制
  6. sbit LCD_RS = P3^5;                   //數(shù)據(jù)_命令選擇端
  7. sbit LCD_RW = P3^6;                   //讀寫(xiě)控制
  8. sbit LCD_PSB= P3^7;                   //串并選擇,H并行,L串行


  9. extern bool bShowPicFlag;  //繪圖時(shí)圖像顯示控制(僅控制GDRAM)

  10. /*************************基本功能函數(shù)*********************************************/
  11. extern void LCD12864_init();                                        //初始化,必須置頂調(diào)用
  12. extern void LCD12864_setPos(u8 row, u8 cols);        //設(shè)置光標(biāo)位置
  13. extern void LCD12864_writeByte(u8 dat);                        //寫(xiě)一個(gè)字節(jié)
  14. extern void LCD12864_writeCmd(u8 cmd);                        //寫(xiě)指令
  15. extern   u8 LCD12864_readByte();                                //讀一個(gè)字節(jié)ram
  16. extern   u8 LCD12864_readIR();                                        //讀暫存器
  17. extern bool LCD12864_isBusy();                                        //判忙

  18. /*************************調(diào)用基本字庫(kù)顯示文字**************************************/        
  19. //獨(dú)創(chuàng)支持全角半角字符及中英混合的字符串,或字符串的子串,起始行號(hào)row(0-3)和列坐標(biāo)cols(0-15),寫(xiě)滿屏幕為止
  20. //行號(hào)4-7行是滾動(dòng)區(qū)
  21. extern void LCD12864_writeData(u8 row, u8 cols,u8* pBuf,u8 dataSize);//寫(xiě)一堆數(shù)據(jù)
  22. extern void LCD12864_earseSomeDDRam(u8 row,u8 cols,u8 dataSize);        //擦除N字節(jié)DDRam

  23. /*************************用戶自定義圖標(biāo)字體****************************************/
  24. extern void LCD12864_writeCGRAM(u8 userRamNum,u8* pCGRAM_userCode); //寫(xiě)自定義圖標(biāo)字體
  25. extern void LCD12864_showCGRAM(u8 row,u8 cols,u8 num) ;        //顯示自定義圖標(biāo)字體,row(0-3),cols(0-15)
  26. extern void LCD12864_clearCGRAM(u8 CGRAM_groupNum) ;    //CGRAM清零(初始化也可清0)

  27. /*************************圖像顯示功能函數(shù)**********************************************/
  28. extern void LCD12864_showGDRAM(bool bShowImage);          //GDRAM繪圖顯示開(kāi)關(guān)
  29. extern void LCD12864_clearGDRAM();                                            //液晶整個(gè)可視區(qū)的GDRAM快速清0
  30. //前4參數(shù):起始點(diǎn)x(0-7)位址,y(0-63)坐標(biāo),要顯示的寬度(1-128)和高度(1-64)[可顯示從圖像左上角開(kāi)始的部分區(qū)域]
  31. //后4參數(shù):圖像代碼地址,圖像本身的寬度(1-128)和高度(1-64), 反白(true反白,false不反白)
  32. //畫(huà)圖填充GDRAM        ,注:顯示的區(qū)域或者圖像本身寬度必須是8的倍數(shù)
  33. extern u8 LCD12864_drawGDRAM(u8 x,u8 y,u8 width,u8 height,u8 *pImageCode,u8 imageWidth,u8 imageHight,bool bReverse);
  34. extern void LCD12864_drawDot(u8 x,u8 y,u8 flag);                   //打點(diǎn),x(0-127),y(0-63),flag(0正常,1反白,2清0)
  35. extern bool LCD12864_drawXYLine(u8 x1, u8 y1,u8 x2, u8 y2,u8 flag);                  //畫(huà)水平或垂直直線
  36. extern void LCD12864_drawAnyLine(u8 x1, u8 y1,u8 x2, u8 y2,u8 flag) ;          //畫(huà)任意直線
  37. extern void LCD12864_drawRectangle(u8 x,u8 y ,u8 width,u8 height,u8 flag);//畫(huà)矩形
  38. extern void LCD12864_drawFillRect(u8 x,u8 y, u8 width,u8 hight,u8 flag);  //填充矩形,可對(duì)矩形區(qū)反白或清0
  39. extern void LCD12864_drawVerticalSquare(u8 x,u8 y,u8 r,u8 flag)        ;                   //畫(huà)站立的正方形
  40. extern void LCD12864_drawCircle(u8 x0,u8 y0,u8 r,u8 flag);                                    //畫(huà)圓

  41. //打點(diǎn)法全屏畫(huà)圖有點(diǎn)慢了,打點(diǎn)法反白矩形區(qū)還可以,建議矩形范圍小一些,不然比較慢
  42. //打點(diǎn)法效果最好,因?yàn)槲淖值木匦螀^(qū)比較小,速度很快
  43. //不過(guò)繪圖法反白文字效率高,flash空間充裕的建議用繪圖法

  44. /***************************全屏滾動(dòng)*******************************************/
  45. //需要滾動(dòng)時(shí),用LCD12864_writeScrollData()函數(shù),參數(shù)和LCD12864_writeData()一樣
  46. extern void LCD12864_writeScrollData(u8 row,u8 cols,u8* pBuf,u8 dataSize);//寫(xiě)數(shù)據(jù) (滾動(dòng)模式)
  47. extern void LCD12864_setScrollPos(u8 row, u8 cols);                //設(shè)置滾動(dòng)模式的坐標(biāo)
  48. extern void LCD12864_showScrollCGRAM(u8 row,u8 cols,u8 CGRAM_groupNum);//用于CGRAM滾動(dòng)顯示前執(zhí)行
  49. extern void LCD12864_startScroll(u8 scrollNum,u16 delay_ms);  //滾動(dòng)開(kāi)始
  50. #endif                                                                                                                                 
復(fù)制代碼
  1. #include "lcd12864.h"
  2. //圖像與文字,圖像與用戶圖標(biāo),像素重合時(shí)是異或關(guān)系
  3. //文字與用戶圖標(biāo)是覆蓋關(guān)系
  4. bool bShowPicFlag=false;                  //繪圖時(shí)圖像顯示控制

  5. /*
  6. u8 LCD12864_table[]={"123456789"};
  7. */

  8. void LCD12864_drawFillRect(u8 x,u8 y, u8 width,u8 hight,u8 flag)//填充任意位置的整個(gè)矩形
  9. {//矩形起始坐標(biāo)x(0-127),y(0-63),寬(1-128)高(1-64),flag有3種值,0正常填充,1反色,2清0
  10.         u8 i=0;
  11.         u8 j=0;
  12.         if(0==width||0==hight)         //矩形寬度或高度為0時(shí)返回
  13.         {
  14.                 return ;
  15.         }
  16.         if( (x+width>128 ||(y+hight)>64)  )
  17.         {
  18.                 led2=0;
  19.                 return;
  20.         }
  21.         for(j=0;j<hight;j++)
  22.         {               
  23.                 for(i=0;i<width;i++)
  24.                 {
  25.                         LCD12864_drawDot(x+i, y+j,flag);               
  26.                 }
  27.         }                        
  28. }


  29. void LCD12864_drawRectangle(u8 x,u8 y, u8 width,u8 hight,u8 flag)//畫(huà)矩形
  30. {        //矩形起始坐標(biāo)x(0-127),y(0-63),寬度(1-128)和高度(1-64)        flag有3種值,0正常寫(xiě)1,1反色,2清0
  31.         if(0==width||0==hight)         //矩形寬度或高度為0時(shí)返回
  32.         {
  33.                 return ;
  34.         }
  35.         width--;hight--;
  36.         LCD12864_drawXYLine(x, y,x+width, y, flag);
  37.         LCD12864_drawXYLine(x+width, y,x+width, y+hight, flag);
  38.         LCD12864_drawXYLine(x, y,x, y+hight, flag);
  39.         LCD12864_drawXYLine(x, y+hight,x+width, y+hight, flag);        
  40. }

  41. bool LCD12864_drawXYLine(u8 x1,u8 y1,  u8 x2, u8 y2,  u8 flag)//畫(huà)水平或垂直直線
  42. {        //起始點(diǎn)坐標(biāo)和終點(diǎn)坐標(biāo),x(0-127),y(0-63),  flag有3種值,0正常寫(xiě)1,1反色,2清0
  43.         u8 n=0;
  44.         if(flag>2|| x1>127||x2>127||y1>63||y2>63)
  45.         {
  46.                 return false;
  47.         }

  48.         if(x1==x2)
  49.         {
  50.                 for(n=0;n<abs(y2-y1)+1;n++)
  51.                 {
  52.                         LCD12864_drawDot( x1,y1+(y2>=y1?n:-n) ,flag);        
  53.                 }
  54.         }

  55.         if(y1==y2)
  56.         {
  57.                 for(n=0;n<abs(x2-x1)+1;n++)
  58.                 {
  59.                          LCD12864_drawDot(x1+(x2>=x1?n:-n),y1,flag)        ;
  60.                 }
  61.         }
  62.         return true;        
  63. }

  64. void LCD12864_drawCircle(u8 x0,u8 y0,u8 r,u8 flag)
  65. {
  66.         s8 a,b;
  67.         s8 di;
  68.         if(r>31 ||r==0) return;    //參數(shù)過(guò)濾,次液晶顯示的最大圓半徑為31
  69.         a=0;
  70.         b=r;
  71.         di=3-2*r;       //判斷下個(gè)點(diǎn)位置的標(biāo)志
  72.         while(a<=b)
  73.         {
  74.                 LCD12864_drawDot(x0-b,y0-a,flag);  //3           
  75.                 LCD12864_drawDot(x0+b,y0-a,flag);  //0           
  76.                 LCD12864_drawDot(x0-a,y0+b,flag);  //1      
  77.                 LCD12864_drawDot(x0-b,y0-a,flag);  //7           
  78.                 LCD12864_drawDot(x0-a,y0-b,flag);  //2            
  79.                 LCD12864_drawDot(x0+b,y0+a,flag);  //4               
  80.                 LCD12864_drawDot(x0+a,y0-b,flag);  //5
  81.                 LCD12864_drawDot(x0+a,y0+b,flag);  //6
  82.                 LCD12864_drawDot(x0-b,y0+a,flag);            
  83.                 a++;
  84.                 //使用Bresenham算法畫(huà)圓     
  85.                 if(di<0)
  86.                 di +=4*a+6;
  87.                 else
  88.                 {
  89.                         di +=10+4*(a-b);   
  90.                         b--;
  91.                 }
  92.                 LCD12864_drawDot(x0+a,y0+b,flag);
  93.         }
  94. }


  95. void LCD12864_drawVerticalSquare(u8 x,u8 y,u8 r,u8 flag)        //畫(huà)站立的正方形
  96. {
  97.     u8 a,b;
  98.     float c=0;
  99.     a = 0;
  100.     b = r;
  101.     c = 3 - 2*r;
  102.     while(a < b)
  103.     {
  104.         LCD12864_drawDot(x+a,y+b,flag);
  105.         LCD12864_drawDot(x-a,y+b,flag);
  106.         LCD12864_drawDot(x+a,y-b,flag);
  107.         LCD12864_drawDot(x-a,y-b,flag);
  108.         
  109.         LCD12864_drawDot(x+b,y+a,flag);
  110.         LCD12864_drawDot(x-b,y+a,flag);
  111.         LCD12864_drawDot(x+b,y-a,flag);
  112.         LCD12864_drawDot(x-b,y-a,flag);
  113.         
  114.         if(c < 0)
  115.         {
  116.             c = c+4*a + 6;
  117.         }
  118.         else
  119.         {
  120.             c= c + 4*(a - b) + 10;
  121.             b-=1;
  122.         }
  123.         a = a + 1;  //控制打點(diǎn)間隔
  124.         
  125.     }
  126.     if(a == b)
  127.     {
  128.         LCD12864_drawDot(x+a,y+b,flag);
  129.         LCD12864_drawDot(x-a,y+b,flag);
  130.         LCD12864_drawDot(x+a,y-b,flag);
  131.         LCD12864_drawDot(x-a,y+b,flag);
  132.         
  133.         LCD12864_drawDot(x+b,y+a,flag);
  134.         LCD12864_drawDot(x-b,y+a,flag);
  135.         LCD12864_drawDot(x+b,y-a,flag);
  136.         LCD12864_drawDot(x-b,y-a,flag);      
  137.     }
  138. }


  139. void LCD12864_drawAnyLine(u8 StartX, u8 StartY,u8 EndX, u8 EndY, u8 flag)  //畫(huà)任意直線
  140. {
  141.     u8 t, distance ;      /*根據(jù)屏幕大小改變變量類(lèi)型(如改為int型)*/
  142.     s16 x = 0 , y = 0 ;
  143.     s8 incx, incy, dx, dy ;
  144.         if((StartX==EndX) ||(StartY==EndY))
  145.         {
  146.                 LCD12864_drawXYLine(StartX,StartY,EndX,EndY,flag);
  147.                 return;
  148.         }

  149.     dx = EndX - StartX ;
  150.     dy = EndY - StartY ;               
  151.         incx = dx > 0 ?1:-1;
  152.         incy = dy > 0 ?1:-1;

  153.     dx = abs( dx );
  154.     dy = abs( dy );
  155.     if( dx > dy )
  156.     {
  157.         distance = dx ;
  158.     }
  159.     else
  160.     {
  161.         distance = dy ;
  162.     }
  163.     LCD12864_drawDot( StartX, StartY, flag ) ;                  //反白補(bǔ)點(diǎn)
  164.     for( t = 0 ; t <= distance+1 ; t++ )
  165.     {
  166.         LCD12864_drawDot( StartX, StartY, flag ) ;
  167.         x += dx ;
  168.         y += dy ;
  169.         if( x > distance )
  170.         {
  171.             x -= distance ;
  172.             StartX += incx ;
  173.         }
  174.         if( y > distance )
  175.         {
  176.             y -= distance ;
  177.             StartY += incy ;
  178.         }
  179.     }
  180. }

  181. void LCD12864_drawDot(u8 x, u8 y,u8 flag)        //畫(huà)點(diǎn),0打點(diǎn),1反色,2清0
  182. {  //x(0-127),y(0-63),flag有3種值,0正常寫(xiě)1,1反色,2清0
  183.     u8 x_word=0;                 //水平(0-127)個(gè)像素中的哪個(gè)字,一字16位
  184.     u8 x_mode=0;                 //取余
  185.     u8 y_part=0;
  186.     u8 y_bit=0;
  187.     u8 tempH=0;
  188.     u8 tempL=0;
  189.         x_word=x>>4;            //在哪一個(gè)字(0-7)              ,x_word=x/16
  190.     x_mode=x&0x0f;      //在該字的哪一位                  ,x_mode= x%16
  191.     y_part=y>>5;        //在哪個(gè)屏0或1                          ,y_part=y/32
  192.     y_bit= y&0x1f;      //垂直方向,y_bit范圍(0-31),y_bit=y%32
  193.     bShowPicFlag?LCD12864_writeCmd(0x36):LCD12864_writeCmd(0x34);
  194.     LCD12864_writeCmd(0x80+y_bit);        //垂直坐標(biāo)
  195.     LCD12864_writeCmd(0x80+8*y_part+x_word);                   //水平位址
  196.   
  197.     LCD12864_readByte();
  198.     tempH=LCD12864_readByte();  //先將該字16位數(shù)據(jù)保存
  199.     tempL= LCD12864_readByte();
  200.    
  201.     LCD12864_writeCmd(0x80+y_bit);                           //重設(shè)地址,因?yàn)锳C計(jì)數(shù)器變了
  202.     LCD12864_writeCmd(0x80+8*y_part+x_word);                   //水平位址
  203.         if(0==flag)                                                                                   //不反白,打1,
  204.         {
  205.             if(x_mode<8)  //如果x_mode小于8,說(shuō)明點(diǎn)應(yīng)位于該字的左邊高8位中
  206.             {
  207.                 LCD12864_writeByte( tempH | bit(7- x_mode) );
  208.                 //LCD12864_writeByte(tempL);
  209.             }
  210.             else
  211.             {
  212.                 //LCD12864_writeByte(tempH);
  213.                         LCD12864_readByte();         //讓AC走半步
  214.                 LCD12864_writeByte(tempL|bit(15-x_mode));
  215.             }         
  216.         }
  217.         else if(1==flag)                        //反白,該點(diǎn)與原來(lái)的狀態(tài)相反
  218.         {
  219.                 if(x_mode<8)  //如果x_mode小于8,說(shuō)明點(diǎn)應(yīng)位于該字的左邊高8位中
  220.             {
  221.                         if(tempH & bit(7- x_mode))             //原來(lái)是1
  222.                         {
  223.                                 LCD12864_writeByte( tempH&~bit(7- x_mode) );        //寫(xiě)0
  224.                         }
  225.                         else                                                         //原來(lái)是0
  226.                         {
  227.                                 LCD12864_writeByte( tempH | bit(7- x_mode) );        //寫(xiě)1
  228.                         }
  229.                
  230.             }
  231.             else
  232.             {
  233.                         LCD12864_readByte();         //讓AC走半字
  234.                         if(tempL& bit(15-x_mode))          //原來(lái)是1的寫(xiě)0
  235.                         {
  236.                                 
  237.                                 LCD12864_writeByte(tempL&~bit(15-x_mode));         //寫(xiě)0
  238.                         }
  239.                         else
  240.                         {
  241.                                 LCD12864_writeByte(tempL|bit(15-x_mode));         //寫(xiě)0
  242.                         }
  243.                
  244.             }
  245.         }
  246.         else if(2==flag)                          //清0
  247.         {
  248.                 if(x_mode<8)  //如果x_mode小于8,說(shuō)明點(diǎn)應(yīng)位于該字的左邊高8位中
  249.             {
  250.                 LCD12864_writeByte( tempH&~bit(7- x_mode) );
  251.             }
  252.             else
  253.             {
  254.                         LCD12864_readByte();         //讓AC走半字
  255.                 LCD12864_writeByte(tempL&~bit(15-x_mode));
  256.             }        
  257.         }  
  258. }

  259. void LCD12864_showGDRAM(bool bShowImage)        //GDRAM圖像顯示開(kāi)關(guān)
  260. {
  261.         if(bShowImage)                 //開(kāi)啟顯示
  262.         {
  263.             LCD12864_writeCmd(0x36);
  264.             LCD12864_writeCmd(0x30);               
  265.         }
  266.         else                                 //關(guān)閉顯示
  267.         {
  268.             LCD12864_writeCmd(0x34);
  269.             LCD12864_writeCmd(0x30);               
  270.         }
  271. }


  272. //填充GDRAM
  273. u8 LCD12864_drawGDRAM(u8 x,u8 y,u8 width,u8 height,u8* pImageCode,u8 imageWidth,u8 imageHight,bool bReverse)
  274. {//前4參數(shù):起始點(diǎn)x(0-7)位址,y(0-63)坐標(biāo),要顯示的寬度(1-128)和高度(1-64)[可顯示從圖像左上角開(kāi)始的部分區(qū)域]
  275. //后4參數(shù):圖像代碼地址,圖像本身的寬度(1-128)和高度(1-64), 反白(true反白,false不反白)
  276.         u8 i=0;
  277.         u8 j=0;
  278.         if( height > imageHight )           //檢測(cè)顯示高度,寬度不檢測(cè)不會(huì)亂碼
  279.         {                                                           //顯示的高度不能超過(guò)圖片本身高度
  280.                 return 0x01;                           //也就是說(shuō)可顯示圖像的部分區(qū)域(從圖像左上角開(kāi)始的部分區(qū)域)
  281.         }
  282.         width>>=3;                                           //像素寬度轉(zhuǎn)化為字節(jié)個(gè)數(shù),所以width必須是8的整數(shù)倍
  283.         imageWidth>>=3;                                   //像素寬度轉(zhuǎn)化為字節(jié)個(gè)數(shù),所以width必須是8的整數(shù)倍
  284.         if(bShowPicFlag)                                
  285.         {
  286.                 LCD12864_writeCmd(0x36);        //改寫(xiě)GDRAM時(shí),開(kāi)啟繪圖顯示,可防止動(dòng)畫(huà)顯示時(shí)閃動(dòng)                 
  287.         }
  288.         else
  289.         {
  290.                 LCD12864_writeCmd(0x34);        //改寫(xiě)GDRAM時(shí),關(guān)閉繪圖顯示
  291.         }

  292.         for(j=0;j<height;j++)                   //寫(xiě)GDRAM
  293.         {
  294.                 if(y+j>31)                                                        //地址變換
  295.                 {
  296.                         LCD12864_writeCmd(0x80+y+j-32);        //垂直坐標(biāo)
  297.                         LCD12864_writeCmd(0x88+x);                //水平位址
  298.                 }
  299.                 else
  300.                 {
  301.                         LCD12864_writeCmd(0x80+y+j);        
  302.                         LCD12864_writeCmd(0x80+x);
  303.                 }
  304.                 for(i=0;i<width;i++)                                //水平方向?qū)憯?shù)據(jù),帶反白控制
  305.                 {
  306.                         LCD12864_writeByte(bReverse?~pImageCode[imageWidth*j+i]:pImageCode[imageWidth*j+i]);        
  307.                 }        
  308.         }
  309.         LCD12864_writeCmd(0x30);
  310.         return 0x02;
  311. }


  312. void LCD12864_clearGDRAM()              //液晶可視區(qū)的繪圖GDRAM清0
  313. {   
  314.     u8 j=0;
  315.     u8 i=0;
  316.     LCD12864_writeCmd(0x34);        //擴(kuò)展指令
  317.     for(j=0;j<64;j++)                       //垂直方向地址手動(dòng)增加,當(dāng)j=64時(shí)清整個(gè)GDram
  318.     {                                                                //我們只要清可視區(qū)的GDRAM就可以了
  319.         LCD12864_writeCmd(0x80+j);  //y軸坐標(biāo)
  320.         LCD12864_writeCmd(0x80);    //x軸坐標(biāo)
  321.         for(i=0;i<32;i++)           //水平方向位址自動(dòng)增加
  322.         {
  323.             LCD12864_writeByte(0x00);
  324.         }
  325.     }
  326.     LCD12864_writeCmd(0x30);  //回到基本指令
  327. }         


  328. /*--------------------------------CGRAM start----------------------------------------------*/
  329. void LCD12864_clearCGRAM(u8 CGRAM_groupNum)//將用戶自定義編碼區(qū)CGRAM清0         
  330. {        //參數(shù)一是CGRAM的4組用戶空間組號(hào)碼(0~3) ,參數(shù)二是用戶自定義圖表或漢字的編碼
  331.     u8 i,addr=0;        
  332.         bShowPicFlag?LCD12864_writeCmd(0x36):LCD12864_writeCmd(0x34);//擴(kuò)展指令,繪圖開(kāi)關(guān)保持                                                               
  333.     LCD12864_writeCmd(0x02);            //SR等于0,允許設(shè)置卷動(dòng)地址
  334.     LCD12864_writeCmd(0x30);            //恢復(fù)為8位并行,基本指令集
  335.     addr=(CGRAM_groupNum<<4)|0x40;        //將CGRAM空間號(hào)轉(zhuǎn)換為相應(yīng)存儲(chǔ)地址
  336.     LCD12864_writeCmd(addr);                //定位到該位址(用戶空間位址范圍0x40-0x7F共128字節(jié))
  337.     for(i=0;i<16;i++)                                //將用戶自定義編碼寫(xiě)入該16*16位元組空間
  338.     {
  339.         LCD12864_writeByte(0);                //連續(xù)寫(xiě)2個(gè)字節(jié)共16位
  340.         LCD12864_writeByte(0);
  341.     }   
  342. }

  343. void LCD12864_writeScrollCGRAM(u8 CGRAM_groupNum, u8* pUserCode)//將用戶自定義編碼寫(xiě)入CGRAM         
  344. {        //參數(shù)一是CGRAM的4組用戶空間組號(hào)碼(0~3) ,參數(shù)二是用戶自定義圖表或漢字的編碼
  345.     u8 i,addr=0;
  346.         if(bShowPicFlag)                                
  347.         {
  348.                 LCD12864_writeCmd(0x36);        //開(kāi)啟繪圖顯示,可流暢播放動(dòng)畫(huà)                 
  349.         }
  350.         else
  351.         {
  352.                 LCD12864_writeCmd(0x34);        //默認(rèn)關(guān)閉繪圖顯示
  353.         }                                
  354.     LCD12864_writeCmd(0x02);            //SR等于0,允許設(shè)置卷動(dòng)地址
  355.     LCD12864_writeCmd(0x30);            //恢復(fù)為8位并行,基本指令集
  356.     addr=(CGRAM_groupNum<<4)|0x40;        //將CGRAM空間號(hào)轉(zhuǎn)換為相應(yīng)存儲(chǔ)地址
  357.     LCD12864_writeCmd(addr);                //定位到該位址(用戶空間位址范圍0x40-0x7F共128字節(jié))
  358.     for(i=0;i<16;i++)                                //將用戶自定義編碼寫(xiě)入該16*16位元組空間
  359.     {
  360.         LCD12864_writeByte(pUserCode[i*2]);                 //連續(xù)寫(xiě)2個(gè)字節(jié)共16位
  361.         LCD12864_writeByte(pUserCode[i*2+1]);
  362.     }   
  363. }

  364. void LCD12864_writeCGRAM(u8 CGRAM_groupNum, u8* pUserCode)//將用戶自定義編碼寫(xiě)入CGRAM         
  365. {        //參數(shù)一是CGRAM的4組用戶空間組號(hào)碼(0~3) ,參數(shù)二是用戶自定義圖表或漢字的編碼
  366.     u8 i,addr=0;
  367.         if(bShowPicFlag)                                
  368.         {
  369.                 LCD12864_writeCmd(0x36);        //開(kāi)啟繪圖顯示,可流暢播放動(dòng)畫(huà)                 
  370.         }
  371.         else
  372.         {
  373.                 LCD12864_writeCmd(0x34);        //默認(rèn)關(guān)閉繪圖顯示
  374.         }                                
  375.     LCD12864_writeCmd(0x02);            //SR等于0,允許設(shè)置卷動(dòng)地址
  376.     LCD12864_writeCmd(0x30);            //恢復(fù)為8位并行,基本指令集
  377.     addr=(CGRAM_groupNum<<4)|0x40;        //將CGRAM空間號(hào)轉(zhuǎn)換為相應(yīng)存儲(chǔ)地址
  378.     LCD12864_writeCmd(addr);                //定位到該位址(用戶空間位址范圍0x40-0x7F共128字節(jié))
  379.     for(i=0;i<16;i++)                                //將用戶自定義編碼寫(xiě)入該16*16位元組空間
  380.     {
  381.         LCD12864_writeByte(pUserCode[i*2]);                 //連續(xù)寫(xiě)2個(gè)字節(jié)共16位
  382.         LCD12864_writeByte(pUserCode[i*2+1]);
  383.     }   
  384. }

  385. void LCD12864_showScrollCGRAM(u8 row,u8 cols,u8 CGRAM_groupNum)//滾動(dòng)CGRAM
  386. {        //row(0-3),        cols(0-15)
  387.         //第三個(gè)參數(shù)是用戶空間號(hào)碼(0~3共4組空間號(hào)碼),該號(hào)碼乘2就是它所對(duì)應(yīng)的[調(diào)用用戶空間編碼]
  388.     LCD12864_setScrollPos(row,cols);
  389.     LCD12864_writeByte(0x00);//4組用戶空間的編碼的高字節(jié)都固定為0,我猜這是為和E文ASCII碼區(qū)分開(kāi)
  390.     LCD12864_writeByte(CGRAM_groupNum*2);        //對(duì)應(yīng)編碼00h,02h,04h,06h
  391.         LCD12864_showCGRAM(row,cols,CGRAM_groupNum);
  392. }

  393. void LCD12864_showCGRAM(u8 row,u8 cols,u8 CGRAM_groupNum)//定位液晶光標(biāo),并顯示自定義內(nèi)容
  394. {        //row(0-3),        cols(0-15)
  395.         //第三個(gè)參數(shù)是用戶空間號(hào)碼(0~3共4組空間號(hào)碼),該號(hào)碼乘2就是它所對(duì)應(yīng)的[調(diào)用用戶空間編碼]
  396.     LCD12864_setPos(row,cols);
  397.     LCD12864_writeByte(0x00);//4組用戶空間的編碼的高字節(jié)都固定為0,我猜這是為和E文ASCII碼區(qū)分開(kāi)
  398.     LCD12864_writeByte(CGRAM_groupNum*2);        //對(duì)應(yīng)編碼00h,02h,04h,06h
  399. }
  400. /*--------------------------------CGRAM end----------------------------------------------*/

  401. /*--------------------------------DDRAM start----------------------------------------------*/
  402. void LCD12864_earseSomeDDRam(u8 row,u8 cols,u8 dataSize) //擦除N個(gè)字節(jié)DDRam
  403. {        //row(0-3),cols(0-15),如果起始地址是漢字的低字節(jié),則會(huì)一同擦除漢字的高字節(jié)
  404.         LCD12864_setPos(row, cols);                                   //定位                                                           
  405.         if(cols%2!=0)                                                           //如果從奇數(shù)列開(kāi)始
  406.         {
  407.                 LCD12864_readByte();                                   //空讀一次,讓位址指針移動(dòng)半字
  408.                 if(LCD12864_readByte()>127)                           //檢測(cè)高位是否是漢字碼
  409.                 {
  410.                         LCD12864_setPos(row, cols);                   //是漢字碼的話要擦除,不然要亂碼
  411.                         LCD12864_writeByte(' ');                   //其實(shí)是寫(xiě)空格,看不到了就等于擦除了
  412.                 }                                                                           //連續(xù)寫(xiě)2個(gè)0的話是亂碼
  413.         }        
  414.         while(dataSize--)                                                   //擦除
  415.         {
  416.                 if(cols)                                                           //cols>0
  417.                 {
  418.                         if(0==cols%16)                                           //如果一行滿了
  419.                         {
  420.                                 row++;                                                   //準(zhǔn)備將光標(biāo)移到下一行
  421.                                 cols=0;                                                   //列坐標(biāo)置于行首
  422.                                 LCD12864_setPos(row, cols);           //設(shè)置新光標(biāo)
  423.                         }                                
  424.                 }
  425.                 LCD12864_writeByte(' ');                           //其實(shí)是寫(xiě)空格,但為啥不寫(xiě)0呢
  426.                 cols++;                                                                   //因?yàn)?與是CGRAM重碼了,寫(xiě)2個(gè)0會(huì)亂碼的
  427.         }
  428.         
  429. }


  430. /*****************************************************************************************
  431. pBuf如果用來(lái)修飾字符串,dataSize=strlen(pBuf);
  432. pBuf如果是一個(gè)字符數(shù)組,dataSize=sizeof(pBuf);
  433. strlen()雖然也可以用來(lái)計(jì)算字符數(shù)組長(zhǎng)度,但遇到'\0'時(shí)就會(huì)返回,不會(huì)再計(jì)算后面的其他字符
  434. 在VC中strlen()只能計(jì)算字符串長(zhǎng)度,不能計(jì)算字符數(shù)組,否則編譯出錯(cuò)
  435. sizeof("你好5"),sizeof("你好56"),最終液晶光標(biāo)位置是一樣的,故不要用sizeof計(jì)算字符串
  436. *****************************************************************************************/
  437. void LCD12864_writeData(u8 row,u8 cols,u8* pBuf,u8 dataSize)//寫(xiě)數(shù)據(jù)
  438. {        //支持全角半角字符及中英混合的字符串,也可寫(xiě)入字符串的子串,(行坐標(biāo)0~3,列坐標(biāo)0~15)
  439.         u8 flag=0;                                                                        //液晶低字節(jié)ram數(shù)據(jù)檢測(cè)標(biāo)志,0不檢測(cè)
  440.     LCD12864_setPos(row, cols);                                        //設(shè)置光標(biāo)   
  441.         if(cols%2!=0)                                                                //列號(hào)不為偶數(shù)(漢字在液晶上要偶對(duì)齊)
  442.         {        //要讓位址空移一個(gè)字節(jié),執(zhí)行下面這句讀操作后,效果是達(dá)到了
  443.                 LCD12864_readByte();//但AC值沒(méi)變,我懷疑除了這個(gè)AC字型指針,另有一個(gè)標(biāo)志位沒(méi)公開(kāi))
  444.                 flag=1;                                                                        //此時(shí)需要檢測(cè)液晶低位字節(jié)ram        
  445.         }                                                                                        //因?yàn)楦呶蛔止?jié)現(xiàn)在可能是漢字碼

  446.     while(dataSize--)                                                        //循環(huán)處理目標(biāo)字節(jié)流
  447.     {                                                                                       
  448.                 if(0==cols%2)                                                        //偶對(duì)齊時(shí),對(duì)于ram高字節(jié)
  449.                 {
  450.                         if(*pBuf>127)                                                //如果寫(xiě)入ram的高字節(jié)是漢字碼
  451.                         {
  452.                                 flag=0;                                                        //下一次不要檢測(cè)低字節(jié),因?yàn)榭隙ㄊ菨h字了
  453.                         }
  454.                         else                                                                //如果高字節(jié)是半角字符
  455.                         {
  456.                                 flag=1;                                                        //若在低字節(jié)ram寫(xiě)入漢字就亂碼了,故檢測(cè)
  457.                         }                                
  458.                 }

  459.                 if(cols%2!=0)                                                    //對(duì)于液晶低字節(jié)
  460.                 {
  461.                         if(flag)                                                        //如果要檢測(cè)低字節(jié)
  462.                         {
  463.                                 if(*pBuf>127)                                        //如果低字節(jié)是漢字碼
  464.                                 {
  465.                                         LCD12864_writeByte(0x20);        //插入一個(gè)空格
  466.                                         cols++;                                                //字節(jié)計(jì)數(shù)器++
  467.                                         flag=0;                                                //清檢測(cè)標(biāo)志
  468.                                 }                                       
  469.                         }        
  470.                 }      
  471.                
  472.                 if(cols)                                                                //行尾檢測(cè)
  473.                 {
  474.                         if(0==cols%16)                                                //如果一行滿了
  475.                         {
  476.                                 row++;                                                        //準(zhǔn)備將光標(biāo)移到下一行
  477.                                 cols=0;                                                        //列坐標(biāo)置于行首
  478.                                 LCD12864_setPos(row, cols);                //設(shè)置新位址
  479.                         }                                
  480.                 }

  481.                 LCD12864_writeByte(*pBuf++);                        //終于可以寫(xiě)數(shù)據(jù)了
  482.                 cols++;                                                                    //列號(hào)累加
  483.     }
  484. }


  485. //滾屏模式的寫(xiě)數(shù)據(jù)函數(shù)
  486. void LCD12864_writeScrollData(u8 row,u8 cols,u8* pBuf,u8 dataSize)//寫(xiě)數(shù)據(jù),卷動(dòng)模式
  487. {        //支持全角半角字符及中英混合的字符串,也可寫(xiě)入字符串的子串,(行坐標(biāo)0~3,列坐標(biāo)0~15)
  488.         u8 flag=0;                                                                        //液晶低字節(jié)ram數(shù)據(jù)檢測(cè)標(biāo)志,0不檢測(cè)
  489.         LCD12864_writeData(row,cols,pBuf,dataSize);
  490.     LCD12864_setScrollPos(row, cols);                                        //設(shè)置光標(biāo)   
  491.         if(cols%2!=0)                                                                //列號(hào)不為偶數(shù)(漢字在液晶上要偶對(duì)齊)
  492.         {        //要讓位址空移一個(gè)字節(jié),執(zhí)行下面這句讀操作后,效果是達(dá)到了
  493.                 LCD12864_readByte();//但AC值沒(méi)變,我懷疑除了這個(gè)AC字型指針,另有一個(gè)標(biāo)志位沒(méi)公開(kāi))
  494.                 flag=1;                                                                        //此時(shí)需要檢測(cè)液晶低位字節(jié)ram        
  495.         }                                                                                        //因?yàn)楦呶蛔止?jié)現(xiàn)在可能是漢字碼

  496.     while(dataSize--)                                                        //循環(huán)處理目標(biāo)字節(jié)流
  497.     {                                                                                       
  498.                 if(0==cols%2)                                                        //偶對(duì)齊時(shí),對(duì)于ram高字節(jié)
  499.                 {
  500.                         if(*pBuf>127)                                                //如果寫(xiě)入ram的高字節(jié)是漢字碼
  501.                         {
  502.                                 flag=0;                                                        //下一次不要檢測(cè)低字節(jié),因?yàn)榭隙ㄊ菨h字了
  503.                         }
  504.                         else                                                                //如果高字節(jié)是半角字符
  505.                         {
  506.                                 flag=1;                                                        //若在低字節(jié)ram寫(xiě)入漢字就亂碼了,故檢測(cè)
  507.                         }                                
  508.                 }

  509.                 if(cols%2!=0)                                                    //對(duì)于液晶低字節(jié)
  510.                 {
  511.                         if(flag)                                                        //如果要檢測(cè)低字節(jié)
  512.                         {
  513.                                 if(*pBuf>127)                                        //如果低字節(jié)是漢字碼
  514.                                 {
  515.                                         LCD12864_writeByte(0x20);        //插入一個(gè)空格
  516.                                         cols++;                                                //字節(jié)計(jì)數(shù)器++
  517.                                         flag=0;                                                //清檢測(cè)標(biāo)志
  518.                                 }                                       
  519.                         }        
  520.                 }      
  521.                
  522.                 if(cols)                                                                //行尾檢測(cè)
  523.                 {
  524.                         if(0==cols%16)                                                //如果一行滿了
  525.                         {
  526.                                 row++;                                                        //準(zhǔn)備將光標(biāo)移到下一行
  527.                                 cols=0;                                                        //列坐標(biāo)置于行首
  528.                                 LCD12864_setScrollPos(row, cols);                //設(shè)置新位址
  529.                         }                                
  530.                 }

  531.                 LCD12864_writeByte(*pBuf++);                        //終于可以寫(xiě)數(shù)據(jù)了
  532.                 cols++;                                                                    //列號(hào)累加
  533.     }
  534. }

  535. void  LCD12864_startScroll(u8 scrollNum,u16 delay_ms)  //滾動(dòng)
  536. {        //scrollNum建議值為64
  537.         u8 i;
  538.         LCD12864_writeCmd(0x34);         
  539.         LCD12864_writeCmd(0x03);
  540.         for(i=0x40;i<0x40+scrollNum;i++)
  541.         {  
  542.                 LCD12864_writeCmd(i); //設(shè)置卷動(dòng)地址
  543.                 delayms(delay_ms);                    //實(shí)際使用時(shí)建議用定時(shí)器處理
  544.         }
  545.         LCD12864_writeCmd(0x40);  //補(bǔ)滾一行
  546.         LCD12864_writeCmd(0x30);
  547. }

  548. void LCD12864_setScrollPos(u8 row, u8 cols)                //設(shè)置光標(biāo)位置 ,卷動(dòng)模式
  549. {                                                                                                //row行坐標(biāo)0~3
  550.         u8 newPos=0;                                                                //cols列坐標(biāo)0~15
  551.         switch(row)
  552.         {
  553.                 case 0:
  554.                 {
  555.                         row=0xa8;        
  556.                 }
  557.                 break;
  558.                 case 1:
  559.                 {
  560.                         row=0xb8;
  561.                 }
  562.                 break;
  563.                 case 2:
  564.                 {
  565.                         row=0xa0;
  566.                 }
  567.                 break;
  568.                 case 3:
  569.                 {
  570.                         row=0xb0;
  571.                 }
  572.                 break;
  573.                 default:                //如果需要檢測(cè)行坐標(biāo)范圍,可在這里加代碼
  574.                 break;                        
  575.         }
  576.         newPos=row+cols/2;        //液晶寫(xiě)指令坐標(biāo)只能8級(jí),我的函數(shù)中列坐標(biāo)是16級(jí)的,支持半角全角混合
  577.         LCD12864_writeCmd(newPos);
  578. }


  579. void LCD12864_setPos(u8 row, u8 cols)                        //設(shè)置光標(biāo)位置
  580. {                                                                                                //row行坐標(biāo)0~3
  581.         u8 newPos=0;                                                                //cols列坐標(biāo)0~15
  582.         switch(row)
  583.         {
  584.                 case 0:
  585.                 {
  586.                         row=0x80;        
  587.                 }
  588.                 break;
  589.                 case 1:
  590.                 {
  591.                         row=0x90;
  592.                 }
  593.                 break;
  594.                 case 2:
  595.                 {
  596.                         row=0x88;
  597.                 }
  598.                 break;
  599.                 case 3:
  600.                 {
  601.                         row=0x98;
  602.                 }
  603.                 break;
  604.                 case 4:
  605.                 {
  606.                         row=0xa0;
  607.                 }
  608.                 break;
  609.                 case 5:
  610.                 {
  611.                         row=0xb0;
  612.                 }
  613.                 break;
  614.                 case 6:
  615.                 {
  616.                         row=0xa8;
  617.                 }
  618.                 break;
  619.                 case 7:
  620.                 {
  621.                         row=0xb8;
  622.                 }
  623.                 break;

  624.                 default:                //如果需要檢測(cè)行坐標(biāo)范圍,可在這里加代碼
  625.                 break;                        
  626.         }
  627.         newPos=row+cols/2;        //液晶寫(xiě)指令坐標(biāo)只能8級(jí),我的函數(shù)中列坐標(biāo)是16級(jí)的,支持半角全角混合
  628.         LCD12864_writeCmd(newPos);
  629. }
  630. /*
  631. void LCD12864_setPos(u8 row, u8 cols)                        //設(shè)置光標(biāo)位置
  632. {                                                                                                //row行坐標(biāo)0~3
  633.         u8 newPos=0;                                                                //cols列坐標(biāo)0~15
  634.         switch(row)
  635.         {
  636.                 case 0:
  637.                 {
  638.                         row=0x80;        
  639.                 }
  640.                 break;
  641.                 case 1:
  642.                 {
  643.                         row=0x90;
  644.                 }
  645.                 break;
  646.                 case 2:
  647.                 {
  648.                         row=0x88;
  649.                 }
  650.                 break;
  651.                 case 3:
  652.                 {
  653.                         row=0x98;
  654.                 }
  655.                 break;
  656.                 default:                //如果需要檢測(cè)行坐標(biāo)范圍,可在這里加代碼
  657.                 break;                        
  658.         }
  659.         newPos=row+cols/2;        //液晶寫(xiě)指令坐標(biāo)只能8級(jí),我的函數(shù)中列坐標(biāo)是16級(jí)的,支持半角全角混合
  660.         LCD12864_writeCmd(newPos);
  661. }
  662.          */



  663. void LCD12864_init()                                  //初始化
  664. {
  665.         delayms(40);                                          //rst由低到高后保持40ms以上,我們的rst接VCC
  666.         LCD_PSB= 1;                                                    //選擇并口方式

  667.         LCD12864_writeCmd( B(110000) );          //0x30,啟用基本指令集
  668.         delayXus(15);                                          //要求延時(shí)100us以上,(8+6x)*1.085=106us

  669.         LCD12864_writeCmd( B(110000) );   //0x30,要求寫(xiě)2次該指令
  670.         delayXus(5);                                           //要求延時(shí)37us以上,(8+6x)*1.085=41us

  671.     LCD12864_writeCmd( B(1100) );          //0x0f,整體顯示,游標(biāo),游標(biāo)反白
  672.         delayXus(15);                                          //要求延時(shí)100us以上

  673.         LCD12864_writeCmd( B(0001) );          //0x01,清屏指令,整屏幕寫(xiě)滿空格
  674.         delayms(10);                                           //要求延時(shí)10ms以上

  675.         LCD12864_writeCmd( B(110) );          //0x06,進(jìn)入模式設(shè)置,游標(biāo)自動(dòng)指向下一位置,
  676.                                                 
  677.         delayms(5);                                                    //手冊(cè)上沒(méi)說(shuō)這里要延時(shí),額,還是加上吧
  678. }


  679. void LCD12864_writeCmd(u8 cmd)                    //寫(xiě)指令
  680. {
  681.         while(LCD12864_isBusy());
  682.         LCD_EN=0;                                                   //使能 拉低
  683.         LCD_RW=0;                                                   //寫(xiě)
  684.         LCD_RS=0;_nop_();                                  //命令
  685.                
  686.         LCD_EN=1;                                                  //使能
  687.         LCD_dataBus=cmd;                                  //送指令
  688.         _nop_();_nop_();                              //穩(wěn)定

  689.         LCD_EN=0;_nop_();                           //取走
  690. }

  691. void LCD12864_writeByte(u8 dat)                     //寫(xiě)一個(gè)字節(jié)
  692. {
  693.         while(LCD12864_isBusy());
  694.         LCD_EN=0;                                 //使能先拉低
  695.         LCD_RW=0;                                 //寫(xiě)
  696.         LCD_RS=1;_nop_();                 //數(shù)據(jù)
  697.         
  698.         LCD_EN=1;
  699.         LCD_dataBus=dat;
  700.         _nop_();_nop_();                 //延時(shí)大于1.5us

  701.         LCD_EN=0;_nop_();                 //下降沿取走數(shù)據(jù)
  702. }

  703. u8 LCD12864_readByte()                  //讀數(shù)據(jù)暫存器Data Register
  704. {                                                         //用的時(shí)候要空操作一次
  705.         u8 temp=0;
  706.         while(LCD12864_isBusy());//忙檢測(cè)
  707.         LCD_dataBus=0xff;                 //用總線讀數(shù)據(jù)時(shí)必須先置為輸入模式
  708.         LCD_EN=0;                                 //使能線拉低
  709.         LCD_RW=1;                                 //讀
  710.         LCD_RS=1;_nop_();                 //數(shù)據(jù)                                         
  711.         LCD_EN=1;_nop_();                 //使能
  712.         temp=LCD_dataBus;                 //取走數(shù)據(jù)
  713.         
  714.         _nop_();
  715.         LCD_EN=0;                                 //使能恢復(fù)
  716.         return temp;
  717. }

  718. bool LCD12864_isBusy()                   //檢測(cè)液晶是否忙
  719. {
  720.         if(LCD12864_readIR() & 0x80) //檢測(cè)BF位
  721.         {
  722.                 return TRUE;                  //忙
  723.         }
  724.         return FALSE;                          //不忙
  725. }

  726. u8 LCD12864_readIR()                 //讀指令暫存器Instruction Register
  727. {
  728.         u8 temp=0;
  729.         LCD_EN=0;                                 //使能準(zhǔn)備
  730.         LCD_RW=1;                                 //讀
  731.         LCD_RS=0;_nop_();                 //命令字
  732.         LCD_dataBus=0xff;               //準(zhǔn)備輸入
  733.         LCD_EN=1;_nop_();             //使能
  734.         temp=LCD_dataBus;                 //提取數(shù)據(jù)

  735.         _nop_();
  736.         LCD_EN=0;                                 //使能拉低
  737.         return temp;                  
  738. }

復(fù)制代碼




分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩

相關(guān)帖子

回復(fù)

使用道具 舉報(bào)

無(wú)效樓層,該帖已經(jīng)被刪除
板凳
ID:137736 發(fā)表于 2022-8-30 12:49 | 只看該作者
太好了,生成了頭文件,使用很方便,感謝
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表