你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

使用Nano板验证驱动SPI串口屏的颜色显示

[复制链接]
阿青_STM32 发布时间:2024-12-25 19:18

一、简介

正如简介所述,本章节内容针对屏显示出现色差问题。前段时间使用FRDM-MCXN947成功驱动了一块1.77寸的TFT屏,颜色正常。双十二在淘宝上购得一块1.44寸同方案的TFT屏,除了尺寸分辨率不同,接线接口都一致,使用FRDM-MCXN947相同的工程去点这块1.44屏,显示的颜色出现异常了,红色变蓝色,画图显示如下图。商家提示需要参考给出的工程示例,重新编写驱动代码,因此采用Nano板验证该问题。

色差.jpg

二、开发板资源

该开发板是基于STM32F103RBT6的,板载ST-Link,下载调试都很方便,板卡可在正点原子旗舰店购买。

硬件资源.png

三、代码移植

这里只是为验证屏的色差问题,因此咱们借助商家提供的参考驱动代码,移植到板块SDK中的SPI工程示例中。工程采用基于寄存器版本的,废话少说,咱们直接上部分主干代码吧。

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "key.h"
#include "spi.h"
#include "usmart.h"
#include "w25qxx.h"
#include "main.h"
#include "lcd.h" 

//要写入到W25Q16的字符串数组
const u8 TEXT_Buffer[]={"NANOSTM32 SPI TEST"};
#define SIZE sizeof(TEXT_Buffer)
extern u16 POINT_COLOR;

void TEST_STAND()   //测试画面  
 {
        DispFrame();            //显示框线画面
        StopDelay(Delay_Time);      //画面延时

        DispGrayHor16();        //显示16阶灰度画面
        StopDelay(Delay_Time);      //画面延时

        StopDelay(Delay_Time);      //画面延时

        DispBand();         //显示彩条画面
        StopDelay(Delay_Time);      //画面延时

        DispColor(RED);         //显示红色画面
        StopDelay(Delay_Time);      //画面延时

        DispColor(GREEN);       //显示绿色画面
        StopDelay(Delay_Time);      //画面延时

        DispColor(BLUE);        //显示蓝色画面
        StopDelay(Delay_Time);      //画面延时

        DispColor(WHITE);       //显示白色画面
        StopDelay(Delay_Time);      //画面延时

        DispColor(BLACK);       //显示黑色画面
        StopDelay(Delay_Time);      //画面延时
}

