找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2195|回复: 2
打印 上一主题 下一主题
收起左侧

基于STM单片机I2C的JLX19296 LCD驱动程序

[复制链接]
跳转到指定楼层
楼主
晶联讯官方不提供JLX19296,官方提供的C51驱动也有很多问题. stm32驱动,为了减少连线数量,使用i2c接口,使用通用字库文件.



单片机源程序如下:
  1. #include "st75256.h"
  2. #include "LCMfont.h"           
  3. #include "delay.h"
  4. #include "myiic.h"
  5. //LCM的显存
  6. //-----------------虚拟显存定义----------------
  7. u8 LCM_GRAM[192][12];
  8. /**********************************************
  9. // IIC Write Command
  10. **********************************************/
  11. void Write_IIC_Command(u8 IIC_Command)
  12. {
  13.         IIC_Start();
  14.         IIC_Send_Byte (0x78);            //Slave address,SA0=0
  15.         IIC_NAck ();
  16.         IIC_Send_Byte (0x80);                        //write command
  17.         IIC_NAck ();
  18.         IIC_Send_Byte(IIC_Command);
  19.         IIC_NAck ();
  20.         IIC_Stop();
  21. }
  22. /**********************************************
  23. // IIC Write Data
  24. **********************************************/
  25. void Write_IIC_Data(u8 IIC_Data)
  26. {
  27.         IIC_Start();
  28.         IIC_Send_Byte (0x78);                        //D/C#=0; R/W#=0
  29.         IIC_NAck ();
  30.         IIC_Send_Byte(0xC0);                        //write data
  31.         IIC_NAck ();
  32.         IIC_Send_Byte (IIC_Data);
  33.         IIC_NAck ();
  34.         IIC_Stop ();
  35. }
  36. void LCM_WR_Byte(u8 dat,u8 cmd)
  37. {
  38.         if(cmd)
  39.                 {

  40.    Write_IIC_Data(dat);
  41.    
  42.                 }
  43.         else {
  44.    Write_IIC_Command(dat);
  45.                
  46.         }
  47. }

  48. void LCM_Set_Pos(u8 x, u8 y)
  49. {         
  50.         LCM_WR_Byte(0x15,LCM_CMD);        //set Column
  51.         LCM_WR_Byte(0X00,LCM_DATA);
  52.         LCM_WR_Byte(x,LCM_DATA);
  53.         
  54.         LCM_WR_Byte(0x75,LCM_CMD);
  55.         LCM_WR_Byte(0,LCM_DATA);
  56.         LCM_WR_Byte(y,LCM_DATA);
  57.         LCM_WR_Byte(0x30,LCM_CMD);
  58.         LCM_WR_Byte(0x5C,LCM_CMD);                //写数据到显存
  59. }
  60. u8 test_ddr(void)
  61. {
  62.         u8 vol;
  63.         Write_IIC_Command(0x30);   //EXT=0
  64.         LCM_Set_Pos(0,0);
  65.         LCM_WR_Byte(0x01,LCM_DATA);
  66.         LCM_Set_Pos(0,0);
  67.         LCM_WR_Byte(0x5d,LCM_CMD);
  68.         vol = IIC_Read_Byte(1);
  69.         return vol;
  70. }
  71.         

  72. //更新显存到LCM        
  73. void LCM_Refresh(void)
  74. {
  75.         u8 i,j;
  76.         LCM_WR_Byte(0x15,LCM_CMD);
  77.         LCM_WR_Byte(0X00,LCM_DATA);
  78.         LCM_WR_Byte(Max_Column-1,LCM_DATA);
  79.         
  80.         LCM_WR_Byte(0x75,LCM_CMD);
  81.         LCM_WR_Byte(0X08,LCM_DATA);                                        //        页地址偏移8
  82.         LCM_WR_Byte((Max_Page-1)+8,LCM_DATA);
  83.         LCM_WR_Byte(0x30,LCM_CMD);
  84.         LCM_WR_Byte(0x5C,LCM_CMD);                //写数据到显存
  85.         
  86.         for(i=0;i<Max_Page;i++)
  87.         {
  88.                 for(j=0;j<Max_Column;j++)
  89.                 {
  90.                         LCM_WR_Byte(LCM_GRAM[j][i],LCM_DATA);
  91.                 }        
  92.   }
  93. }
  94. //清屏函数
  95. void LCM_Clear(void)
  96. {
  97.         u8 i,j;
  98.         for(i=0;i<Max_Page;i++)
  99.         {
  100.            for(j=0;j<Max_Column;j++)
  101.                         {
  102.                          LCM_GRAM[j][i]=0x00;//清除所有数据
  103.                         }
  104.   }
  105.         LCM_Refresh();//更新显示
  106. }
  107. //画点
  108. //x:0~255
  109. //y:0~96
  110. //t:1 填充 0,清空        
  111. void LCM_DrawPoint(u8 x,u8 y,u8 t)
  112. {
  113.         u8 i,m,n;
  114.         i=y/8;
  115.         m=y%8;
  116.         n=1<<m;
  117.         if(t){LCM_GRAM[x][i]|=n;}
  118.         else
  119.         {
  120.                 LCM_GRAM[x][i]=~LCM_GRAM[x][i];
  121.                 LCM_GRAM[x][i]|=n;
  122.                 LCM_GRAM[x][i]=~LCM_GRAM[x][i];
  123.         }
  124. }

  125. //画线
  126. //x1,y1:起点坐标
  127. //x2,y2:结束坐标
  128. void LCM_DrawLine(u8 x1,u8 y1,u8 x2,u8 y2,u8 mode)
  129. {
  130.         u16 t;
  131.         int xerr=0,yerr=0,delta_x,delta_y,distance;
  132.         int incx,incy,uRow,uCol;
  133.         delta_x=x2-x1; //计算坐标增量
  134.         delta_y=y2-y1;
  135.         uRow=x1;//画线起点坐标
  136.         uCol=y1;
  137.         if(delta_x>0)incx=1; //设置单步方向
  138.         else if (delta_x==0)incx=0;//垂直线
  139.         else {incx=-1;delta_x=-delta_x;}
  140.         if(delta_y>0)incy=1;
  141.         else if (delta_y==0)incy=0;//水平线
  142.         else {incy=-1;delta_y=-delta_x;}
  143.         if(delta_x>delta_y)distance=delta_x; //选取基本增量坐标轴
  144.         else distance=delta_y;
  145.         for(t=0;t<distance+1;t++)
  146.         {
  147.                 LCM_DrawPoint(uRow,uCol,mode);//画点
  148.                 xerr+=delta_x;
  149.                 yerr+=delta_y;
  150.                 if(xerr>distance)
  151.                 {
  152.                         xerr-=distance;
  153.                         uRow+=incx;
  154.                 }
  155.                 if(yerr>distance)
  156.                 {
  157.                         yerr-=distance;
  158.                         uCol+=incy;
  159.                 }
  160.         }
  161. }
  162. //x,y:圆心坐标
  163. //r:圆的半径
  164. void LCM_DrawCircle(u8 x,u8 y,u8 r)
  165. {
  166.         int a, b,num;
  167.     a = 0;
  168.     b = r;
  169.     while(2 * b * b >= r * r)      
  170.     {
  171.         LCM_DrawPoint(x + a, y - b,1);
  172.         LCM_DrawPoint(x - a, y - b,1);
  173.         LCM_DrawPoint(x - a, y + b,1);
  174.         LCM_DrawPoint(x + a, y + b,1);

  175.         LCM_DrawPoint(x + b, y + a,1);
  176.         LCM_DrawPoint(x + b, y - a,1);
  177.         LCM_DrawPoint(x - b, y - a,1);
  178.         LCM_DrawPoint(x - b, y + a,1);
  179.         
  180.         a++;
  181.         num = (a * a + b * b) - r*r;//计算画的点离圆心的距离
  182.         if(num > 0)
  183.         {
  184.             b--;
  185.             a--;
  186.         }
  187.     }
  188. }



  189. //在指定位置显示一个字符,包括部分字符
  190. //x:0~255
  191. //y:0~96
  192. //size1:选择字体 6x8/6x12/8x16/12x24
  193. //mode:0,反色显示;1,正常显示
  194. void LCM_ShowChar(u8 x,u8 y,u8 chr,u8 size1,u8 mode)
  195. {
  196.         u8 i,m,temp,size2,chr1;
  197.         u8 x0=x,y0=y;
  198.         if(size1==8)size2=6;
  199.         else size2=(size1/8+((size1%8)?1:0))*(size1/2);  //得到字体一个字符对应点阵集所占的字节数
  200.         chr1=chr-' ';  //计算偏移后的值
  201.         for(i=0;i<size2;i++)
  202.         {
  203.                 if(size1==8)
  204.                           {temp=asc2_0806[chr1][i];} //调用0806字体
  205.                 else if(size1==12)
  206.         {temp=asc2_1206[chr1][i];} //调用1206字体
  207.                 else if(size1==16)
  208.         {temp=asc2_1608[chr1][i];} //调用1608字体
  209.                 else if(size1==24)
  210.         {temp=asc2_2412[chr1][i];} //调用2412字体
  211.                 else return;
  212.                 for(m=0;m<8;m++)
  213.                 {
  214.                         if(temp&0x01)LCM_DrawPoint(x,y,mode);
  215.                         else LCM_DrawPoint(x,y,!mode);
  216.                         temp>>=1;
  217.                         y++;
  218.                 }
  219.                 x++;
  220.                 if((size1!=8)&&((x-x0)==size1/2))
  221.                 {x=x0;y0=y0+8;}
  222.                 y=y0;
  223.   }
  224. }


  225. //显示字符串
  226. //x,y:起点坐标  
  227. //size1:字体大小
  228. //*chr:字符串起始地址
  229. //mode:0,反色显示;1,正常显示
  230. void LCM_ShowString(u8 x,u8 y,u8 *chr,u8 size1,u8 mode)
  231. {
  232.         while((*chr>=' ')&&(*chr<='~'))//判断是不是非法字符!
  233.         {
  234.                 LCM_ShowChar(x,y,*chr,size1,mode);
  235.                 if(size1==8)x+=6;
  236.                 else x+=size1/2;
  237.                 chr++;
  238.   }
  239. }

  240. //m^n
  241. u32 LCM_Pow(u8 m,u8 n)
  242. {
  243.         u32 result=1;
  244.         while(n--)
  245.         {
  246.           result*=m;
  247.         }
  248.         return result;
  249. }

  250. //显示数字
  251. //x,y :起点坐标
  252. //num :要显示的数字
  253. //len :数字的位数
  254. //size:字体大小
  255. //mode:0,反色显示;1,正常显示
  256. void LCM_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size1,u8 mode)
  257. {
  258.         u8 t,temp,m=0;
  259.         if(size1==8)m=2;
  260.         for(t=0;t<len;t++)
  261.         {
  262.                 temp=(num/LCM_Pow(10,len-t-1))%10;
  263.                         if(temp==0)
  264.                         {
  265.                                 LCM_ShowChar(x+(size1/2+m)*t,y,'0',size1,mode);
  266.       }
  267.                         else
  268.                         {
  269.                           LCM_ShowChar(x+(size1/2+m)*t,y,temp+'0',size1,mode);
  270.                         }
  271.   }
  272. }

  273. //显示汉字
  274. //x,y:起点坐标
  275. //num:汉字对应的序号
  276. //mode:0,反色显示;1,正常显示
  277. void LCM_ShowChinese(u8 x,u8 y,u8 num,u8 size1,u8 mode)
  278. {
  279.         u8 m,temp;
  280.         u8 x0=x,y0=y;
  281.         u16 i,size3=(size1/8+((size1%8)?1:0))*size1;  //得到字体一个字符对应点阵集所占的字节数
  282.         for(i=0;i<size3;i++)
  283.         {
  284.                 if(size1==16)
  285.                                 {temp=Hzk1[num][i];}//调用16*16字体
  286.                 else if(size1==24)
  287.                                 {temp=Hzk2[num][i];}//调用24*24字体
  288.                 else if(size1==32)      
  289.                                 {temp=Hzk3[num][i];}//调用32*32字体
  290.                 else if(size1==64)
  291.                                 {temp=Hzk4[num][i];}//调用64*64字体
  292.                 else return;
  293.                 for(m=0;m<8;m++)
  294.                 {
  295.                         if(temp&0x01)LCM_DrawPoint(x,y,mode);
  296.                         else LCM_DrawPoint(x,y,!mode);
  297.                         temp>>=1;
  298.                         y++;
  299.                 }
  300.                 x++;
  301.                 if((x-x0)==size1)
  302.                 {x=x0;y0=y0+8;}
  303.                 y=y0;
  304.         }
  305. }

  306. //num 显示汉字的个数
  307. //space 每一遍显示的间隔
  308. //mode:0,反色显示;1,正常显示
  309. void LCM_ScrollDisplay(u8 num,u8 space,u8 mode)
  310. {
  311.         u8 i,n,t=0,m=0,r;
  312.         while(1)
  313.         {
  314.                 if(m==0)
  315.                 {
  316.             LCM_ShowChinese(128,24,t,16,mode); //写入一个汉字保存在LCM_GRAM[][]数组中
  317.                         t++;
  318.                 }
  319.                 if(t==num)
  320.                         {
  321.                                 for(r=0;r<Max_Page*space;r++)      //显示间隔
  322. ……………………

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

以上3个文件下载
JLX19296G.rar (10.3 KB, 下载次数: 43)

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1012918 发表于 2022-3-29 15:55 | 只看该作者
初始化后LCD背景可能有发黑现象,是因为LCD 偏置电压过高引起的,需要根据ST75256 手册做出微调,
回复

使用道具 举报

板凳
ID:1131936 发表于 2024-9-13 16:18 | 只看该作者
请问单片机只要接i2c引脚到屏上就可以了吗?不用接字库IC的引脚是因为使用通用字库吗?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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