ST7789V屏幕RGB初始化代码例程SPI通信

程序介绍

      • 背景
      • 后记

背景

  • IO口是自己定义的几个
  • SPI通信是三线通信,拉低然后放数据,然后拉高的时候捕获的工作方式
  • 屏幕大小是320x240
  • 因为IO口模拟SPI直接刷新太慢,所以采用的RGB接口
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define GPIO_PB_8 24
#define GPIO_PH_4 116
#define GPIO_PH_5 117
#define GPIO_PE_11 75
#define GPIO_PE_12 76

#define SCLK GPIO_PH_4
#define MOSI GPIO_PH_5
#define CS GPIO_PE_11
#define Reset GPIO_PE_12
#define LCDPWM GPIO_PB_8

#define OUTP 1 //表示GPIO接口方向为输出
#define INP 0  //表示GPIO接口方向为输入

#define set_gpio_value gpio_set_value
#define get_gpio_value gpio_get_value

//默认为1则一直关比背光灯,默认为0一直打开背光灯
#define LCDdefault 0

//先释放一下几个gpio口为了方便以后的占用
static void spi_free_gpio(void)
{
     
    gpio_free(MOSI);
    gpio_free(SCLK);
    gpio_free(CS);
    gpio_free(Reset);
    gpio_free(LCDPWM);
}

//申请GPIO口资源
static int spi_request_gpio(void)
{
     
    if (gpio_request(MOSI, "spi_mosi") < 0)
    {
     
        printk("fail to request mosi\n");
        return -1;
    }
    if (gpio_request(SCLK, "spi_sclk\n") < 0)
    {
     
        printk("fail to request sclk\n");
        return -1;
    }
    if (gpio_request(CS, "spi_cs") < 0)
    {
     
        printk("fail to request cs\n");
        return -1;
    }
    if (gpio_request(Reset, "spi_reset") < 0)
    {
     
        printk("fail to request reset\n");
        return -1;
    }
    if (gpio_request(LCDPWM, "spi_lcdpwm") < 0)
    {
     
        printk("fail to request lcdpwm\n");
        return -1;
    }
    return 0;
}

/* SPI端口初始化 用于每次传递参数 */
static void spi_init(void)
{
     
    gpio_set_value(SCLK, 0);
    gpio_set_value(MOSI, 0);
}

/*  
  从设备使能  
  enable:为1时,使能信号有效,SS低电平  
  为0时,使能信号无效,SS高电平  
  */
//因为不确定cs为高低才是使能,所以先保持原样
void ss_enable(int enable)
{
     
    if (enable)
        set_gpio_value(CS, 0); //SS低电平,从设备使能有效
    else
        set_gpio_value(CS, 1); //SS高电平,从设备使能无效
}

/* SPI字节写 */
void spi_write_cmd(unsigned char b)
{
     
    //变量初始化
    int i;

    /* SPI端口初始化 */
    spi_init();
    // udelay(5);

    ss_enable(1); //从设备使能有效,通信开始
    // udelay(5);

    for (i = 8; i >= 0; i--)
    {
     
        if (i == 8)
        {
     
            set_gpio_value(SCLK, 0);
            // udelay(5);               //延时
            set_gpio_value(MOSI, 0); //如果是写命令则首位先写0
            // udelay(5);               //延时
            set_gpio_value(SCLK, 1); // CPHA=1,在时钟的第一个跳变沿采样
            // udelay(5);
        }
        else
        {
     
            set_gpio_value(SCLK, 0);
            // udelay(5);                        //延时
            set_gpio_value(MOSI, b & 1 << i); //从高位7到低位0进行串行写入
            // udelay(5);                        //延时
            set_gpio_value(SCLK, 1); // CPHA=1,在时钟的第一个跳变沿采样
            // udelay(5);                        //延时
        } //延时
    }

    set_gpio_value(SCLK, 0);
    // udelay(5);

    //结束单次通信
    ss_enable(0);
}

void spi_write_data(unsigned char b)
{
     
    //变量初始化
    int i;

    /* SPI端口初始化 */
    spi_init();
    // udelay(5);

    ss_enable(1); //从设备使能有效,通信开始
    // udelay(5);    //延时

    for (i = 8; i >= 0; i--)
    {
     
        if (i == 8)
        {
     
            set_gpio_value(SCLK, 0);
            // udelay(5);               //延时
            set_gpio_value(MOSI, 1); //如果是写数据则首位先写1
            // udelay(5);               //延时
            set_gpio_value(SCLK, 1); // CPHA=1,在时钟的第一个跳变沿采样
            // udelay(5);
        }
        else
        {
     
            set_gpio_value(SCLK, 0);
            // udelay(5);                        //延时
            set_gpio_value(MOSI, b & 1 << i); //从高位7到低位0进行串行写入
            // udelay(5);                        //延时
            set_gpio_value(SCLK, 1); // CPHA=1,在时钟的第一个跳变沿采样
            // udelay(5);                        //延时
        }
    }

    set_gpio_value(SCLK, 0);
    // udelay(5);

    //结束单次通信
    ss_enable(0);
}