int main(void)
{ 
    u8 key;
    u16 i=0;
    u8 datatemp[SIZE];
    u32 FLASH_SIZE;
    Stm32_Clock_Init(9); //系统时钟设置
    delay_init(72);      //延时初始化
    uart_init(72,115200);//串口初始化 
    LED_Init();      //初始化与LED连接的硬件接口
    KEY_Init();      //按键初始化         
    W25QXX_Init();       //SPI FLASH 初始化 
    LCD_Init();
    usmart_dev.init(72);    //初始化USMART
    printf("NANO STM32\r\n");    
    printf("SPI TEST\r\n");
    while(W25QXX_ReadID()!=W25Q16)//检测W25Q16
    {
        printf("W25Q16 Check Failed!\r\n");
        delay_ms(500);
        printf("Please Check!\r\n");
        delay_ms(500);
        LED0=!LED0;//DS0闪烁
    }
        printf("W25Q16 Ready!\r\n");
    printf("KEY_UP:Write  KEY1:Read\r\n");
    FLASH_SIZE=2*1024*1024; //FLASH 大小为2M字节
    while(1)
    {
        key=KEY_Scan(0);
        if(key==WKUP_PRES)  //WK_UP 按下,写入W25Q16
        {
            LED2=0;
                    printf("\r\nStart Write W25Q16....\r\n");
            W25QXX_Write((u8*)TEXT_Buffer,FLASH_SIZE-100,SIZE);
            printf("W25Q16 Write Finished!\r\n");//提示传送完成
            LED2=1;
        }
        if(key==KEY1_PRES)  //KEY1 按下,读取字符串并显示
        {
            LED2=0;
            printf("\r\nStart Read W25Q16....\r\n");
            W25QXX_Read(datatemp,FLASH_SIZE-100,SIZE);
            printf("The Data Readed Is:  \r\n");//提示传送完成
            printf("%s\r\n",datatemp);//显示读到的字符串
            LED2=1;
        }
        i++;
        delay_ms(10);
        if(i==20)
        {
            LED0=!LED0;//提示系统正在运行
            i=0;
        }        
        TEST_STAND();
                POINT_COLOR = RED;
                LCD_ShowString(0,32,100,16,16,"Hello World");
                StopDelay(Delay_Time);
    }
}
#ifndef __LCD_H2
#define __LCD_H2
#include "sys.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
//==================================================================
enum LCD_INTERFACE{MCU16,SPI4Line,MCU8,MCUH8,SPI3Line,SPI3Line2,SPI4Line_CS_D8};
typedef struct _LCD_CONFIG{
    int col;
    int row;
    int col_pre;
    int row_pre;
    int delay_time;
    u8 is_commdata16;
    enum LCD_INTERFACE lcd_interface;
    u32 pic_bytes;
}LCD_CONFIG;
//==================================================================
///*LCD-MCU端口定义*/
//==================================================================
#define LCD_RS_SET      GPIOA->BSRR=1<<1    //DC            PA1    
#define LCD_WR_SET      GPIOA->BSRR=1<<2    //SCL       PA2
#define LCD_RD_SET      GPIOA->BSRR=1<<3    //SDA       PA3
#define LCD_RST_SET     GPIOA->BSRR=1<<4    //RES       PA4

#define LCD_RS_CLR      GPIOA->BRR=1<<1     //DC            PA1    
#define LCD_WR_CLR      GPIOA->BRR=1<<2     //SCL       PA2
#define LCD_RD_CLR      GPIOA->BRR=1<<3     //SDA       PA3
#define LCD_RST_CLR     GPIOA->BRR=1<<4     //RES       PA4

//IO SPI
#define LCD_SPI_SCL_SET     GPIOA->BSRR=1<<2    //SPI_SCL
#define LCD_SPI_SDA_SET     GPIOA->BSRR=1<<3    //SPI_SDA
#define LCD_SPI_SDA2_SET    GPIOB->BSRR=1<<2    //SPI_SDA2

#define LCD_SPI_SCL_CLR     GPIOA->BRR=1<<2     //SPI_SCL
#define LCD_SPI_SDA_CLR     GPIOA->BRR=1<<3     //SPI_SDA
#define LCD_SPI_SDA2_CLR    GPIOB->BRR=1<<2     //SPI_SDA2

#define DATAOUT(x)      GPIOA->ODR=x;       //数据输出  
#define DATAIN          GPIOA->IDR;         //数据输入

#define LCD_PD_SET      GPIOA->BSRR=1<<5    //BLK   PA5
#define LCD_PD_CLR    GPIOA->BRR=1<<5       //BLK       PA5

#define LCD_CS_SET      CS_SET()            //CS    PA6
#define LCD_CS_CLR      CS_CLR()            //CS    PA6

///*画笔颜色*/
//=======================================================
#define WHITE      0xFFFF
#define BLACK      0x0000     
#define BLUE       0x001F 
#define BRED       0XF81F
#define GRED       0XFFE0
#define GBLUE      0X07FF
#define RED        0xF800
#define MAGENTA    0xF81F
#define GREEN      0x07E0
#define CYAN       0x7FFF
#define YELLOW     0xFFE0
#define BROWN      0XBC40 //棕色
#define BRRED      0XFC07 //棕红色
#define GRAY       0X8430 //灰色
#define GRAY25     0xADB5
//GUI颜色
#define DARKBLUE   0X01CF //深蓝色
#define LIGHTBLUE  0X7D7C //浅蓝色  
#define GRAYBLUE   0X5458 //灰蓝色
//以上三色为PANEL的颜色 

