原创 JLX12864G_086 LCD在STM8S105 和STM32的移植

2015-12-16 22:33 3695 15 18 分类: MCU/ 嵌入式

写在最前: 装载请注明出处,谢谢。
写在之前: 写博客的目的是为了记录自己的一些工作生活,其中可能有些由于本人水平有限而说的不对或者不准确,也请各位不吝赐教。之前在STM32F1上的移植没有意识到留下照片,
现在就用当前的STM8S作为演示(好吧,其实是因为我懒得重新接线哈)

上一篇:https://mbb.eet-china.com/blog/1850657-370272.html 
我分享的附件清单如下,待有空再详细补足。

1.JLX12864G-086-PC的中文字库编程说明书 里面有C51的例程

2,LCD显示 在STM32上的显示

3,《JLX12864G-086》 里面有JLX12864G-086的指令。JLX12864G-086中有一些数字有着其特定的意义,当他作为命令发送时候,代表一条指令,作为数字时候就是普通的数据。

4,《JLX12864G-1016中文说明书》 JLX12864G-1016中文说明书.pdf是一本参考资料,对JLX12864G-086的学习很有意义,里面也提供了C51的例程

平台: STM32F1 和STM8S105

软件:STLINK IAR for STM8

功能: 实现数字输入 汉字输入 和带参数输入

20151125111505476.jpg

关于JLX12864G-086-PC的若干事
1,JLX12864G-086-PC 是一款比较优良的显示屏,能做很低的功耗,也比较容易上手。
2,JLX12864G-086-PC 容易编写,SPI时序。
3,JLX12864G-086-PC 扩展性高。
4,....

就初始化做一些解析

void JLX12864G_086_GPIOIntI(void)  
{
 
    PC_DDR |= (1<<1)+(1<<2)+(1<<4)+(1<<7); //RST SCK SDA CS
    PC_CR1 |= (1<<1)+(1<<2)+(1<<4)+(1<<7);
    PC_CR2 &=~((1<<1)+(1<<2)+(1<<4)+(1<<7));
  
 //   PC_DDR &=~(1<<4);                            //PC7悬浮输入 SDO
 //   PC_CR1 &=~(1<<4);
 //   PC_CR2 &=~(1<<4);
   
    PE_DDR |= (1<<5);   //RS
    PE_CR1 |= (1<<5);
    PE_CR2 &=~(1<<5);
   
    PB_DDR |= (1<<0)+(1<<1)+(1<<2);  // sck cs# ROM_in
    PB_CR1 |= (1<<0)+(1<<1)+(1<<2);
    PB_CR2 &=~((1<<0)+(1<<1)+(1<<2)); 
   
    PB_DDR &=~(1<<3);  //Rom_out 
    PB_CR1 |= (1<<3);
    PB_CR2 &=~ (1<<3);  //不要中断上拉输入 上拉输入
 
}

初始化的重点:
1,选的引脚不能是特殊引脚,比如VSS VDD 串口等 新手常会犯这种错误
2,上拉输入和中断上拉输入是不同的,如果你配置了中断上拉输入而不做中断函数配置,会提示进入 UNEXPECT HANDLE(未预计错误)
Tip: UNEXPECT HANDLE 的错误很多情况下是因为你初始化了中断然而并没有配置好
3, ROM_OUT引脚对应字符库芯片的输入引脚,ROM_IN引脚对应字符库芯片的输出引脚,所以ROM_OUT要配置成上拉输入
4,延时要准确,我在这里分享给大家两个在示波器上得到验证的演示函数,当然大家最好在示波器上验证一下,此外,该延时只是大概延时,误差多多少少会有的,切不可当作准确演示。
Tip:任何时序的延时都是非常重要的,如果程序运行不对,程序也没有问题的情况下,很可能是延时不够准确。

/*****************************************************
//在16M晶振下,必须在16M的情况下

void delay_us( unsigned int time)
{
    unsigned int x;
    for(x=time;x>0;x--)
    {
        asm("nop"); //一个asm("nop")函数经过示波器测试代表100ns
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop"); //一个asm("nop")函数经过示波器测试代表100ns
    }
}

void delay_ms(unsigned int time)
{
    unsigned int i;
    while(time--) 
    for(i=900;i>0;i--)
    delay_us(1);
}
**********************************************************/

