打印
[技术讨论]

TFT屏SPI通信方式不显示

[复制链接]
221|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
LKC134|  楼主 | 2025-7-6 11:00 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
前几天在网上淘了一块TFT2.4寸屏,驱动芯片是的ILI9341,带转接板SPI通信方式,店家提供代码例程,发现不论怎样调试屏就是不显示,被搞矇了,用逻辑分析仪测试通信时序和规格书对比,规格书要求CS时间为40ns为写入时间,读取时间为40ns,共80ns,而单片机输出为80us,是单片机速度不够快还是代码问题?

#include <STC8H.H>
#include <intrins.h>
#define uint8_t unsigned char
#define uint16_t unsigned int
#define uint32_t unsigned long

//SDO引脚可以不连接

// 引脚定义 (根据实际电路连接修改)
#define LCD_CS  P10
#define LCD_DC  P11
#define LCD_SCL P12
#define LCD_SDO P13  // 主机输出
#define LCD_SDI P14  // 主机输入
#define reset  P16


// 颜色定义 (RGB565)
#define WHITE     0xFFFF
#define BLACK     0x0000
#define RED       0xF800
#define GREEN     0x07E0
#define BLUE      0x001F

// 延时函数 (1个_nop_约42ns @24MHz)
void delay_ns(uint8_t ns)
{
    while(ns--) _nop_();
}

void Delay1ms(void)        //@24.000MHz
{
        unsigned char data i, j;

        i = 24;
        j = 85;
        do
        {
                while (--j);
        } while (--i);
}

void delay_ms(unsigned int ms)
{
        while(ms--)
        {
                Delay1ms();
        }
}
// SPI初始化
void SPI_Init(void) {
    LCD_CS = 1;   // 片选无效
    LCD_DC = 1;   // 默认数据模式
    LCD_SCL = 0;  // 时钟低电平

    // 配置IO模式 (P1.0-P1.4推挽输出)
    P1M1 = 0x00;  // 清除低5位
    P1M0 = 0xFF;  // P1.0-P1.6推挽输出
         
}

// SPI写命令
void LCD_Write_Cmd(uint8_t cmd)
        {
                uint8_t i;
    LCD_CS = 0;      // 片选有效
    LCD_DC = 0;      // 命令模式
  //  delay_ns(1);     // >10ns (tas)

    // 发送8位命令
    for( i= 0; i < 8; i++)
        {
        LCD_SCL = 0;
        LCD_SDO = (cmd & 0x80) ? 1 : 0;
        cmd <<= 1;
       // delay_ns(1);         // >30ns (tds)
        LCD_SCL = 1;
       // delay_ns(1);         // >40ns (twrh)
    }

    LCD_SCL = 0;
    LCD_CS = 1;      // 片选释放
}

// SPI写数据
void LCD_Write_Data(uint8_t dat)
{
        uint8_t i;
    LCD_CS = 0;      // 片选有效
    LCD_DC = 1;      // 数据模式
   // delay_ns(1);     // >10ns (tas)

    // 发送8位数据
    for(i = 0; i < 8; i++) {
        LCD_SCL = 0;
        LCD_SDO = (dat & 0x80) ? 1 : 0;
        dat <<= 1;
      //  delay_ns(1);         // >30ns (tds)
        LCD_SCL = 1;
      //  delay_ns(1);         // >40ns (twrh)
    }

    LCD_SCL = 0;
    LCD_CS = 1;      // 片选释放
}

// SPI读数据
/*uint8_t LCD_Read_Data(void)
        {
    uint8_t dat = 0;
    uint8_t i;
    // 配置SDI为输入
    P1M1 |= (1 << 4);  // P1.4高阻输入
    P1M0 &= ~(1 << 4);

    LCD_CS = 0;      // 片选有效
    LCD_DC = 1;      // 数据模式
    delay_ns(1);     // >10ns (tas)

    // 读取8位数据
    for( i = 0; i < 8; i++)
                {
        LCD_SCL = 0;
        delay_ns(2);         // >60ns (ttdl)

        LCD_SCL = 1;
        dat <<= 1;
        if(LCD_SDI) dat |= 1;
        delay_ns(2);         // >60ns (trdh)
    }

    LCD_SCL = 0;
    LCD_CS = 1;      // 片选释放

    // 恢复SDO为输出模式
    P1M1 &= ~(1 << 4);
    P1M0 |= (1 << 4);

    return dat;
}*/

// ILI9341初始化
void ILI9341_Init(void) {
    // 硬件复位
    LCD_CS = 1;
          reset=0;
                delay_ms(50);
                reset=1;
                delay_ms(100);
    // 这里可以添加硬件复位逻辑,如果板子有RESET引脚

    // 软件初始化序列
    LCD_Write_Cmd(0xCF);  // Power Control B
    LCD_Write_Data(0x00);
    LCD_Write_Data(0xC1);
    LCD_Write_Data(0x30);

    LCD_Write_Cmd(0xED);  // Power on sequence control
    LCD_Write_Data(0x64);
    LCD_Write_Data(0x03);
    LCD_Write_Data(0x12);
    LCD_Write_Data(0x81);

    // ... 省略部分初始化命令,完整初始化序列请参考ILI9341数据手册

    LCD_Write_Cmd(0x36);  // Memory Access Control
    LCD_Write_Data(0x48); // RGB顺序设置

    LCD_Write_Cmd(0x3A);  // Pixel Format
    LCD_Write_Data(0x55); // 16位像素

    LCD_Write_Cmd(0x11);  // Sleep Out
    delay_ms(120);

    LCD_Write_Cmd(0x29);  // Display On
}

