JLX12864G-290-PC-S液晶屏的51单片机源程序

[复制链接]
查看2 | 回复0 | 2021-4-17 01:28:41 | 显示全部楼层 |阅读模式
单片机源程序如下:
  1. /* Test program for JLX12864G-290-PC-S,串行接口,带中文字库 IC
  2. 驱动 IC 是:ST7567(or competible),字库 IC:JLX-GB2312

  3. */
  4. #include <reg51.H>
  5. #include <intrins.h>
  6. sbit lcd_sclk=P3^2; //接口定义:lcd_sclk 就是 LCD 的 sclk
  7. sbit lcd_sid=P3^1; //接口定义:lcd_sid 就是 LCD 的 sid
  8. sbit lcd_rs=P3^0; //接口定义:lcd_rs 就是 LCD 的 rs
  9. sbit lcd_reset=P1^0; //接口定义:lcd_reset 就是 LCD 的 reset
  10. sbit lcd_cs1=P1^1; //接口定义:lcd_cs1 就是 LCD 的 cs1
  11. sbit Rom_IN=P1^2; //字库 IC 接口定义:Rom_IN 就是字库 IC 的 SI

  12. sbit Rom_OUT=P1^3; //字库 IC 接口定义:Rom_OUT 就是字库 IC 的 SO
  13. sbit Rom_SCK=P1^4; //字库 IC 接口定义:Rom_SCK 就是字库 IC 的 SCK
  14. sbit Rom_CS=P1^5; //字库 IC 接口定义 Rom_CS 就是字库 IC 的 CS#
  15. sbit key=P2^0; //定义一个按键
  16. #define uchar unsigned char
  17. #define uint unsigned int
  18. #define ulong unsigned long

  19. void delay_us(int i);

  20. /*写指令到 LCD 模块*/
  21. void transfer_command_lcd(int data1)
  22. {
  23. char i;
  24. lcd_cs1=0;
  25. lcd_rs=0;
  26. for(i=0;i<8;i++)
  27. {
  28. lcd_sclk=0;
  29. delay_us(1);
  30. if(data1&0x80) lcd_sid=1;
  31. else lcd_sid=0;
  32. lcd_sclk=1;
  33. delay_us(1);

  34. data1=data1<<=1;
  35. }
  36. lcd_cs1=1;
  37. }
  38. /*写数据到 LCD 模块*/
  39. void transfer_data_lcd(int data1)
  40. {
  41. char i;
  42. lcd_cs1=0;
  43. lcd_rs=1;
  44. for(i=0;i<8;i++)
  45. {
  46. lcd_sclk=0;
  47. if(data1&0x80) lcd_sid=1;
  48. else lcd_sid=0;
  49. lcd_sclk=1;
  50. data1=data1<<=1;
  51. }
  52. lcd_cs1=1;
  53. }
  54. /*延时*/
  55. void delay(int i)
  56. {
  57. int j,k;
  58. for(j=0;j<i;j++)
  59. for(k=0;k<500;k++);
  60. }
  61. /*短延时*/
  62. void delay_us(int i)
  63. {
  64. int j,k;
  65. for(j=0;j<i;j++)
  66. for(k=0;k<2;k++);
  67. }
  68. /*等待一个按键,我的主板是用 P2.0 与 GND 之间接一个按键*/
  69. void waitkey()
  70. {
  71. repeat:
  72. if (P2&0x01) goto repeat;
  73. else delay(60);
  74. if (P2&0x01) goto repeat;
  75. else
  76. delay(400);
  77. }
  78. /*LCD 模块初始化*/
  79. void initial_lcd()
  80. {
  81. lcd_reset=0; /*低电平复位*/
  82. delay(20);
  83. lcd_reset=1; /*复位完毕*/
  84. delay(20);
  85. transfer_command_lcd(0xe2); /*软复位*/
  86. delay(5);
  87. transfer_command_lcd(0x2c); /*升压步聚 1*/
  88. delay(5);
  89. transfer_command_lcd(0x2e); /*升压步聚 2*/
  90. delay(5);
  91. transfer_command_lcd(0x2f); /*升压步聚 3*/
  92. delay(5);
  93. transfer_command_lcd(0x24); /*粗调对比度,可设置范围 0x20~0x27*/
  94. transfer_command_lcd(0x81); /*微调对比度*/
  95. transfer_command_lcd(0x2a); /*0x1a,微调对比度的值,可设置范围 0x00~0x3f*/
  96. transfer_command_lcd(0xa2); /*1/9 偏压比(bias)*/
  97. transfer_command_lcd(0xc8); /*行扫描顺序:从上到下*/
  98. transfer_command_lcd(0xa0); /*列扫描顺序:从左到右*/
  99. transfer_command_lcd(0x40); /*起始行:第一行开始*/
  100. transfer_command_lcd(0xaf); /*开显示*/
  101. }
  102. void lcd_address(uint page,uint column)
  103. {
  104. column=column-1;
  105. transfer_command_lcd(0xb0+page-1); /*设置页地址*/
  106. transfer_command_lcd(0x10+(column>>4&0x0f)); /*设置列地址的高 4 位*/
  107. transfer_command_lcd(column&0x0f); /*设置列地址的低 4 位*/
  108. }
  109. /*全屏清屏*/
  110. void clear_screen()
  111. {
  112. unsigned char i,j;
  113. for(i=0;i<9;i++)
  114. {
  115. lcd_address(1+i,1);
  116. for(j=0;j<224;j++)
  117. {
  118. transfer_data_lcd(0x00);
  119. }

  120. }
  121. lcd_cs1=1;
  122. }
  123. //===显示测试画面:例如全显示,隔行显示,隔列显示,雪花显示=====
  124. void test_display(uchar data1,uchar data2)
  125. {
  126. int i,j;
  127. for(j=0;j<8;j++)
  128. {
  129. lcd_address(j+1,1);
  130. for(i=0;i<128;i++)
  131. {
  132. transfer_data_lcd(data1);
  133. transfer_data_lcd(data2);
  134. }
  135. }
  136. }


  137. /*显示 16x16 点阵图像、汉字、生僻字或 16x16 点阵的其他图标,reverse=1 反显*/
  138. void display_graphic_16x16(uint page,uint column,uchar reverse,uchar *dp)
  139. {
  140. uint i,j;
  141. for(j=0;j<2;j++)
  142. {
  143. lcd_address(page+j,column);
  144. for (i=0;i<16;i++)
  145. {
  146. if(reverse==1)
  147. transfer_data_lcd(~*dp); /*写数据到 LCD,每写完一个 8 位的数据后列地址自动加 1*/
  148. else
  149. transfer_data_lcd(*dp); /*写数据到 LCD,每写完一个 8 位的数据后列地址自动加 1*/
  150. dp++;
  151. }
  152. }
  153. }
  154. /*显示 8x16 点阵图像、ASCII, 或 8x16 点阵的自造字符、其他图标,reverse=1 反显*/
  155. void display_graphic_8x16(uint page,uchar column,uchar reverse,uchar *dp)
  156. {
  157. uint i,j;
  158. for(j=0;j<2;j++)
  159. {
  160. lcd_address(page+j,column);
  161. for (i=0;i<8;i++)
  162. {
  163. if(reverse==1)
  164. transfer_data_lcd(~*dp); /*写数据到 LCD,每写完一个 8 位的数据后列地址自动加 1*/
  165. else
  166. transfer_data_lcd(*dp); /*写数据到 LCD,每写完一个 8 位的数据后列地址自动加 1*/
  167. dp++;
  168. }
  169. }
  170. }

  171. /****送指令到晶联讯字库 IC***/
  172. void send_command_to_ROM( uchar datu )
  173. {
  174. uchar i;
  175. for(i=0;i<8;i++ )
  176. {
  177. if(datu&0x80)
  178. Rom_IN = 1;
  179. else
  180. Rom_IN = 0;
  181. datu = datu<<1;
  182. Rom_SCK=0;
  183. Rom_SCK=1;
  184. }
  185. }
  186. /****从晶联讯字库 IC 中取汉字或字符数据(1 个字节)***/
  187. static uchar get_data_from_ROM( )
  188. {
  189. uchar i;
  190. uchar ret_data=0;
  191. Rom_SCK=1;
  192. for(i=0;i<8;i++)
  193. {
  194. Rom_OUT=1;
  195. Rom_SCK=0;
  196. ret_data=ret_data<<1;
  197. if( Rom_OUT )
  198. ret_data=ret_data+1;
  199. else
  200. ret_data=ret_data+0;
  201. Rom_SCK=1;

  202. }
  203. return(ret_data);
  204. }
  205. /*从相关地址(addrHigh:地址高字节,addrMid:地址中字节,addrLow:地址低字节)中连续读出 DataLen 个字节的数据到 pBuff 的地址*/
  206. /*连续读取*/
  207. void get_n_bytes_data_from_ROM(uchar addrHigh,uchar addrMid,uchar addrLow,uchar *pBuff,uchar DataLen )
  208. {
  209. uchar i;
  210. Rom_CS = 0;
  211. lcd_cs1=1;
  212. Rom_SCK=0;
  213. send_command_to_ROM(0x03);
  214. send_command_to_ROM(addrHigh);
  215. send_command_to_ROM(addrMid);
  216. send_command_to_ROM(addrLow);
  217. for(i = 0; i < DataLen; i++ )
  218. *(pBuff+i) =get_data_from_ROM();
  219. Rom_CS = 1;
  220. }
  221. /******************************************************************/
  222. ulong fontaddr=0;
  223. void display_GB2312_string(uchar y,uchar x,uchar reverse,uchar *text)
  224. {
  225. uchar i= 0;
  226. uchar addrHigh,addrMid,addrLow ;
  227. uchar fontbuf[32];
  228. while((text[i]>0x00))
  229. {
  230. if(((text[i]>=0xb0) &&(text[i]<=0xf7))&&(text[i+1]>=0xa1))
  231. {
  232. /*国标简体(GB2312)汉字在晶联讯字库 IC 中的地址由以下公式来计算:*/
  233. /*Address = ((MSB - 0xB0) * 94 + (LSB - 0xA1)+ 846)*32+ BaseAdd;BaseAdd=0*/
  234. /*由于担心 8 位单片机有乘法溢出问题,所以分三部取地址*/
  235. fontaddr = (text[i]- 0xb0)*94;
  236. fontaddr += (text[i+1]-0xa1)+846;
  237. fontaddr = (ulong)(fontaddr*32);

  238. addrHigh = (fontaddr&0xff0000)>>16; /*地址的高 8 位,共 24 位*/
  239. addrMid = (fontaddr&0xff00)>>8; /*地址的中 8 位,共 24 位*/
  240. addrLow = fontaddr&0xff; /*地址的低 8 位,共 24 位*/
  241. get_n_bytes_data_from_ROM(addrHigh,addrMid,addrLow,fontbuf,32 );/*取 32 个字节的数据,存到"fontbuf[32]"*/
  242. display_graphic_16x16(y,x,reverse,fontbuf);/*显示汉字到 LCD 上,y 为页地址,x 为列地址,fontbuf[]为数据*/
  243. i+=2;
  244. x+=16;

  245. }
  246. else if(((text[i]>=0xa1) &&(text[i]<=0xa3))&&(text[i+1]>=0xa1))
  247. {
  248. /*国标简体(GB2312)15x16 点的字符在晶联讯字库 IC 中的地址由以下公式来计算:*/
  249. /*Address = ((MSB - 0xa1) * 94 + (LSB - 0xA1))*32+ BaseAdd;BaseAdd=0*/
  250. /*由于担心 8 位单片机有乘法溢出问题,所以分三部取地址*/
  251. fontaddr = (text[i]- 0xa1)*94;
  252. fontaddr += (text[i+1]-0xa1);
  253. fontaddr = (ulong)(fontaddr*32);

  254. addrHigh = (fontaddr&0xff0000)>>16; /*地址的高 8 位,共 24 位*/
  255. addrMid = (fontaddr&0xff00)>>8; /*地址的中 8 位,共 24 位*/
  256. addrLow = fontaddr&0xff; /*地址的低 8 位,共 24 位*/
  257. get_n_bytes_data_from_ROM(addrHigh,addrMid,addrLow,fontbuf,32 );/*取 32 个字节的数据,存到"fontbuf[32]"*/
  258. display_graphic_16x16(y,x,reverse,fontbuf);/*显示汉字到 LCD 上,y 为页地址,x 为列地址,fontbuf[]为数据*/
  259. i+=2;
  260. x+=16;
  261. }
  262. else if((text[i]>=0x20) &&(text[i]<=0x7e))
  263. {
  264. unsigned char fontbuf[16];
  265. fontaddr = (text[i]- 0x20);
  266. fontaddr = (unsigned long)(fontaddr*16);
  267. fontaddr = (unsigned long)(fontaddr+0x3cf80);
  268. addrHigh = (fontaddr&0xff0000)>>16;
  269. addrMid = (fontaddr&0xff00)>>8;
  270. addrLow = fontaddr&0xff;
  271. get_n_bytes_data_from_ROM(addrHigh,addrMid,addrLow,fontbuf,16 );/*取 16 个字节的数据,存到"fontbuf[32]"*/

  272. display_graphic_8x16(y,x,reverse,fontbuf);/*显示 8x16 的 ASCII 字到 LCD 上,y 为页地址,x 为列地址,fontbuf[]为数据*/
  273. i+=1;
  274. x+=8;
  275. }
  276. else
  277. i++;
  278. }

  279. }

  280. //===============main program===================
  281. void main(void)
  282. {
  283. initial_lcd();
  284. while(1)
  285. {
  286. Rom_CS=1;
  287. lcd_cs1=0;
  288. clear_screen();  
  289. display_GB2312_string(1,1,0,"0123456789"); /*在第 1 页,第 1 列,显示一串 16x16 点阵汉字或 8x16 的 ASCII 字*/
  290. display_GB2312_string(4,1,1,"A B C D E F G");
  291. display_GB2312_string(7,1,0,"DIY兴趣爱好者"); /*显示一串 16x16 点阵汉字或 8x16 的 ASCII 字.以下雷同*/
  292. waitkey();         
  293. }
  294. }
复制代码


回复

使用道具 举报

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

本版积分规则