找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1673|回复: 0
收起左侧

单片机LCD12864G带字库的独立函数,可调用

[复制链接]
ID:282626 发表于 2020-8-18 17:41 | 显示全部楼层 |阅读模式
本人在使用LCD12864时,用到了JLX12864G-086-pc 也就是带字库的LCD12864屏,采用SPI串口方式,根据厂家提供的标准例程,进行了修改,做成了一个可被调用的独立模块,并可对显示的文字进行反白显示,并提供了相应的头文件。
单片机源程序如下:
  1. //液晶屏型号:JLX12864G-086-PC-3S
  2. //接口:串行
  3. //中文字库:带中文字库IC:JLX-GB2312,竖置横排
  4. #include "JLX1286486PC.h"

  5. //延时
  6. void lcddelay(int n_ms)               
  7. {
  8.         int j,k;
  9.         for(j=0;j<n_ms;j++)
  10.         for(k=0;k<110;k++);
  11. }
  12. //短延时
  13. void lcddelay_us(int n_us)               
  14. {
  15.         int j,k;
  16.         for(j=0;j<n_us;j++)
  17.         for(k=0;k<1;k++);
  18. }

  19. //写指令到LCD模块
  20. void transfer_command_lcd(int data1)   
  21. {
  22.         char i;
  23.         lcd_cs1=0;
  24.         lcd_rs=0;
  25.         for(i=0;i<8;i++)
  26.    {
  27.                 lcd_sclk=0;
  28.                 lcddelay_us(10);         //加少量延时
  29.                 if(data1&0x80) lcd_sid=1;
  30.                 else lcd_sid=0;
  31.                 lcd_sclk=1;
  32.                 lcddelay_us(10);         //加少量延时
  33.                  data1=data1<<=1;
  34.    }
  35.         lcd_cs1=1;
  36. }

  37. //写数据到LCD模块
  38. void transfer_data_lcd(int data1)
  39. {
  40.         char i;
  41.         lcd_cs1=0;
  42.         lcd_rs=1;
  43.         for(i=0;i<8;i++)
  44.         {
  45.                 lcd_sclk=0;
  46.                 if(data1&0x80) lcd_sid=1;
  47.                 else lcd_sid=0;
  48.                 lcd_sclk=1;
  49.                 data1=data1<<=1;
  50.         }
  51.         lcd_cs1=1;
  52. }




  53. //LCD模块初始化
  54. void initial_lcd()
  55. {
  56.         lcd_reset=0;                        //低电平复位
  57.         lcddelay(100);
  58.         lcd_reset=1;                            //复位完毕
  59.         lcddelay(100);        
  60.         transfer_command_lcd(0xe2);         //软复位
  61.         lcddelay(50);
  62.         transfer_command_lcd(0x2c);  //升压步聚1
  63.         lcddelay(50);       
  64.         transfer_command_lcd(0x2e);  //升压步聚2
  65.         lcddelay(50);
  66.         transfer_command_lcd(0x2f);  //升压步聚3
  67.         lcddelay(50);
  68.         transfer_command_lcd(0x23);  //粗调对比度,可设置范围0x20~0x27
  69.         transfer_command_lcd(0x81);  //微调对比度
  70.         transfer_command_lcd(0x28);  //微调对比度的值,可设置范围0x00~0x3f
  71.         transfer_command_lcd(0xa2);  //1/9偏压比(bias)
  72.         transfer_command_lcd(0xc8);  //行扫描顺序:从上到下
  73.         transfer_command_lcd(0xa0);  //列扫描顺序:从左到右
  74.         transfer_command_lcd(0x40);  //起始行:第一行开始
  75.         transfer_command_lcd(0xaf);  //开显示
  76.         lcddelay(50);
  77. }

  78. void lcd_address(uint page,uint column)
  79. {
  80.         column=column-0x01;
  81.         transfer_command_lcd(0xb0+page-1);   //设置页地址,每8行为一页,全屏共64行,被分成8页
  82.         transfer_command_lcd(0x10+(column>>4&0x0f));        //设置列地址的高4位
  83.         transfer_command_lcd(column&0x0f);        //设置列地址的低4位       
  84. }

  85. //全屏清屏
  86. void clear_screen()
  87. {
  88.         unsigned char i,j;
  89.                
  90.         for(i=0;i<9;i++)
  91.         {
  92.                 transfer_command_lcd(0xb0+i);
  93.                 transfer_command_lcd(0x10);
  94.                 transfer_command_lcd(0x00);
  95.                 for(j=0;j<132;j++)
  96.                 {
  97.                           transfer_data_lcd(0x00);
  98.                 }
  99.         }
  100. }

  101. //显示128x64点阵图像
  102. void display_128x64(uchar *dp)
  103. {
  104.         uint i,j;
  105.        
  106.         for(j=0;j<8;j++)
  107.         {
  108.                 lcd_address(j+1,1);
  109.                 for (i=0;i<128;i++)
  110.                 {       
  111.                         transfer_data_lcd(*dp);                                        //写数据到LCD,每写完一个8位的数据后列地址自动加1
  112.                         dp++;
  113.                 }
  114.         }
  115. }


  116. //显示16x16点阵图像、汉字、生僻字或16x16点阵的其他图标
  117. void display_graphic_16x16(uchar page,uchar column,uchar *dp)
  118. {
  119.         uint i,j;
  120.         for(j=0;j<2;j++)
  121.         {
  122.                 lcd_address(page+j,column);
  123.                 for (i=0;i<16;i++)
  124.                 {       
  125.                         transfer_data_lcd(*dp);                                        //写数据到LCD,每写完一个8位的数据后列地址自动加1
  126.                         dp++;
  127.                 }
  128.         }
  129. }

  130. //显示8x16点阵图像、ASCII, 或8x16点阵的自造字符、其他图标
  131. void display_graphic_8x16(uchar page,uchar column,uchar *dp)
  132. {
  133.         uint i,j;
  134.         for(j=0;j<2;j++)
  135.         {
  136.                 lcd_address(page+j,column);
  137.                 for (i=0;i<8;i++)
  138.                 {       
  139.                         transfer_data_lcd(*dp);                                        //写数据到LCD,每写完一个8位的数据后列地址自动加1
  140.                         dp++;
  141.                 }
  142.         }
  143. }


  144. //显示5X8点阵图像、ASCII, 或5x8点阵的自造字符、其他图标
  145. void display_graphic_5x8(uchar page,uchar column,uchar *dp)
  146. {
  147.         uint i;
  148.         lcd_address(page,column);
  149.         for (i=0;i<6;i++)
  150.         {       
  151.                 transfer_data_lcd(*dp);
  152.                 dp++;
  153.         }
  154.        
  155. }

  156. //送指令到晶联讯字库IC
  157. void send_command_to_ROM( uchar datu )
  158. {
  159.         uchar i;
  160.         for(i=0;i<8;i++ )
  161.         {
  162.                 Rom_SCK=0;
  163.                 lcddelay_us(10);
  164.                 if(datu&0x80)Rom_IN = 1;
  165.                 else Rom_IN = 0;
  166.                 datu = datu<<1;
  167.                   lcddelay_us(10);          //加一个延时
  168.                 Rom_SCK=1;
  169.                 lcddelay_us(10);
  170.         }
  171. }

  172. //从晶联讯字库IC中取汉字或字符数据(1个字节)
  173. static uchar get_data_from_ROM( )
  174. {
  175.         uchar i;
  176.         uchar ret_data=0;
  177.         for(i=0;i<8;i++)
  178.         {
  179.                 Rom_OUT=1;
  180.                 Rom_SCK=0;
  181.                 lcddelay_us(10);
  182.                 ret_data=ret_data<<1;
  183.                 if( Rom_OUT )
  184.                         ret_data=ret_data+1;
  185.                 else
  186.                         ret_data=ret_data+0;
  187.                 Rom_SCK=1;
  188.                 lcddelay_us(10);
  189.         }
  190.         return(ret_data);
  191. }


  192. //从指定地址读出数据写到液晶屏指定(page,column)座标中
  193. void get_and_write_16x16(ulong fontaddr,uchar page,uchar column,uchar fb)
  194. {
  195.         uchar i,j,disp_data;
  196.         Rom_CS = 0;
  197.         send_command_to_ROM(0x03);
  198.         send_command_to_ROM((fontaddr&0xff0000)>>16);         //地址的高8位,共24位
  199.         send_command_to_ROM((fontaddr&0xff00)>>8);                 //地址的中8位,共24位
  200.         send_command_to_ROM(fontaddr&0xff);                                 //地址的低8位,共24位
  201.         for(j=0;j<2;j++)
  202.         {
  203.                 lcd_address(page+j,column);
  204.                 for(i=0; i<16; i++ )
  205.             {
  206.                         disp_data=get_data_from_ROM();
  207.                   lcddelay_us(4);                   //加了一个延时
  208.        if(fb==1)                 
  209.                                 transfer_data_lcd(~disp_data);        //写数据到LCD,每写完1字节的数据后列地址自动加1 反白,对数据取反
  210.                     else
  211.                                 transfer_data_lcd(disp_data);        //  写数据到LCD,每写完1字节的数据后列地址自动加1
  212.                 }
  213.         }
  214.         Rom_CS=1;
  215. }

  216. //从指定地址读出数据写到液晶屏指定(page,column)座标中
  217. void get_and_write_8x16(ulong fontaddr,uchar page,uchar column,uchar fb)
  218. {
  219.         uchar i,j,disp_data;
  220.         Rom_CS = 0;
  221.         send_command_to_ROM(0x03);
  222.         send_command_to_ROM((fontaddr&0xff0000)>>16);         //地址的高8位,共24位
  223.         send_command_to_ROM((fontaddr&0xff00)>>8);                 //地址的中8位,共24位
  224.         send_command_to_ROM(fontaddr&0xff);                                 //地址的低8位,共24位
  225.         for(j=0;j<2;j++)
  226.         {
  227.                 lcd_address(page+j,column);
  228.                 for(i=0; i<8; i++ )
  229.             {
  230.                         disp_data=get_data_from_ROM();
  231.                         lcddelay_us(4);                                                                 //加了一个延时
  232.                         if(fb==1)
  233.                                 transfer_data_lcd(~disp_data);        //写数据到LCD,每写完1字节的数据后列地址自动加1
  234.                     else
  235.                                 transfer_data_lcd(disp_data);        //写数据到LCD,每写完1字节的数据后列地址自动加1
  236.                         }
  237.         }
  238.         Rom_CS=1;
  239. }

  240. //从指定地址读出数据写到液晶屏指定(page,column)座标中
  241. void get_and_write_5x8(ulong fontaddr,uchar page,uchar column,uchar fb)
  242. {
  243.         uchar i,disp_data;
  244.         Rom_CS = 0;
  245.         send_command_to_ROM(0x03);
  246.         send_command_to_ROM((fontaddr&0xff0000)>>16);         //地址的高8位,共24位
  247.         send_command_to_ROM((fontaddr&0xff00)>>8);                 //地址的中8位,共24位
  248.         send_command_to_ROM(fontaddr&0xff);                                 //地址的低8位,共24位
  249.         lcd_address(page,column);
  250.         for(i=0; i<5; i++ )
  251.         {
  252.                 disp_data=get_data_from_ROM();
  253.                 lcddelay_us(4);                                                                 //加了一个延时
  254.                 if(fb==1)
  255.                         transfer_data_lcd(~disp_data);        //写数据到LCD,每写完1字节的数据后列地址自动加1
  256.       else
  257.                 transfer_data_lcd(disp_data);        //写数据到LCD,每写完1字节的数据后列地址自动加1
  258.         }
  259.                         if(fb==1)
  260.                         {disp_data=0xff;
  261.                                 transfer_data_lcd(disp_data);        //写数据到LCD,每写完1字节的数据后列地址自动加1
  262.                         }
  263.                         Rom_CS=1;
  264. }


  265. //****************************************************************

  266. ulong  fontaddr=0;
  267. void display_GB2312_string(uchar page,uchar column,uchar *text,uchar fb)
  268. {
  269.         uchar i= 0;                       
  270.         while((text[i]>0x00))
  271.         {
  272.                 if(((text[i]>=0xb0) &&(text[i]<=0xf7))&&(text[i+1]>=0xa1))
  273.                 {                                               
  274.                         //国标简体(GB2312)汉字在晶联讯字库IC中的地址由以下公式来计算:
  275.                         //Address = ((MSB - 0xB0) * 94 + (LSB - 0xA1)+ 846)*32+ BaseAdd;BaseAdd=0
  276.                         //由于担心8位单片机有乘法溢出问题,所以分三部取地址
  277.                         fontaddr = (text[i]- 0xb0)*94;
  278.                         fontaddr += (text[i+1]-0xa1)+846;
  279.                         fontaddr = (ulong)(fontaddr*32);

  280.                         get_and_write_16x16(fontaddr,page,column,fb);         //从指定地址读出数据写到液晶屏指定(page,column)座标中
  281.                         i+=2;
  282.                         column+=16;
  283.                 }
  284.                 else if(((text[i]>=0xa1) &&(text[i]<=0xa3))&&(text[i+1]>=0xa1))
  285.                 {                                               
  286.                         //国标简体(GB2312)15x16点的字符在晶联讯字库IC中的地址由以下公式来计算:
  287.                         //Address = ((MSB - 0xa1) * 94 + (LSB - 0xA1))*32+ BaseAdd;BaseAdd=0
  288.                         //由于担心8位单片机有乘法溢出问题,所以分三部取地址
  289.                         fontaddr = (text[i]- 0xa1)*94;
  290.                         fontaddr += (text[i+1]-0xa1);
  291.                         fontaddr = (ulong)(fontaddr*32);
  292.        
  293.                         get_and_write_16x16(fontaddr,page,column,fb);         //从指定地址读出数据写到液晶屏指定(page,column)座标中
  294.                         i+=2;
  295.                         column+=16;
  296. ……………………

  297. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码


lcd12864.rar (3.63 KB, 下载次数: 37)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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