// 设置显示区域
void LCD_SetWindow(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) {
    LCD_Write_Cmd(0x2A);  // 列地址设置
    LCD_Write_Data(x1 >> 8);
    LCD_Write_Data(x1 & 0xFF);
    LCD_Write_Data(x2 >> 8);
    LCD_Write_Data(x2 & 0xFF);

    LCD_Write_Cmd(0x2B);  // 行地址设置
    LCD_Write_Data(y1 >> 8);
    LCD_Write_Data(y1 & 0xFF);
    LCD_Write_Data(y2 >> 8);
    LCD_Write_Data(y2 & 0xFF);

    LCD_Write_Cmd(0x2C);  // 写入GRAM
}

// 刷屏函数 (填充整个屏幕)
void LCD_FillScreen(uint16_t color)
        {
                uint32_t i;
    LCD_SetWindow(0, 0, 239, 319);  // ILI9341通常为240x320

    for( i = 0; i < 240*320; i++) {
        LCD_Write_Data(color >> 8);   // 高字节
        LCD_Write_Data(color & 0xFF); // 低字节
    }
}

// 主函数示例
void main() {
    SPI_Init();         // 初始化SPI
    ILI9341_Init();     // 初始化LCD

    while(1) {
        LCD_FillScreen(RED);
        delay_ms(500);

        LCD_FillScreen(GREEN);
        delay_ms(500);

        LCD_FillScreen(BLUE);
        delay_ms(500);

        LCD_FillScreen(WHITE);
        delay_ms(500);

        LCD_FillScreen(BLACK);
        delay_ms(500);
    }
}

使用特权

评论回复

相关帖子

沙发
LKC134|  楼主 | 2025-7-6 11:01 | 只看该作者
这是规格书的时序图

9341.JPG (217.89 KB )

9341.JPG

使用特权

评论回复
板凳
LKC134|  楼主 | 2025-7-6 11:02 | 只看该作者
这是实测的时序图

时序图.jpg (649.58 KB )

时序图.jpg

使用特权

评论回复
地板
LKC134|  楼主 | 2025-7-6 11:02 | 只看该作者
有那位大佬做过,请指点下。

使用特权

评论回复
5
xch| | 2025-7-6 19:47 | 只看该作者
你这驱动没事干老是拉高CS 干啥?大部分命令含参数的,未写完参数CS不能拉高。

另外淘宝买的号称某某驱动的可能都是假冒的。SPI接口时序不能按照正宗的写。

使用特权

评论回复
6
丙丁先生| | 2025-7-7 07:46 | 只看该作者
xch 发表于 2025-7-6 19:47
你这驱动没事干老是拉高CS 干啥?大部分命令含参数的,未写完参数CS不能拉高。

另外淘宝买的号称某某驱动 ...

感谢回复

使用特权

评论回复
7
lulugl| | 2025-7-7 07:55 | 只看该作者
使用模拟时序,应该是可以的。最好先用这块屏接到其他的开发板上使用模拟时序驱动后,然后对比时序。这样就可以找到原因。

使用特权

评论回复
8
trucyw| | 2025-7-7 08:12 | 只看该作者
你这个应该要用模拟SPI来做吧

使用特权

评论回复
9
tobot| | 2025-7-7 08:54 | 只看该作者
我之前还买 一个 屏。连cs都没有。。。

使用特权

评论回复
10
LKC134|  楼主 | 2025-7-7 10:30 | 只看该作者
xch 发表于 2025-7-6 19:47
你这驱动没事干老是拉高CS 干啥?大部分命令含参数的,未写完参数CS不能拉高。

另外淘宝买的号称某某驱动 ...

这方面也问过店家说没问题,这才郁闷。

使用特权

评论回复
11
LKC134|  楼主 | 2025-7-7 10:34 | 只看该作者
lulugl 发表于 2025-7-7 07:55
使用模拟时序,应该是可以的。最好先用这块屏接到其他的开发板上使用模拟时序驱动后,然后对比时序。这样就 ...

很多开发板的TFT是并口,驱动不一样

使用特权

评论回复
12
LKC134|  楼主 | 2025-7-7 10:36 | 只看该作者
xch 发表于 2025-7-6 19:47
你这驱动没事干老是拉高CS 干啥?大部分命令含参数的,未写完参数CS不能拉高。

另外淘宝买的号称某某驱动 ...

那要如何写呢?大佬做过这类吧?指点下。谢谢!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

43

主题

346

帖子

6

粉丝