注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

男儿当自强的博客

每天进步一点

 
 
 

日志

 
 
 
 

兼容HX8347D和HX8347-H驱动IC类型的显示屏  

2012-09-29 17:12:02|  分类: windows CE 驱动 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
 

备注:GRAM:Graphics RAM,即图像寄存器,用于存储要显示的图像信息。

 

由于项目的需要,在支持采用HX8347D驱动IC的显示屏基础上,需要增加采用HX8347-H驱动IC的显示屏,这样就需要软件上的兼容,也就说要通过软件来自动判断产品当前采用的显示屏,大众的做法就是根据显示屏的ID来做区分,下面就总结兼容过程中遇到的问题和需要重点注意的地方。

 

1.       显示屏的ID

HX8347D驱动IC中关于显示屏ID的寄存器是R00h,如下图:

兼容HX8347D和HX8347-H驱动IC类型的显示屏 - 男儿当自强 - 男儿当自强的博客

 

图1

由图1可知,采用HX8347D驱动IC中的显示屏ID是0x47,其值保存在寄存器R00h中,那么采用HX8347-H驱动IC的显示屏ID是多少呢?见下图:

兼容HX8347D和HX8347-H驱动IC类型的显示屏 - 男儿当自强 - 男儿当自强的博客

 

图2

由图2可知其ID值是0x79,也是保存在R00h寄存器中。这样我们就只需要在eboot中初始化显示控制器之前通过显示屏ID来识别不同的显示屏。

 

2.       显示屏接口

采用上面两种驱动IC的显示屏是引脚兼容的,下面简要描述主要的引脚:

2.1    系统接口选择

兼容HX8347D和HX8347-H驱动IC类型的显示屏 - 男儿当自强 - 男儿当自强的博客

 

图3

结合下图

兼容HX8347D和HX8347-H驱动IC类型的显示屏 - 男儿当自强 - 男儿当自强的博客

 

图4

结合图3和图4可知,我们的设计中显示屏是作为3线串行接口的方式和显示控制器交互的,这里注意了,IM0对应ID,这里ID是什么?做什么用呢?见后面的描述。

 

2.2    时序控制接口

兼容HX8347D和HX8347-H驱动IC类型的显示屏 - 男儿当自强 - 男儿当自强的博客

 

图5

这里重点注意RESET引脚,这个引脚是低电平可以复位显示屏的驱动IC,在我们设备上电的时候需要复位,控制代码如下:

s2450IOP->GPDCON&=~(0x3<<0);

      s2450IOP->GPDCON|=(0x01<<0);

         //拉低CS

         LCD_CS_LOW;//要有效控制和访问显示屏的IC,先输出低电平

         DelayX1ms(15);

         //RESET

             s2450IOP->GPDDAT&=~(0x1<<0);

         DelayX1ms(30);    //实际4.5ms

         s2450IOP->GPDDAT|=(0x1<<0);

         DelayX1ms(40);

 

         LCD_CS_HIG;//不需要访问显示屏IC后,就要输出高电平,也起到误操作引起隐患 的作用。

2.3    通讯接口

兼容HX8347D和HX8347-H驱动IC类型的显示屏 - 男儿当自强 - 男儿当自强的博客

 

图6

图6中FMARK没有使用,根据图4的配置决定了WR/SCL引脚是作为SCL来使用的,我们的实际中用普通的GPIO口GPK0和GPK1分别来模拟I2C总线和SDA与SCL通讯。

2.4     

3.       读写时序

HX8347D驱动IC和HX8347-H驱动IC的读写时序很接近,这里就以HX8347-H驱动IC的时序来说明。

HX8347-H01通过外部引脚IM3、IM2、IM1来支持两种3线和4线串行总线接口模式,这里介绍我们用到的3线串行总线接口模式,3线是指片选引脚NCS、串行数据线SDA和串行时钟线SCL。

3.1    3线串行接口数据通讯说明

当片选信号NCS为低,首先要发送开始字节,开始字节是由6位总线设备标识码、寄存器选择(RS)位和读/写(R/W)操作位组成,其中6位总线设备标识码的高5位必须被设置为01110,并且标识码的最小位必须被设置为何IM0引脚的电平状态一样,这位就是ID位,见图7可更好理解。

         开始字节的第7位是RS位,此位决定是对内部索引寄存器,或是寄存器,还是GRAM的访问。当写数据到索引寄存器或是读取索引寄存器的状态时,必须设置RS=0;当写/读一个命令或是GRAM数据时,必须设置RS=1。开始字节的第8位是RW位,此位决定了读/写操作,当向显示屏写数据时必须设置R/W=0,从显示屏读取数据时必须设置R/W=1,下图是RS和RW这两位组合对应的功能表:

兼容HX8347D和HX8347-H驱动IC类型的显示屏 - 男儿当自强 - 男儿当自强的博客

 

