Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1570789
  • 博文数量: 204
  • 博客积分: 2215
  • 博客等级: 大尉
  • 技术积分: 4426
  • 用 户 组: 普通用户
  • 注册时间: 2011-06-06 08:03
个人简介

气质,源于心灵的自信!

文章存档

2018年(1)

2017年(1)

2016年(1)

2015年(18)

2014年(20)

2013年(30)

2012年(119)

2011年(14)

分类:

2012-05-15 11:42:27

原文地址:LCD的SPI接口分析 作者:rain0993

   LCD与CPU的接线分控制线和数据线,控制线一般基于SPI协议,我们初始化LCD的寄存器就是通过这个,在主芯片的输出格式固定的前提之下,调LCD 也就是剩下始化寄存器而已,一般LCD移植,我们就是要关心这部分;数据线就是用来传送像素数据到LCD,这部分一般不需要我们来控制了,只要接线没问 题,一般就是OK的。   我一直不解既然这部分是定死的代码,为何不有IC厂商做成firmware,这样岂不能省出控制线部分,有位老兄这样解释:

我们可以从另一个角度来看,初始化寄存器的数值充其量也就十几B,远远达不到1KB。如果仅仅为这几十B的数据而添加一个存储设备,无形中增加了成本。所以很多LCD在使用之前都需要初始化其寄存器。呵呵,技术上讲不通的,都是因为COST  DOWN。

下面针对ILI9481DS的driver ic 讲解一下控制部分也就是SPI部分,下面是ili9481ds SPEC 的Serial Interface时序图:

 

 从上图可以提取以下信息:

1)SCL的上升沿LCD 读取数据,下降沿SDA上的电平变化

2)传输单位为9bit,其中第一个bit 用来区分下面的8bit是command还是data, 第一个bit为0则是cmd,为1这是data

于是代码如下,分发命令和数据两个函数:

发命令的函数

  1. static void ILI9481DS_spi_write_cmd_byte(u8 val)  
  2. {  
  3.         int i;  
  4.           
  5.         gpio_set_value(spi_cs, 0);   //"Low" enable  
  6.         gpio_set_value(spi_sclk, 0);          
  7.         "color:#ff6666;">gpio_set_value(spi_sdi, 0);  
  8.          
  9.         udelay(1);  
  10.         gpio_set_value(spi_sclk, 1);//clk产生上升沿,读取sdi电平为0,根据spec下面的8bit是command而不是data  
  11.         udelay(1);  
  12.   
  13. /*取val二进制的各位,并通过sdi发送出去*/  
  14.         for (i = 0; i < 8; i++) {  
  15.             /* #1: Drive the Data (High or Low) */  
  16.             gpio_set_value(spi_sclk, 0);  
  17.             if (val & bit_shift[i]) //  
  18.                 gpio_set_value(spi_sdi, 1);  
  19.             else  
  20.                 gpio_set_value(spi_sdi, 0);  
  21.       
  22.             /* #2: Drive the Clk High and then Low */  
  23.             udelay(1);  
  24.             gpio_set_value(spi_sclk, 1);//clk产生上升沿,从机会读取sid上的电平  
  25.             udelay(1);  
  26.         }  
  27.       
  28.         /*FIXME: Idle state of sdi should be low */  
  29.         if (gpio_get_value(spi_sdi)) {            
  30.             gpio_set_value(spi_sdi, 0);  
  31.         }         
  32.         gpio_set_value(spi_cs, 1);  //disable LCD chip  
  33. }  

发数据的函数

  1. static void ILI9481DS_spi_write_data_byte(u8 val)  
  2. {  
  3.         int i;  
  4.           
  5.         gpio_set_value(spi_cs, 0);   //"Low" enable  
  6.         gpio_set_value(spi_sclk, 0);          
  7.         "color:#ff6666;">gpio_set_value(spi_sdi, 1);  // data  
  8.          
  9.         udelay(1);  
  10.         gpio_set_value(spi_sclk, 1);//clk产生上升沿,读取sdi电平为1,根据spec下面的8bit是data而不是command  
  11.         udelay(1);  
  12.   
  13. /*取val二进制的各位,并通过sdi发送出去*/  
  14.         for (i = 0; i < 8; i++) {  
  15.             /* #1: Drive the Data (High or Low) */  
  16.             gpio_set_value(spi_sclk, 0);  
  17.             if (val & bit_shift[i]) //  
  18.                 gpio_set_value(spi_sdi, 1);  
  19.             else  
  20.                 gpio_set_value(spi_sdi, 0);  
  21.       
  22.             /* #2: Drive the Clk High and then Low */  
  23.             udelay(1);  
  24.             gpio_set_value(spi_sclk, 1);//clk产生上升沿,从机会读取sid上的电平  
  25.             udelay(1);  
  26.         }  
  27.       
  28.         /*FIXME: Idle state of sdi should be low */  
  29.         if (gpio_get_value(spi_sdi)) {            
  30.             gpio_set_value(spi_sdi, 0);  
  31.         }         
  32.         gpio_set_value(spi_cs, 1);  //disable LCD chip  
  33. }  

两个函数的区别仅仅是红色标识部分!


补充一点,关于通过SPI写入lcd的数据,什么是cmd什么是data,可以看一下这个帖子

阅读(1343) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~