void JLX12864G_086_IntI(void) //初始化
{
        //RST=1;
 //delay_ms(1000);
        //CS=0;
        delay_ms(20);
 RST=0;
 delay_ms(5);
 RST=1;
 Send_OrderOrDate_To_LCD(0xE2, 1);
 delay_ms(5);
 Send_OrderOrDate_To_LCD(0x2c, 1);  /*升压步聚1*/
 delay_ms(5);
 Send_OrderOrDate_To_LCD(0x2e, 1);  /*升压步聚2*/
 delay_ms(5);
 Send_OrderOrDate_To_LCD(0x2f, 1);  /*升压步聚3*/
 delay_ms(5);
 Send_OrderOrDate_To_LCD(0x24, 1);  /*粗调对比度,可设置范围20~27*/
 Send_OrderOrDate_To_LCD(0x81, 1);  /*微调对比度*/
 Send_OrderOrDate_To_LCD(0x1a, 1);  /*微调对比度的值,可设置范围0~63  1f*/ 
 Send_OrderOrDate_To_LCD(0xa2, 1);  /*1/9偏压比(bias)*/
 Send_OrderOrDate_To_LCD(0xc8, 1);  /*行扫描顺序:从上到下*/
 Send_OrderOrDate_To_LCD(0xa0, 1);  /*列扫描顺序:从左到右*/
 Send_OrderOrDate_To_LCD(0x40, 1);  /*起始行:从第一行开始*/
        ClearScreen();                                 //清屏
 Send_OrderOrDate_To_LCD(0xaf, 1);  /*开显示*/
        //delay_ms(20);
        //CS=1;
}


Tip:如上所述,JLX12864G-086-PC 中有些数字代表着一个命令,在这里我不做解析。大家如有兴趣,可自行查阅我分享的第三份和第四份参考资料。

那么你就要问了,那怎么区别命令和数字呢?这里给大家一个我写的函数
/***********************************************************************/
//**  发送命令或数据
void Send_OrderOrDate_To_LCD(unsigned char data,unsigned char OrderorDateFlag) //OrderorDateFlag 1 :命令  0:data
{
    unsigned char i;
    //ROM_CS=1;
    //delay_ms(10);
    CS=0;
    if(OrderorDateFlag) RS=0;  //区别在这里
    else RS=1;                 //区别在这里
//SPI 时序
    for(i=0;i<8;i++)
    {
      SCK = 0;
      //if(!OrderorDateFlag) delay_us(2); //少量延时
      delay_us(2);  //少量延时
      if(data & 0x80)  SDA=1;  //输出 1
      else SDA = 0 ;
      SCK = 1; 
      delay_us(2);  //少量延时
      data = data << 1;
    }
}
/***********************************************************************/

/***********************************************************************/
//  指定行和列写入
void LCDAddr(unsigned char page,unsigned char column)  //
{
      CS=0;
      column--;                
      page--;
      Send_OrderOrDate_To_LCD(0xb0+page,1);   
      Send_OrderOrDate_To_LCD(((column>>4)&0x0f)+0x10,1);
      Send_OrderOrDate_To_LCD(column&0x0f,1);       
}

Tip; 要有间隔 如;

      DisplayWithParameter(1,10,"WenDu:",WenDu);
      DisplayWithParameter(3,10,"ShiDu:",ShiDu);

其中 “1”和 “3”是行

如果显示一半,很可能是你的传输数据时候 “i++”的问题
/***********************************************************************/

 

/***********************************************************************/
//带参数显示
void DisplayWithParameter(unsigned short page,unsigned short column,unsigned char *text,unsigned char data)
{
  unsigned short i=0,j,m,k,n;
  static unsigned char  data1[2] ;
  data1[0] = data;
  CS=0;

  while(text>0x00)
  {  
    if((text>=0x20)&&(text<=0x7e))
    {
      j=text-0x20;
      for(n=0;n<2;n++)
      {      
        LCDAddr(page+n,column);
        for(k=0;k<8;k++)
        {
          Send_OrderOrDate_To_LCD(ascii_table_8x16[j][k+8*n],0);
        }
      }
      i++;
      column+=8; 
    }
    else
    {
        i++;
    }
  }
 
  while(data1>0x00)
  {
    i=n=k=0;
    j = data1 /10; //求出data与0的十位
    m = data1 % 10; // 个位
    //j = 1;
    //m = 2;
    //if(data>9) j+=6;
         // j=data / 10; //求出data与0的绝对值
    for(n=0;n<2;n++)
      {              
        if(j)
          {
            LCDAddr(page+n,column+2);
            for(k=0;k<8;k++)
            {
              Send_OrderOrDate_To_LCD(ascii_table_8x16[j+0x10][k+8*n],0);
              //column += 8;
            }
          }
       LCDAddr(page+n,column+10);
       for(k=0;k<8;k++)
       {
          Send_OrderOrDate_To_LCD(ascii_table_8x16[m+0x10][k+8*n],0);
       }
        }
        i++;
        column+=8;
  }
  CS=1; 
}

/***********************************************************************/

20151125111608610.jpg

/***********************************************************************/
//输出中文

