找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5009|回复: 1
收起左侧

PIC单片机驱动LCD12864显示字符源代码

[复制链接]
ID:192549 发表于 2017-4-23 00:23 | 显示全部楼层 |阅读模式
  1. #include <pic.h>       //调用头文件,可以去PICC软件下去查找PIC16F87XA单片机的头文件
  2. __CONFIG(XT&WDTDIS&LVPDIS);   
  3. //定义配置字,晶振类型:XT,关闭开门狗,禁止低电压编程
  4. #define Rs  RB0 //并行数据/控制字选择 H:数据  L:控制字
  5. #define RW  RB1 //并行读/写选择       H:读    L:写
  6. #define E   RB2 //并行读写使能        H有效,下降沿锁定数据
  7. #define Psb RB3 //串口,并口选择       H:并口  L:串口(开发板上引脚标识为CS1)
  8. #define Rst RB5 //复位引脚            L:液晶复位
  9. //---------------------------------------
  10. //名称: 延时函数

  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. //名称: 数据总线处理函数

  25. //ND118开发板中,因为布线的原因液晶的8位数据总线和单片机的8位数据线
  26. //是反的,所以需要调换过来,即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. //名称: 写命令字节到12864函数

  49. //-----------------------------------------
  50. void write_com(unsigned char cmdcode)
  51. {
  52. unsigned int ii=20000;
  53. Rs=0;                    //设置该字节数据为命令代码
  54. RW=1;                    //设置此次操作为读
  55. E=1;                     //使能
  56. TRISD=0B11111111;     //RD设置为输入
  57. while((PORTD&0X01)&&(ii>0))          //读忙状态,不忙时退出
  58. {
  59.   ii--;
  60. }
  61. E=0;                    //失能
  62. TRISD=0B00000000;    //RD设置为输出
  63. Rs=0;                   //设置该字节数据为控制命令
  64. RW=0;                   //设置此次操作为读写
  65. write_bus(cmdcode);     //通过数据总线处理函数将命令字写进总线中去
  66. E=1;                    //使能写
  67. asm("NOP");             //略加延迟
  68. asm("NOP");
  69. asm("NOP");
  70. E=0;                    //失能写
  71. }
  72. //---------------------------------------
  73. //名称: 写数据字节到12864函数

  74. //-----------------------------------------
  75. void write_data(unsigned char Rsspdata)
  76. {
  77. unsigned int ii=20000;
  78. Rs=0;                    //设置该字节数据为命令代码
  79. RW=1;                    //设置此次操作为读
  80. E=1;                     //使能
  81. TRISD=0B11111111;     //RD设置为输入
  82. while((PORTD&0X01)&&(ii>0))          //读忙状态,不忙时退出
  83. {
  84.   ii--;
  85. }
  86. E=0;                    //失能
  87. TRISD=0B00000000;    //RD设置为输出
  88. Rs=1;                   //设置该字节数据为数据
  89. RW=0;                   //设置此次操作为读写
  90. write_bus(Rsspdata);    //通过数据总线处理函数将命令字写进总线中去
  91. E=1;                    //使能写
  92. asm("NOP");             //略加延迟
  93. asm("NOP");
  94. asm("NOP");
  95. E=0;                    //失能写
  96. }
  97. //---------------------------------------
  98. //名称: 写地址函数
  99. //输入参数: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;           //复位液晶
  119. delay(250);      //加些延时
  120. delay(250);
  121. Rst=1;           //复位结束
  122. delay(250);      //加些延时
  123. Psb=1;           //选择8bit并口

  124. write_com(0x30);  //基本指令集  
  125. write_com(0x0c);  //显示开
  126. write_com(0x06);  //光标右移,整体显示不移动
  127. write_com(0x01);  //清除显示(清零DDRAM)
  128. delay(250);

  129. }
  130. //---------------------------------------
  131. //名称: 指定地址中英文字符串显示函数

  132. //-----------------------------------------
  133. void write_string(unsigned char x,unsigned char y,const unsigned char *s)
  134. {
  135. write_xy(x,y);   //先写入地址参数
  136. while(*s)        //只要字符串没写完就继续写
  137. {
  138.   write_data(*s); //写入一个字符串数据
  139.   s++;            //指针转到下一个
  140.   delay(10);
  141. }
  142. }
  143. //---------------------------------------
  144. //名称: 整行中英文字符串显示函数

  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. //名称: 主函数   

  204. //-----------------------------------------
  205. void main(void)
  206. {   
  207.    TRISB=0B11000000;    //RB0-5设置为输出
  208. TRISD=0B00000000;    //RD设置为输出
  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. }

复制代码

回复

使用道具 举报

ID:215984 发表于 2018-6-22 17:28 | 显示全部楼层
PIC关于LCD12864驱动的文章很少,学习了。有个问题想请教楼主:可否不要并串口的选择口,还有就是一定要复位吗?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表