图7

这个表格很重要,在读写的时候如果搞错了,就导致读写出错的。HX8347-H01中有一个索引寄存器(index register,IR),它保存有内部控制寄存器和GRAM的索引数据。

3.2    写时序

兼容HX8347D和HX8347-H驱动IC类型的显示屏 - 男儿当自强 - 男儿当自强的博客

 

图8

从图8的时序可知,在SCL的16个时钟脉冲之内,依次发送的是开始字节和IR/控制寄存器的值,假如我们要向列地址结束寄存器(Column address end register)低字节寄存器0x05写入数据0xEF(239),我们在软件上写操作流程如下:

兼容HX8347D和HX8347-H驱动IC类型的显示屏 - 男儿当自强 - 男儿当自强的博客

 

图9

源代码的实现如下所示:

lcd_write_reg(0x05,0xEF); //Column End

void lcd_write_reg(unsigned char addr,unsigned char data)

{

         LCD_CS_LOW;

         DelayX1us(1);

         lcd_write_byte(0x70);

         lcd_write_byte(addr);

         LCD_CS_HIG;

 

         DelayX1us(1);

         LCD_CS_LOW;

         DelayX1us(1);

         lcd_write_byte(0x72);

         lcd_write_byte(data);

         LCD_CS_HIG;

         DelayX1us(1);

}

这里解释一下为什么第一个写周期需要首先写入的值是0x70呢?因为我们先指定要写入的寄存器地址到IR中,结合图7可知,对应的RS=0,R/W=0,再结合控制字节的格式(见图8),这样就可以确定我们如果要设置IR,就要先发送0x70;而第二个写周期的目的是要把数据写入指定的寄存器中,结合图7可以,对应的RS=1,R/W0,所以可以确定是0x72,接下来看lcd_write_byte函数是如何发送一个字节的数据的:

兼容HX8347D和HX8347-H驱动IC类型的显示屏 - 男儿当自强 - 男儿当自强的博客

 

图10

这里需要重点注意数据的发送是在SCL的上升沿还是下降沿有效的,根据图8可知是在SCL的上升沿的时候,处理器应该向SDA端发送当前数据位的,所以就有了图10的控制方式,假如我把SCL上升沿的时间提前,比如:

兼容HX8347D和HX8347-H驱动IC类型的显示屏 - 男儿当自强 - 男儿当自强的博客

 

图11

这时候就设备启动的时候显示屏是白屏,这是因为我们要发送的数据没有在正确的时序发送过去而导致的,从而可以看出要密切结合时序来控制的重要性。

 

3.3    读时序

兼容HX8347D和HX8347-H驱动IC类型的显示屏 - 男儿当自强 - 男儿当自强的博客

 

图12

图12可知读操作的一个周期也是16个时钟脉冲,前8个时钟脉冲同步开始字且是向驱动IC写入,后8个时钟脉冲同步寄存器值的输出。那么假如我们要读取Himax ID register(地址为0x00)的值,该如何实现呢?首先要告诉(写)驱动IC,处理器要读取地址为0x00寄存器的值,那么肯定要把0x00的值写入到IR(索引寄存器);然后从保存在IR中的值0x00对应的寄存器中读取数据,操作流程如下:

兼容HX8347D和HX8347-H驱动IC类型的显示屏 - 男儿当自强 - 男儿当自强的博客

 

图13

这里解释一下为什么第二个周期发送的开始字节是0x73,因为第一个周期发送的开始字节0x70是告诉驱动IC要对地址为0x00的寄存器进行操作(读还是写就有第二个周期发送的开始字节的内容决定),因为我们要从地址为0x00的寄存器中读取数据(要获取ID),结合图7可知,需要设置RS=1,R/W=1才能读取对应的寄存器的值,所以就有了0x73,对应的控制代码如下:

unsigned char lcd_read_reg(unsigned char addr)

{

         unsigned char data=0;

        

         LCD_CS_LOW;

         DelayX1us(1);

         lcd_write_byte(0x70);

         lcd_write_byte(addr);

         LCD_CS_HIG;

 

         DelayX1us(1);

         LCD_CS_LOW;

         DelayX1us(1);

         lcd_write_byte(0x73);

         data = Lcd_Read_Byte();

         LCD_CS_HIG;

         DelayX1us(1);

         return data;

}

根据图2可知,此驱动IC的ID code是0x79,可是为什么我读取到的值却是0x78呢?后来我继续读取最低位为1的寄存器的值,读取出来的却是0,而不是1,为什么呢?从这个现象上来看,应该是在读取的时候丢掉了最低位D0了,先来看Lcd_Read_Byte的实现部分:

兼容HX8347D和HX8347-H驱动IC类型的显示屏 - 男儿当自强 - 男儿当自强的博客

 

图14

  评论这张
 
阅读(1756)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017