#define LIGHTGREEN      0X841F //浅绿色
#define LGRAY       0XC618 //浅灰色(PANNEL),窗体背景色

#define LGRAYBLUE       0XA651 //浅灰蓝色(中间层颜色)
#define LBBLUE          0X2B12 //浅棕蓝色(选择条目的反色)

#define X_min 0x0043    //TP测试范围常量定义
#define X_max 0x07AE
#define Y_min 0x00A1
#define Y_max 0x0759
//==========================================
extern u16 BACK_COLOR, POINT_COLOR ;  
void LCD_CONFIG_INIT(void);
void LCD_Init(void);
void LCD_IC_Init(void);
void LCD_WR_REG(u16 data);
void LCD_WR_DATA(u16 data);
void SendData(unsigned int color);
void DispColor(unsigned int color);
void BlockWrite(unsigned int Xstart,unsigned int Xend,unsigned int Ystart,unsigned int Yend);
void LCD_GPIOInit(void);

void WriteOneDot(unsigned int color);
void WriteDispData(unsigned int color1,unsigned int color2);
void DispFrame(void);
void DispBand(void);
void DispGrayHor16(void);
void DispGrayHor32(void);
extern void TP_DrawLine(void);
void DrawGird(unsigned int color);
void PutPixel(unsigned int x,unsigned int y,unsigned int color);
void DispStr(unsigned char *str,unsigned int Xstart,unsigned int Ystart,unsigned int TextColor,unsigned int BackColor);
void DispInt(unsigned int i,unsigned int Xstart,unsigned int Ystart,unsigned int TextColor,unsigned int BackColor);
void StopDelay(unsigned int sdly);
void LCD_SetCursor(unsigned short Xpos, unsigned short Ypos);
void LCD_Fast_DrawPoint(unsigned short x,unsigned short y,unsigned short color);
void  LCD_DispChars_24a(/*坐标X*/unsigned short Char_X,/*坐标Y*/unsigned short Char_Y,/*显示内容*/char hz[],/*显示颜色*/uint16_t Char_Color,/*显示样式*/u8 XY_Mod );
void LCD_ShowString(u16 x,u16 y,u16 width,u16 height,u8 size,u8 *p);
void LCD_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2);
void LCD_DrawLine(u16 x1, u16 y1, u16 x2, u16 y2);
void LCD_DrawPoint(u16 x,u16 y);
void LCD_ShowCharaa(uint16_t x,uint16_t y,uint16_t fc, uint16_t bc, uint8_t num,uint8_t size,uint8_t mode);
void LCD_ShowCharqq(uint16_t x,uint16_t y,uint16_t fc, uint16_t bc, uint8_t num,uint8_t size,uint8_t mode);
void Show_Str(uint16_t x, uint16_t y, uint16_t fc, uint16_t bc, uint8_t *str,uint8_t size,uint8_t mode);
void LCD_ShowChar(u16 x,u16 y,u8 num,u8 size,u8 mode);
void DispColor_9bit_window(unsigned char r,unsigned char g,unsigned char b);
void DispBand_9b(void);  
void DispFrame_9b(void);
void DispGrayHor16_9b(void); 
void DispChess(u8 div);
void TEST_STAND_9b(void);
#endif
#include <stdio.h>
#include <string.h>
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "w25qxx.h"
#include "lcd.h"
#include "interface.h"
#include "stm32f10x_gpio.h"
#include "main.h"
#include "stm32f10x_rcc.h"
//=========================================
// 函数: void LCD_GPIOInit(void)
// 描述: LCD 相关的GPIO设定
//=========================================
void LCD_GPIOInit(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); 
    GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure); 
    GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6);

}
//struct LCD_CONFIG lcdconfig;
LCD_CONFIG lcdconfig;
//=============================================================
// 函数: void LCD_CONFIG_INIT(void)
// 描述: LCD设置初始化
//=============================================================
void LCD_CONFIG_INIT(void)
{
    lcdconfig.col=COL;
    lcdconfig.row=ROW;
    lcdconfig.col_pre=COL_Pre;
    lcdconfig.row_pre=ROW_Pre;
    #ifdef LCD_SPI4Line
    lcdconfig.lcd_interface=SPI4Line;
    #endif
    #ifdef LCD_SPI3Line
    lcdconfig.lcd_interface=SPI3Line;
    #endif
        lcdconfig.delay_time=Delay_Time;
    #ifdef commdata16
    lcdconfig.is_commdata16=1;
    #else
    lcdconfig.is_commdata16=0;
    #endif
    #ifdef TEST_STAND_H9B
    lcdconfig.pic_bytes=(COL*ROW)*3;
    #else
    lcdconfig.pic_bytes=(COL*ROW)<<1;
    #endif
}

