嵌入式学习--work11 关于SPI的深入学习及软件模拟SPI(LCD调试所遇)

在调试液晶LCD时,需要向LCD驱动通过硬件SPI发送9bits遇到的问题:
LCD是某清洋实业公司生产,在其液晶显示模块规格书里,
1、描述了尺寸为 1.22 inch,接口类型为 SPI 3Line2Lane Interface,SPI为三线两通道的SPI,液晶驱动IC是ST7789(Sitronix公司生产的)。
引脚如图所示:
ss
LCD厂家的时序图如下:
这里写图片描述
可以看出都是往SDA,输入数据,并且发送的数据位在9位!
2、我
们从LCD的驱动ST7789里找到关于 3-LIne的SPI时序图如下:三线SPI
这里写图片描述
关于三线SPI,就是只使用了SDA、SCK、CS三根线,SDA可以作为输入与输出引脚,在LCD的驱动里,我们只需要作为输出就行,所以可以设置为MOSI。这里说明以下,原以为SPI协议是只能作为全双工通信,其实不然,它也可以作为半双工通信方式,具体可以参考:《STM32F4xx中文参考手册》里关于SPI的说明,可以设置的。
小技巧,如果你不想去设置成半双工的通信方式,而驱动又没有用到MISO引脚,你可以选择直接配置成全双工,只是MISO直接不连就行了。
引脚如下:三线SPI与四线SPI的区别是DCX位四线的模式是另外设置一根引脚的,而三线模式下,DCX位它是SPI发送出去的。正因如此,它可以节省一个引脚,可它也给某些驱动带来了弊端。
这里写图片描述
唔觉得这里的引脚图有问题,我改过来了,这样子看引脚与时序图才是搭在一起的,下面的英文解释也印证了我的观点,:
这里写图片描述
这里写图片描述
这里写图片描述

这里我们先确定一些可以确定的东西,首先是时钟线起始为低,然后上升沿有效,因而,SPI的CPOL 与 CPHA 都应设为0,CPOL = 0,CPHA =0;并且,在配置SCK引脚时可以不上拉,及就设为NOPULL,GPIO_InitStructure.Pull = GPIO_NOPULL;如果CPOL与CPHA设置为1了,那么SCK引脚就要上拉,因为时序要求起始位为高电平状态。
下面我们看下引脚:
可以确定:PB5(MOSI)-SDA、PB3(SCK)-SCL、PA15(NSS)-CS。注意看上面的AF是06还是05。
这里写图片描述
其他引脚可以不使用。

/————以下—————分割线————-结论————/

主要的原因是之前的代码里,有人用软件模拟了一个SPI协议,代码如下,现在想直接调用库函数的方式来实现SPI。STM32F0系列有的可以设置8bits至16bits之间的任意位数,因而可以,可我使用的F411不可以,只能设置为8bits或者16bits,那么怎么办》?
方法1可以是,在每次write_command()或者write_data()时,改变GPIO的模式,改为通用IO口模式,然后往里面输入1/0,然后再改回复用SPI模式。可这样的操作太冗余,每次都在初始化与消除初始化,在我看来还不如直接用软件模拟SPI通信呢。
方法2,设置为16位输出,这个我不确定可以不可以,驱动是辨别9bits,我们通过SPI发送16位进去,怎么截取是个问题,还得将所有命令修改格式,也挺麻烦的。


void write_command(uint8_t addr) 
{
  LCD_CS_High();
  LCD_CS_Low();                   //片选拉低有效
  LCD_SCLK_Low();                 //时钟线拉低
  LCD_WR_Low();                   //D/C位拉低,写命令
  LCD_SCLK_High();                //时钟线拉高
  uint8_t i=0;
  for(i=0;i<8;i++)                //模拟时钟的上升沿
    {
     LCD_SCLK_Low();              //时钟线拉低
      if (addr&0x80)
       {
         //数为1则拉高
          LCD_WR_High();          //拆分为8位,每一位依次做与运算
        }
         //数为0则拉低
      else
         {
          LCD_WR_Low();           //WR拉低
         }
      addr=addr<<1;
      //时钟拉高
      LCD_SCLK_High();
    }
  LCD_CS_High();
}
void write_data(uint8_t data) 
{
  LCD_CS_Low();
  LCD_SCLK_Low(); 

  LCD_WR_High();                       //D/C位(WR)拉 低高,写数据      
  LCD_SCLK_High();
  uint8_t i=0;
  for(i=0;i<8;i++)
  {
      LCD_SCLK_Low();
      if (data & 0x80)
        {
        LCD_WR_High();
        }
      else
        {
        LCD_WR_Low();
        }
    data=data<<1;
    LCD_SCLK_High();
    }
  LCD_CS_High();
}
阅读更多
文章标签: 嵌入式 软件
个人分类: stm32学习
所属专栏: 嵌入式学习
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

不良信息举报

嵌入式学习--work11 关于SPI的深入学习及软件模拟SPI(LCD调试所遇)

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