//屏幕初始化函数
static void spi_lcd_init(void)
{
     
    //spi模拟通信初始化
    gpio_direction_output(CS, 1);
    gpio_direction_output(SCLK, 1);
    gpio_direction_output(MOSI, 0);

    //屏幕初始化
    gpio_direction_output(LCDPWM, 1);
    gpio_direction_output(Reset, 1);
    gpio_set_value(LCDPWM, LCDdefault);
    gpio_set_value(Reset, 1);
    mdelay(10);
    gpio_set_value(Reset, 0);
    mdelay(100);
    gpio_set_value(Reset, 1);
    mdelay(500);

    spi_write_cmd(0xb2);
    spi_write_data(0x0C);
    spi_write_data(0x0C);
    spi_write_data(0x00);
    spi_write_data(0x33);
    spi_write_data(0x33);

    spi_write_cmd(0xb7);
    spi_write_data(0x35);
    //-------ST7789S Power setting-------//
    spi_write_cmd(0xbb);
    spi_write_data(0x20);

    spi_write_cmd(0xc0);
    spi_write_data(0x2c);

    spi_write_cmd(0xc2);
    spi_write_data(0x01);

    spi_write_cmd(0xc3);
    spi_write_data(0x12); //0x15

    spi_write_cmd(0xc4);
    spi_write_data(0x20);

    spi_write_cmd(0xc6);
    spi_write_data(0x0f);

    spi_write_cmd(0xd0);
    spi_write_data(0xa4);
    spi_write_data(0xa1);
    //-------ST7789S gamma setting------//
    spi_write_cmd(0xe0);
    spi_write_data(0xd0);
    spi_write_data(0x00);
    spi_write_data(0x05);
    spi_write_data(0x0e);
    spi_write_data(0x15);
    spi_write_data(0x0d);
    spi_write_data(0x37);
    spi_write_data(0x43);
    spi_write_data(0x47);
    spi_write_data(0x09);
    spi_write_data(0x15);
    spi_write_data(0x12);
    spi_write_data(0x16);
    spi_write_data(0x19);

    spi_write_cmd(0xe1);
    spi_write_data(0xd0);
    spi_write_data(0x00);
    spi_write_data(0x05);
    spi_write_data(0x0d);
    spi_write_data(0x0c);
    spi_write_data(0x06);
    spi_write_data(0x2d);
    spi_write_data(0x44);
    spi_write_data(0x40);
    spi_write_data(0x0e);
    spi_write_data(0x1c);
    spi_write_data(0x18);
    spi_write_data(0x16);
    spi_write_data(0x19);

    spi_write_cmd(0x2a);
    spi_write_data(0x00);
    spi_write_data(0x00);
    spi_write_data(0x01);
    spi_write_data(0x3f);

    spi_write_cmd(0x2b);
    spi_write_data(0x00);
    spi_write_data(0x00);
    spi_write_data(0x00);
    spi_write_data(0xef);

    spi_write_cmd(0x3a);
    spi_write_data(0x66);

    spi_write_cmd(0xB0);
    spi_write_data(0x11);
    spi_write_data(0xf0);

    spi_write_cmd(0xB1);
    spi_write_data(0x46);
    spi_write_data(0x05);
    spi_write_data(0x14);

    spi_write_cmd(0x36);
    spi_write_data(0xa0); //行列切换

    spi_write_cmd(0x11);
    mdelay(150);
    spi_write_cmd(0x29); // display on
    mdelay(50);

    printk("finished invitialized.....\n");
}

//入口主函数
static int __init ya15c_spi_init(void)
{
     
    //spi端口先释放,防止之前有人使用
    spi_free_gpio();

    //占用函数要用的几个IO口
    if (spi_request_gpio())
    {
     
        printk("ya15c spi initializer failure...\n");
        return -1;
    }

    //屏幕初始化
    printk("start to set color! ...\n");
    // setcolor();
    spi_lcd_init();

    return 0;
}

static void __exit ya15c_spi_exit(void)
{
     
    printk("ya15c exit!\n");
}

module_init(ya15c_spi_init);
module_exit(ya15c_spi_exit);
MODULE_LICENSE("GPL");

后记

代码例程也不复杂,注释也已经很清楚,唯一的问题就是初始化代码可能会不好理解,可以结合手册理解。

你可能感兴趣的:(MYD,linux,嵌入式,驱动,系统,c语言)