void LCD_RESET(void)
{
    LCD_RST_SET;
    delay_ms(50);
    LCD_RST_CLR;
    delay_ms(200);
    LCD_RST_SET;
    delay_ms(200);
}

void LCD_Init(void)
{
    LCD_GPIOInit();
    LCD_CONFIG_INIT();
    LCD_RESET();
    LCD_IC_Init();
}

void WriteOneDot(unsigned int color)
{
    LCD_CS_CLR;
    LCD_RD_SET;
    LCD_RS_SET;
    SendData(color);
    LCD_CS_SET;
}
void WriteDispData(unsigned int color1,unsigned int color2)
{
    SendData(color1);
    SendData(color2);
}
void DispColor(unsigned int color)
{
    unsigned int i,j;
    BlockWrite(COL_Pre,COL+COL_Pre-1,ROW_Pre,ROW+ROW_Pre-1);
    LCD_CS_CLR;
    LCD_RS_SET;
    LCD_RD_SET;
    for(i=0;i<ROW;i++)
    {
            for(j=0;j<COL;j++)
        {  
        SendData(color);
         }
    }
    LCD_CS_SET;
}
void DispBand(void)  
{
    int i,j,k;
    unsigned int color[8]={0xf800,0xf800,0x07e0,0x07e0,0x001f,0x001f,0xffff,0xffff};//0x94B2

        BlockWrite(COL_Pre,COL+COL_Pre-1,ROW_Pre,ROW+ROW_Pre-1);
    LCD_CS_CLR;
    LCD_RD_SET;
    LCD_RS_SET;                                                                                                   
    for(i=0;i<8;i++)
    {
        for(j=0;j<ROW/8;j++)
        {
                    for(k=0;k<COL;k++)
            {
                SendData(color[i]); 
            } 
        }
    }
    for(j=0;j<ROW%8;j++)
    {
        for(k=0;k<COL;k++)
        {
            SendData(color[7]); 
        } 
    }
    LCD_CS_SET;
}
//==========================================
void DispFrame(void)
{
    unsigned int i,j;
    BlockWrite(COL_Pre,COL+COL_Pre-1,ROW_Pre,ROW+ROW_Pre-1);
    LCD_CS_CLR;
    LCD_RS_SET;
    LCD_RD_SET;
    SendData(0xf800);
    for(i=0;i<COL-2;i++){SendData(0xFFFF);}
    SendData(0x001f);
    for(j=0;j<ROW-2;j++)
    {
        SendData(0xf800);
        for(i=0;i<COL-2;i++){SendData(0x0000);}
        SendData(0x001F);
    }
    SendData(0xf800);
    for(i=0;i<COL-2;i++){SendData(0xFFFF);}
    SendData(0x001F);
    LCD_CS_SET;
}
void DispGrayHor16(void)     
{
    int i,j,k;
        BlockWrite(COL_Pre,COL+COL_Pre-1,ROW_Pre,ROW+ROW_Pre-1);
    LCD_CS_CLR;
    LCD_RD_SET;
    LCD_RS_SET;                                                                                                   
    for(i=0;i<ROW;i++)
    {
        for(j=0;j<COL%16;j++)
        {
            SendData(0);
        }
        for(j=0;j<16;j++)
        {
                    for(k=0;k<COL/16;k++)
            {
                SendData(((((j*2)<<3)|((j*4)>>3))<<8)|(((j*4)<<5)|(j*2)));
            } 
        }
    }
    LCD_CS_SET; 
}