ulong fontaddr=0;
void display_GB2312_string(uchar page,uchar column,uchar *text)
{
    uchar i= 0;
    while((text>0x00))
    {
    if(((text>=0xb0) &&(text<=0xf7))&&(text[i+1]>=0xa1))
    {
    //国标简体(GB2312)汉字在晶联讯字库 IC 中的地址由以下公式来计算:
    //Address = ((MSB - 0xB0) * 94 + (LSB - 0xA1)+ 846)*32+ BaseAdd;BaseAdd=0
    //由于担心 8 位单片机有乘法溢出问题,所以分三部取地址
        fontaddr = (text- 0xb0)*94;
        fontaddr += (text[i+1]-0xa1)+846;
        fontaddr = (ulong)(fontaddr*32);
        get_and_write_16x16(fontaddr,page,column); //从指定地址读出数据写到液晶屏指定(page,column)座标中
        //get_and_write_5x8(fontaddr,page,column); //从指定地址读出数据写到液晶屏指定(page,column)座标中
        i+=2;
        column+=16;
    }
    else if(((text>=0xa1) &&(text<=0xa3))&&(text[i+1]>=0xa1))
    {
    //国标简体(GB2312)15x16 点的字符在晶联讯字库 IC 中的地址由以下公式来计算:
    //Address = ((MSB - 0xa1) * 94 + (LSB - 0xA1))*32+ BaseAdd;BaseAdd=0
    //由于担心 8 位单片机有乘法溢出问题,所以分三部取地址
        fontaddr = (text- 0xa1)*94;
        fontaddr += (text[i+1]-0xa1);
        fontaddr = (ulong)(fontaddr*32);
        get_and_write_16x16(fontaddr,page,column); //从指定地址读出数据写到液晶屏指定(page,column)座标中
        //get_and_write_5x8(fontaddr,page,column); //从指定地址读出数据写到液晶屏指定(page,column)座标中
        i+=2;
        column+=16;
    }
    else if((text>=0x20) &&(text<=0x7e))
    {
        fontaddr = (text- 0x20);
        fontaddr = (unsigned long)(fontaddr*16);
        fontaddr = (unsigned long)(fontaddr+0x3cf80);
        get_and_write_8x16(fontaddr,page,column); //从指定地址读出数据写到液晶屏指定(page,column)座标中
        //get_and_write_8x16(fontaddr,page,column); //从指定地址读出数据写到液晶屏指定(page,column)座标中
        i+=1;
        column+=8;
    }
    else
        i++;
    }
}
/***********************************************************************/


 好了,函数的解析就到这里,谢谢大家。以上函数都经过测试,没有问题。

作者: Bruce-Woo, 来源:面包板社区

链接: https://mbb.eet-china.com/blog/uid-me-1850657.html

版权声明:本文为博主原创,未经本人允许,禁止转载!

文章评论3条评论)

登录后参与讨论

Bruce-Woo 2015-12-2 16:11

学习的话,条件允许买一个开发板或者叫你周围的大神给你弄个简单的最小系统加一些简单的外设 如LED蜂鸣器还有一些简单的传感器 先把例程烧进去自己看看效果,比如LED亮一秒,你就试一下让它亮5s,从中去修改与体会。。有问题可以多交流。

用户377235 2015-11-27 20:40

我只会强电和机械设计,不知怎么学习。

用户377235 2015-11-25 12:58

不错
相关推荐阅读
Bruce-Woo 2023-03-07 15:14
嵌入式面试之系统
最近一段时间在开始找工作,自己以前也面试过其他人,想从实际工作的角度,来提出一些有意义的问题并做一些浅薄的解答,期望帮助到找工作或者刚开始当面试官的朋友。我把面试要准备的地方列成一下几个注意点,大家...
Bruce-Woo 2023-02-25 21:59
芯片选型的思路
近来在面试,不知为何很多人问起我刚毕业的时候的项目中的一个芯片选型的事情,回过头来整理下,希望可以帮助到后面的朋友1. 开发难度 开发难度,要考虑本身的程序员的开发能力,擅长的领域和工具等。综合下你...
Bruce-Woo 2021-03-17 14:19
记一次调用动态库报错的处理过程( undefined symbol)
最近工作在调用其他同事的一个动态库的时候发现有 未识别的错误 特此记录一下         首先我们用ldd查一下动态库连接是否有问题   ...
Bruce-Woo 2021-03-11 15:03
ubuntu16.04下安装svn
SVN和GIT相信是大家使用最多的代码协同工具,不过可能在win下用的比较多,那今天在ubuntu上运行一遍,操作都差不多。某种程度上讲,我也更喜欢指令操作。1. 远程登录虚拟机,也可以页面操作,看个...
Bruce-Woo 2021-02-09 01:08
2020,我想和你谈谈
这篇文字无关技术,也没有代码。 这是最好的时代,也是最坏的时代!写在回家前夜。 不到10个小时后就要开始坐车回家,手头的工作也没有做完。正经的事儿没完成,乱七八糟的事情倒是想了不少,说话是一种表达方...
Bruce-Woo 2021-01-19 12:34
cmake的安装过程
今天在编译opencv的时候突然发现cmake失败,显示版本不同遂决定修复之方法如下下载更高版本cmake,可在cmake官网下载 解压 tar -zxvf cmake-3.19....
我要评论
3
15
关闭 站长推荐上一条 /2 下一条