3线spi屏幕驱动方式

前言

最近研究了一下3线spi屏幕的驱动方式。屏幕的驱动芯片为ILI9488,相比于4线,3线spi屏幕没有用到DC写命令/写数据控制线。DC=0表示写命令,DC=1表示写数据。

3线spi数据格式

在这里插入图片描述
3线spi就是将DC命令放到了每个8位数据的最高位。这么说还是有些枯燥,看下具体的例子。
假如采用spi发送0x55,一般采用的MSB,高位在前的方式。
那么SDA(MOSI)数据线上是这样的:

01010101

如果要假如dc命令,则0x55要分为两个字节进行发送,假设DC=1,则SDA(MOSI)数据如下:

10101010 1
低字节 高字节

相当于要将0x55转换为:0x80AA。同时要在单片机中设置spi数据为9位。经过多次摸索,其转换公式为:

uint16_t data = (0x8000&(cmd<<15))|(0x7f&(cmd>>1)) ;

具体在esp32中需要将发送函数改为如下:

static void lcd_cmd(spi_device_handle_t spi, const uint8_t cmd)
{
    esp_err_t ret;
    spi_transaction_t t;
    uint16_t data=0;
    data = (0x8000&(cmd<<15))|(0x7f&(cmd>>1)) ;
    memset(&t, 0, sizeof(t));       //Zero out the transaction
    t.length=9;                     //Command is 8 bits
    t.tx_buffer=&data;               //The data is the cmd itself
    ret=spi_device_polling_transmit(spi, &t);  //Transmit!
    assert(ret==ESP_OK);            //Should have had no issues.
}

static void lcd_data_byte(spi_device_handle_t spi, const uint8_t cmd)
{
    esp_err_t ret;
    spi_transaction_t t;
    uint16_t data=0;
     data = (0x8000&(cmd<<15))|(0x80|cmd>>1) ;
    memset(&t, 0, sizeof(t));       //Zero out the transaction
    t.length=8;                     //Command is 8 bits
    t.tx_buffer=&data;               //The data is the cmd itself
    ret=spi_device_polling_transmit(spi, &t);  //Transmit!
    assert(ret==ESP_OK);            //Should have had no issues.
}

只有改成为这样才能正常与屏幕通信。这个造成了通信速度降低,难以采用dma传输大量的数据。原因就是每个字节都要先进行拆解拼凑成2个字节再发送。及其不方便,当时调这个花了不少时间。

个人觉得3线spi通信方式及其扯淡,效率极低,还是老老实实用4线spi或者单片机8080接口来驱动屏幕。有的屏幕中DC引脚使用RS来表示的,笔者也是一开始没搞明白,发现这个屏幕没有DC引脚,才来研究3线spi,后面发现屏幕刷新率太低了,刷新一整屏需要10s钟。最后发现RS=DC,立刻改为4线spi,爽歪歪。

不过ILI9488这个驱动芯片最坑的一点是采用spi方式,只支持8bit和18bit的颜色格式,不支持16bit。这是实验所得,其规格书上写的是采用4线spi时,可以支持16bit颜色,
但将0x3A写入0x05(16bit)屏幕没有显示,只有将0x3A写入0x06(18bit)时,才能显示出颜色。这一点非常坑爹。

ILI9488 18位颜色格式

在这里插入图片描述
通常用的都是16位颜色,所以在采用18位颜色是需要进行装换。然后再通过spi发送。具体转换方式就是

    colors[0] = (color>>8)&0xf8;
    colors[1] = (color>>3)&0xfc;
    colors[2] = (color<<3)&0xfc;

红色放到第一个字节,绿色放到第二个字节,蓝色放到低三个字节,且都是高位对齐。低位空置。转换后屏幕即可正常显示。

  • 6
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
Linux SPI屏幕驱动是一种用于控制SPI接口屏幕驱动程序。下面是一个简单的SPI屏幕驱动程序的示例: ```c #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/spi/spi.h> static struct spi_device *spi_device; static int spi_screen_probe(struct spi_device *spi) { printk(KERN_INFO "SPI screen probe called.\n"); spi_device = spi; return 0; } static int spi_screen_remove(struct spi_device *spi) { printk(KERN_INFO "SPI screen remove called.\n"); spi_device = NULL; return 0; } static struct spi_driver spi_screen_driver = { .driver = { .name = "spi_screen", .owner = THIS_MODULE, }, .probe = spi_screen_probe, .remove = spi_screen_remove, }; static int __init spi_screen_init(void) { int ret; printk(KERN_INFO "SPI screen driver init called.\n"); ret = spi_register_driver(&spi_screen_driver); if (ret < 0) { printk(KERN_ERR "Failed to register SPI screen driver.\n"); return ret; } return 0; } static void __exit spi_screen_exit(void) { printk(KERN_INFO "SPI screen driver exit called.\n"); spi_unregister_driver(&spi_screen_driver); } module_init(spi_screen_init); module_exit(spi_screen_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Your Name"); MODULE_DESCRIPTION("SPI screen driver"); ``` 这个驱动程序使用了Linux SPI框架提供的API来与SPI设备进行通信。在probe函数中,我们可以初始化SPI设备并进行必要的设置。在remove函数中,我们可以清理并关闭SPI设备。 如果你想了解更多关于Linux SPI屏幕驱动的信息,可以参考以下资料: - 《Linux设备驱动开发详解》 - 《Linux内核源代码情景分析》 - 《Linux驱动开发实战》
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值