void LCD_IC_Init()
{
    WriteComm(0x11); //Sleep out
    Delay(120); 
    //---------------ST7735S Frame Rate---------------//
    WriteComm(0xB1);
    WriteData(0x05);
    WriteData(0x3A);
    WriteData(0x3A);
    WriteComm(0xB2);
    WriteData(0x05);
    WriteData(0x3A);
    WriteData(0x3A);
    WriteComm(0xB3);
    WriteData(0x05);
    WriteData(0x3A);
    WriteData(0x3A);
    WriteData(0x05);
    WriteData(0x3A);
    WriteData(0x3A);
    //-----------------End ST7735S Frame Rate------------------//
    WriteComm(0xB4);  //Dot inversion
    WriteData(0x03);
    //------------------ST7735S Power Sequence----------------//
    WriteComm(0xC0);
    WriteData(0x62);
    WriteData(0x02);
    WriteData(0x04);
    WriteComm(0xC1);
    WriteData(0xC0);
    WriteComm(0xC2);
    WriteData(0x0D);
    WriteData(0x00);
    WriteComm(0xC3);
    WriteData(0x8D);
    WriteData(0x6A);
    WriteComm(0xC4);
    WriteData(0x8D);
    WriteData(0xEE);
    //-----------------End ST7735S Power Sequence--------------------//
    WriteComm(0xC5); //VCOM
    WriteData(0x12);
    //-----------------ST7735S Gamma Sequence-------------------------//
    WriteComm(0xE0);
    WriteData(0x03);
    WriteData(0x1B);
    WriteData(0x12);
    WriteData(0x11);
    WriteData(0x3F);
    WriteData(0x3A);
    WriteData(0x32);
    WriteData(0x34);
    WriteData(0x2F);
    WriteData(0x2B);
    WriteData(0x30);
    WriteData(0x3A);
    WriteData(0x00);
    WriteData(0x01);
    WriteData(0x02);
    WriteData(0x05);
    WriteComm(0xE1);
    WriteData(0x03);
    WriteData(0x1B);
    WriteData(0x12);
    WriteData(0x11);
    WriteData(0x32);
    WriteData(0x2F);
    WriteData(0x2A);
    WriteData(0x2F);
    WriteData(0x2E);
    WriteData(0x2C);
    WriteData(0x35);
    WriteData(0x3F);
    WriteData(0x00);
    WriteData(0x00);
    WriteData(0x01);
    WriteData(0x05);
    //---------------End ST7735S Gamma Sequence-------------//
    WriteComm(0xFC); //Enable Gate power save mode
    WriteData(0x8C);
    WriteComm(0x3A); //65k mode
    WriteData(0x05);
    WriteComm(0x36); //65k mode
    WriteData(0xC8);
    WriteComm(0x29); //Display on
}

void BlockWrite(unsigned int Xstart,unsigned int Xend,unsigned int Ystart,unsigned int Yend) 
{
     WriteComm(0x2a);
     WriteData((Xstart)>>8);
     WriteData((Xstart));
     WriteData((Xend)>>8);
     WriteData(Xend);

     WriteComm(0x2b);
     WriteData((Ystart)>>8);
     WriteData((Ystart));
     WriteData((Yend)>>8);
     WriteData(Yend);

     WriteComm(0x2c); 
}

四、下载验证

由于板载ST-Link调试接口,只需要一个MicroUSB数据线,即可完成下载。显示效果如下视频,颜色纯正,验证商家的屏没问题,128X128的分辨率显示非常流畅。

TFT屏正常显示.zip

TFT屏正常显示.mp4

TFT屏正常显示.gif
收藏 评论0 发布时间:2024-12-25 19:18

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版