找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5304|回復(fù): 1
收起左側(cè)

PIC單片機驅(qū)動LCD12864顯示字符源代碼

[復(fù)制鏈接]
ID:192549 發(fā)表于 2017-4-23 00:23 | 顯示全部樓層 |閱讀模式
  1. #include <pic.h>       //調(diào)用頭文件,可以去PICC軟件下去查找PIC16F87XA單片機的頭文件
  2. __CONFIG(XT&WDTDIS&LVPDIS);   
  3. //定義配置字,晶振類型:XT,關(guān)閉開門狗,禁止低電壓編程
  4. #define Rs  RB0 //并行數(shù)據(jù)/控制字選擇 H:數(shù)據(jù)  L:控制字
  5. #define RW  RB1 //并行讀/寫選擇       H:讀    L:寫
  6. #define E   RB2 //并行讀寫使能        H有效,下降沿鎖定數(shù)據(jù)
  7. #define Psb RB3 //串口,并口選擇       H:并口  L:串口(開發(fā)板上引腳標(biāo)識為CS1)
  8. #define Rst RB5 //復(fù)位引腳            L:液晶復(fù)位
  9. //---------------------------------------
  10. //名稱: 延時函數(shù)

  11. //-----------------------------------------
  12. void delay(unsigned int t)
  13. {
  14. unsigned int i,j;
  15. for(i=0;i<t;i++)
  16. {
  17.   for(j=0;j<10;j++)
  18.   {
  19.    asm("NOP");
  20.   }
  21. }
  22. }
  23. //---------------------------------------
  24. //名稱: 數(shù)據(jù)總線處理函數(shù)

  25. //ND118開發(fā)板中,因為布線的原因液晶的8位數(shù)據(jù)總線和單片機的8位數(shù)據(jù)線
  26. //是反的,所以需要調(diào)換過來,即DB0-RD7、DB1-RD6。。。。DB7-RD0
  27. //-----------------------------------------
  28. void write_bus(unsigned char buf)
  29. {
  30. if(buf&0x01) RD7=1;   
  31. else RD7=0;
  32. if(buf&0x02) RD6=1;   
  33. else RD6=0;
  34. if(buf&0x04) RD5=1;   
  35. else RD5=0;
  36. if(buf&0x08) RD4=1;   
  37. else RD4=0;
  38. if(buf&0x10) RD3=1;   
  39. else RD3=0;
  40. if(buf&0x20) RD2=1;   
  41. else RD2=0;
  42. if(buf&0x40) RD1=1;   
  43. else RD1=0;
  44. if(buf&0x80) RD0=1;
  45. else RD0=0;
  46. }
  47. //---------------------------------------
  48. //名稱: 寫命令字節(jié)到12864函數(shù)

  49. //-----------------------------------------
  50. void write_com(unsigned char cmdcode)
  51. {
  52. unsigned int ii=20000;
  53. Rs=0;                    //設(shè)置該字節(jié)數(shù)據(jù)為命令代碼
  54. RW=1;                    //設(shè)置此次操作為讀
  55. E=1;                     //使能
  56. TRISD=0B11111111;     //RD設(shè)置為輸入
  57. while((PORTD&0X01)&&(ii>0))          //讀忙狀態(tài),不忙時退出
  58. {
  59.   ii--;
  60. }
  61. E=0;                    //失能
  62. TRISD=0B00000000;    //RD設(shè)置為輸出
  63. Rs=0;                   //設(shè)置該字節(jié)數(shù)據(jù)為控制命令
  64. RW=0;                   //設(shè)置此次操作為讀寫
  65. write_bus(cmdcode);     //通過數(shù)據(jù)總線處理函數(shù)將命令字寫進總線中去
  66. E=1;                    //使能寫
  67. asm("NOP");             //略加延遲
  68. asm("NOP");
  69. asm("NOP");
  70. E=0;                    //失能寫
  71. }
  72. //---------------------------------------
  73. //名稱: 寫數(shù)據(jù)字節(jié)到12864函數(shù)

  74. //-----------------------------------------
  75. void write_data(unsigned char Rsspdata)
  76. {
  77. unsigned int ii=20000;
  78. Rs=0;                    //設(shè)置該字節(jié)數(shù)據(jù)為命令代碼
  79. RW=1;                    //設(shè)置此次操作為讀
  80. E=1;                     //使能
  81. TRISD=0B11111111;     //RD設(shè)置為輸入
  82. while((PORTD&0X01)&&(ii>0))          //讀忙狀態(tài),不忙時退出
  83. {
  84.   ii--;
  85. }
  86. E=0;                    //失能
  87. TRISD=0B00000000;    //RD設(shè)置為輸出
  88. Rs=1;                   //設(shè)置該字節(jié)數(shù)據(jù)為數(shù)據(jù)
  89. RW=0;                   //設(shè)置此次操作為讀寫
  90. write_bus(Rsspdata);    //通過數(shù)據(jù)總線處理函數(shù)將命令字寫進總線中去
  91. E=1;                    //使能寫
  92. asm("NOP");             //略加延遲
  93. asm("NOP");
  94. asm("NOP");
  95. E=0;                    //失能寫
  96. }
  97. //---------------------------------------
  98. //名稱: 寫地址函數(shù)
  99. //輸入?yún)?shù):x,y:顯示字符串的位置,x:0-7,y:0-3

  100. //-----------------------------------------
  101. void write_xy(unsigned char x,unsigned char y)
  102. {
  103. unsigned char address;
  104. switch(y){
  105.   case 0:address=0x80+x;break;  //第一行的首地址是0x80
  106.   case 1:address=0x90+x;break;  //第二行的首地址是0x90
  107.   case 2:address=0x88+x;break;  //第三行的首地址是0x88
  108.   case 3:address=0x98+x;break;  //第四行的首地址是0x98
  109.   default:address=0x80+x;
  110.    }
  111. write_com(address);
  112. }
  113. //---------------------------------------
  114. //名稱: 初始化LCD屏

  115. //-----------------------------------------
  116. void init_lcd(void)
  117. {
  118. Rst=0;           //復(fù)位液晶
  119. delay(250);      //加些延時
  120. delay(250);
  121. Rst=1;           //復(fù)位結(jié)束
  122. delay(250);      //加些延時
  123. Psb=1;           //選擇8bit并口

  124. write_com(0x30);  //基本指令集  
  125. write_com(0x0c);  //顯示開
  126. write_com(0x06);  //光標(biāo)右移,整體顯示不移動
  127. write_com(0x01);  //清除顯示(清零DDRAM)
  128. delay(250);

  129. }
  130. //---------------------------------------
  131. //名稱: 指定地址中英文字符串顯示函數(shù)

  132. //-----------------------------------------
  133. void write_string(unsigned char x,unsigned char y,const unsigned char *s)
  134. {
  135. write_xy(x,y);   //先寫入地址參數(shù)
  136. while(*s)        //只要字符串沒寫完就繼續(xù)寫
  137. {
  138.   write_data(*s); //寫入一個字符串?dāng)?shù)據(jù)
  139.   s++;            //指針轉(zhuǎn)到下一個
  140.   delay(10);
  141. }
  142. }
  143. //---------------------------------------
  144. //名稱: 整行中英文字符串顯示函數(shù)

  145. //-----------------------------------------
  146. void lcd12864_dis_oneline(unsigned char line,const unsigned char *p)
  147. {
  148.   unsigned char c;
  149.   switch(line%4)
  150.   {
  151.     case 0:   
  152.             write_com(0x80);  //第一行的首地址為0x80
  153.             for(c=0;c<16;c++) //將本行的16個字符全部寫進去,漢字占兩個字符位
  154.             {
  155.               write_data(*p);
  156.               p++;
  157.               if(*p==0)
  158.               {
  159.                 break;
  160.               }
  161.             }   
  162.             break;
  163.     case 1:
  164.             write_com(0x90);  //第二行的首地址為0x90
  165.             for(c=0;c<16;c++) //將本行的16個字符全部寫進去,漢字占兩個字符位
  166.             {
  167.               write_data(*p);
  168.             p++;
  169.               if(*p==0)
  170.               {
  171.                 break;
  172.               }
  173.             }   
  174.             break;
  175.     case 2:
  176.             write_com(0x88);  //第三行的首地址為0x88
  177.             for(c=0;c<16;c++) //將本行的16個字符全部寫進去,漢字占兩個字符位
  178.             {
  179.               write_data(*p);
  180.               p++;
  181.               if(*p==0)
  182.               {
  183.                 break;
  184.               }
  185.             }   
  186.             break;
  187.     case 3:
  188.             write_com(0x98);  //第四行的首地址為0x98
  189.             for(c=0;c<16;c++) //將本行的16個字符全部寫進去,漢字占兩個字符位
  190.             {
  191.               write_data(*p);
  192.               p++;
  193.               if(*p==0)
  194.               {
  195.                 break;
  196.               }
  197.             }   
  198.             break;
  199.     default : break;
  200.   }
  201. }
  202. //---------------------------------------
  203. //名稱: 主函數(shù)   

  204. //-----------------------------------------
  205. void main(void)
  206. {   
  207.    TRISB=0B11000000;    //RB0-5設(shè)置為輸出
  208. TRISD=0B00000000;    //RD設(shè)置為輸出
  209.    init_lcd();             //初始化12864
  210. write_string(0,0,"XXXX電子有限");
  211.     write_string(0,1,"公司");
  212. write_string(0,2,"MovingChip.com");
  213. write_string(0,3,"0574-86878555");
  214. while(1)
  215. {  

  216. }  
  217. }

復(fù)制代碼

回復(fù)

使用道具 舉報

ID:215984 發(fā)表于 2018-6-22 17:28 | 顯示全部樓層
PIC關(guān)于LCD12864驅(qū)動的文章很少,學(xué)習(xí)了。有個問題想請教樓主:可否不要并串口的選擇口,還有就是一定要復(fù)位嗎?
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

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

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

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