微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > pg12864f液晶好难搞定

pg12864f液晶好难搞定

时间:10-02 整理:3721RD 点击:
简直分析不出原因了


仿真后出现这种情况,虽然能显示,但是不完整
附上源码


  1. #include<reg51.h>
  2. #include<intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. sbit wr=P2^0;
  6. sbit rd=P2^1;
  7. sbit ce=P2^2;
  8. sbit cd=P2^3;
  9. sbit rst=P2^4;
  10. uchar code HZ0[3][35]={{
  11. /*--  文字:  王  --*/
  12. /*--  楷体_GB231211;  此字体下对应的点阵为:宽x高=14x14   --*/
  13. /*--  宽度不是8的倍数,现调整为:宽度x高度=16x14  --*/
  14. 0x00,0x00,0x00,0x00,0x01,0xC0,0x1E,0x00,0x02,0x00,0x02,0x00,0x03,0x80,0x1E,0x00,
  15. 0x02,0x00,0x02,0x00,0x03,0xF0,0x7C,0x00,0x00,0x00,0x00,0x00,


  16. },

  17. {/*--  文字:  东  --*/
  18. /*--  楷体_GB231211;  此字体下对应的点阵为:宽x高=14x14   --*/
  19. /*--  宽度不是8的倍数,现调整为:宽度x高度=16x14  --*/
  20. 0x02,0x00,0x02,0x00,0x04,0xE0,0x3F,0x00,0x08,0x00,0x0A,0x00,0x13,0xC0,0x3E,0x00,
  21. 0x02,0x00,0x12,0x40,0x22,0x20,0x46,0x10,0x02,0x00,0x00,0x00,


  22. },

  23. {/*--  文字:  华  --*/
  24. /*--  楷体_GB231211;  此字体下对应的点阵为:宽x高=14x14   --*/
  25. /*--  宽度不是8的倍数,现调整为:宽度x高度=16x14  --*/
  26. 0x09,0x00,0x09,0x40,0x11,0x40,0x31,0x80,0x57,0x20,0x11,0xE0,0x12,0x00,0x03,0xF0,
  27. 0x7E,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,},
  28. };
  29. uchar code HZ1[6][35]=
  30. {
  31. {/*--  文字:  0  --*/
  32. /*--  宋体11;  此字体下对应的点阵为:宽x高=7x14   --*/
  33. /*--  宽度不是8的倍数,现调整为:宽度x高度=8x14  --*/
  34. 0x00,0x00,0x00,0x30,0x48,0x84,0x84,0x84,0x84,0x84,0x48,0x30,0x00,0x00,
  35. },
  36. {/*--  文字:  9  --*/
  37. /*--  宋体11;  此字体下对应的点阵为:宽x高=7x14   --*/
  38. /*--  宽度不是8的倍数,现调整为:宽度x高度=8x14  --*/
  39. 0x00,0x00,0x00,0x78,0x84,0x84,0x84,0x8C,0x74,0x04,0x88,0xF0,0x00,0x00,},

  40. {/*--  文字:  电  --*/
  41. /*--  宋体11;  此字体下对应的点阵为:宽x高=14x14   --*/
  42. /*--  宽度不是8的倍数,现调整为:宽度x高度=16x14  --*/
  43. 0x02,0x00,0x02,0x00,0x02,0x00,0x7F,0xF0,0x42,0x10,0x42,0x10,0x7F,0xF0,0x42,0x10,
  44. 0x42,0x10,0x7F,0xF0,0x42,0x00,0x02,0x08,0x02,0x08,0x01,0xF8,},
  45. {/*--  文字:  子  --*/
  46. /*--  宋体11;  此字体下对应的点阵为:宽x高=14x14   --*/
  47. /*--  宽度不是8的倍数,现调整为:宽度x高度=16x14  --*/
  48. 0x7F,0xF0,0x00,0x20,0x00,0x40,0x00,0x80,0x01,0x00,0x02,0x00,0xFF,0xF8,0x02,0x00,
  49. 0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x0E,0x00,
  50. },
  51. {/*--  文字:  1  --*/
  52. /*--  宋体11;  此字体下对应的点阵为:宽x高=7x14   --*/
  53. /*--  宽度不是8的倍数,现调整为:宽度x高度=8x14  --*/
  54. 0x00,0x00,0x00,0x10,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00,},
  55. {/*--  文字:  班  --*/
  56. /*--  宋体11;  此字体下对应的点阵为:宽x高=14x14   --*/
  57. /*--  宽度不是8的倍数,现调整为:宽度x高度=16x14  --*/
  58. 0x01,0x00,0xF9,0x78,0x21,0x20,0x25,0x20,0x25,0x20,0xFD,0x20,0x25,0x78,0x25,0x20,
  59. 0x29,0x20,0x21,0x20,0x3A,0x20,0xE2,0x20,0x04,0xF8,0x08,0x00,}
  60. };

  61. void delayus(uchar x)
  62. {
  63. while(--x)
  64. {
  65.   _nop_();
  66.   _nop_();
  67.   _nop_();
  68.   _nop_();
  69.   _nop_();
  70.   _nop_();
  71.   _nop_();
  72.   _nop_();
  73.   _nop_();
  74.   _nop_();
  75. }
  76. }

  77. uchar read_status()//读状态
  78. {
  79. uchar status;
  80. rd=0; //读选通信号
  81. wr=1;/
  82. ce=0;//片选信
  83. cd=1;//指令信号
  84. status=P0;/
  85. return status;/
  86. }
  87. void status_check()//检查状态,如果读状态后返回的值后两位为1,则退出检测状态,否则,需等待;要更改状态检测条件,只需改0x03
  88. {
  89. uchar s;
  90. while((s&0x03)!=0x03)//按位与,再和0x03相匹配,若一致,则退出检测
  91.     s=read_status();
  92. }

  93. void data_write(uint data1)
  94. {
  95. rd=1;//读选通信号失效
  96. cd=0;//通道选择数据
  97. ce=0;//启动控制芯片
  98. wr=0;//写信号有效
  99. P0=data1;
  100. delayus(10);
  101. wr=1;//关写信号
  102. ce=1;//芯片关闭
  103. cd=1;//指令信号
  104. }
  105. void command_write(uchar command)//写信号函数
  106. {
  107. rd=1;//读选通信号失效
  108. cd=1;//选择指令通道
  109. wr=0;//写信号
  110. ce=0;//启动控制芯片
  111. P0=command;
  112. delayus(10);
  113. wr=1;//貌似每次冬眠一次
  114. ce=1;
  115. cd=0;
  116. }
  117. void command_sending_with_one_data(uchar data1,uchar command)//先送参数,再送指令
  118. {
  119. status_check();//检查状态
  120. data_write(data1);//写入数据
  121. status_check(); //再检查一次状态
  122. command_write(command);//写入命令
  123. }
  124. void command_sending_with_two_data(uint data1,uint data2,uchar command)
  125. {
  126. status_check();
  127. data_write(data1);
  128. status_check();
  129. data_write(data2);
  130. status_check();
  131. command_write(command);   
  132. }
  133. void display_HZ(uchar x,uint y,uchar *hz)///x 0-3  y 0-7位置指定,汉字指针
  134. {
  135. uint add_init,add;
  136. uchar i,j=0;
  137. add_init=y*16;
  138. i=0;
  139. for(j=add_init;j<add_init+16;j++)             //规定显示在第一行,前面已经定义了16字节/每行,这个循环其实就是j=0;j<16;j++
  140. {
  141.   add=j*16+x*2;
  142.   command_sending_with_two_data(add%256,add/256,0x24);//地址指针设置  低地址,高地址,命令设置地址指针,就是字符在液晶屏的位置
  143.   command_sending_with_one_data(hz[i++],0xc0);
  144.   command_sending_with_one_data(hz[i++],0xc0);
  145. }
  146. }
  147. void display_SZ(uchar x,uint y,uchar *hz)///x 0-3  y 0-7位置指定,数字指针
  148. {
  149. uint add_init,add;
  150. uchar i,j=0;
  151. add_init=y*16;
  152. i=0;
  153. for(j=add_init;j<add_init+16;j++)             //规定显示在第一行,前面已经定义了16字节/每行,这个循环其实就是j=0;j<16;j++
  154. {
  155.   add=j*16+x*2;
  156.   command_sending_with_two_data(add%256,add/256,0x24);//地址指针设置  低地址,高地址,命令设置地址指针,就是字符在液晶屏的位置
  157.   command_sending_with_one_data(hz[i++],0xc0);
  158. }
  159. }


  160. /* 数据自动写清屏 */
  161. void chear_screen()
  162. {
  163. uint i,j;
  164. command_sending_with_two_data(0x00,0x00,0x24);//图形模式下,位地址指针设置命令0x24,设为0x0000初地址
  165. status_check();//检查状态
  166. for(i=0;i<64;i++)              //总共要写清64行
  167. {
  168. command_sending_with_two_data((i*16)%256,(1*16)/256,0x24);         //指定每一行的首地址
  169. status_check();//检查状态
  170. command_write(0xb0);           //数据自动写,每写一次,地址指针加一
  171. for(j=0;j<16;j++)                  //每一行128个字/像素,128/8=16字节
  172. {  
  173.     status_check();//检查状态
  174.    data_write(0x00);
  175.   
  176. }
  177. command_write(0xb2);       //自动写结束

  178. }
  179. }
  180. void init_12864()
  181. {
  182. wr=1;//读失效
  183. rd=1;//写失效
  184. ce=1;//片选信号无
  185. cd=1;//指令信号
  186. rst=1;//不复位
  187. status_check();//检查状态
  188. command_sending_with_two_data(0x01,0x00,0x21); //光标指针设置,前两位子节为该单元地址的高位和地位,后一个字节为指令代码,然而后面并没有开光标显示。
  189. status_check();                                //地址指针在开始写字的时候才进行设置
  190. command_sending_with_two_data(0x00,0x00,0x42); //设置图形显示首地址 GDRAM,第三个字节表明选择图像区首址功能,前两个字节为地址高位低位,不懂
  191. status_check();
  192. command_sending_with_two_data(16,0x00,0x43);   //设置图形区域大小,第三位字节表明选择图像区宽度(字节数/每行)16为字节数,参考字模数组0x00为00H,固定化
  193. status_check();
  194. command_write(0x80);      //模式设置,正常显示,不懂
  195. status_check();
  196. command_write(0x98);      //显示设置,文本关闭,图形显示
  197. status_check();
  198. command_write(0xa0);      //光标设置10100N2,N1,N0
  199. chear_screen();           //清屏
  200. }

  201. void main()
  202. {
  203. uchar i=0;
  204. init_12864();
  205. for(i=0;i<3;i++)
  206.     display_HZ(2+i,0,HZ0[i]);//第0行,第i+1列
  207.         display_SZ(1,1,HZ1[0]);//0
  208.                 display_SZ(2,1,HZ1[1]);//9
  209.                         display_HZ(3,1,HZ1[2]);//电

复制代码



好想是发送数据坐标出了点问题吧,你找仔细查查

12864不是能直接显示汉字吗?

建议你换个其他的Lcd12864用!

  command_sending_with_two_data(add%256,add/256,0x24);//地址指针设置  低地址,高地址,命令设置地址指针,就是字符在液晶屏的位置
  command_sending_with_one_data(hz[i++],0xc0);
  command_sending_with_one_data(hz[i++],0xc0);
这里在添加一句看看

HZ0[3][35]这一行代码出现问题,给数组分配了35列,实际只用了32,后面位自动补充0。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top