1.3寸SPI通讯TFT LCD显示屏(驱动笔记) 您所在的位置:网站首页 彩色显示屏的接线图片 1.3寸SPI通讯TFT LCD显示屏(驱动笔记)

1.3寸SPI通讯TFT LCD显示屏(驱动笔记)

2024-07-18 03:48| 来源: 网络整理| 查看: 265

LCD的驱动为ST7789V,采用SPI协议单工进行通讯。正常SPI通讯拥有四根线片选先线、时钟线、输入线、输出线四根线配合进行输出,而LCD屏只需要写入数据显示即可,因此该显示屏引脚只有SPI通讯的时钟线和输入线。

一、硬件介绍 1.1 1.3寸SPI通讯TFT LCD显示屏

拥有GND、VCC、SCL、SDA、RES、DC、BLK四个引脚,分别为负极、正极(3.3V)、SCL(时钟信号线)、SDA(数据线)、RES(复位线)、DC(寄存器\数据写入选择线)、BLK(背光开启)。

驱动为ST7789V,最多能够驱动240*320分辨率的显示屏,而实际显示屏的分辨率只有240*240的分辨率。

1.2 单片机为STM32F103C6T6

单片机与LCD屏引脚的连接分别为:

BLK  ->  PB5 DC   ->  PB6 RES  ->  PB7 SDA  ->  PB8 SCL  ->  PB9

引脚设置均为推挽输出、上拉电阻;PB8与PB9的初始电压设置为高,其余三个引脚初始电压设置为低。

二、程序编写 2.1 GPIO模拟SPI输出

该模块时钟线和数据线初始状态均为高电平,时钟线由低电平变化为高电平的时刻,对信号线进行采样,传输时,高位在先,低位在后。

void LCD_Transport(char data) {     uint8_t i;     // pull down the clock time     for(i = 0; i < 8; i++)     {         LCD_CLK_Low();         if(data&0x80) // OUTPUT Volt              LCD_SDA_High();         else              LCD_SDA_Low();         LCD_CLK_High(); //RESET         data     // pull down CS,choose this machine     // DC -> high  transport data     LCD_DC_High();     LCD_Transport(data>>8);     LCD_Transport(data);     // SPI hasn't reply mechanism }

void LCD_Write_REG(char REG) {     // DC -> REG choose REG     LCD_DC_Low();     LCD_Transport(REG); }

2.3初始化函数

初始化函数为重启、开启背光、配置寄存器等一些列操作。其中该型号显示屏能够配置12位、16位、18位的RGB等,显示屏分辨率为240*240,也就是240*240个像素点,而每个像素点都可以由12个、16个、18个小灯组成,每个像素点通过不同的RGB搭配方式可以显示出不同的颜色。一般24位以上的RGB显示才能称为真彩显示,因此该显示屏的显示效果比不上现在的手机屏的显示效果。

void LCD_Init() {     // reset at first     LCD_RST_Low();     Delay_ms(20);     LCD_RST_High();     Delay_ms(20);     LCD_BLK_High();  // open background      // set scan mode in screen memory and data form     LCD_Write_REG(0x36);     LCD_Write_Data8(0x00);     //  set RGB form  color deep  16 bit R:5 G:6 B:5; RGB: 444 RGB: 666     LCD_Write_REG(0x3A);     LCD_Write_Data8(0x05);     // porch set     LCD_Write_REG(0xB2);     LCD_Write_Data8(0x0C);     LCD_Write_Data8(0x0C);     LCD_Write_Data8(0x00);     LCD_Write_Data8(0x33);     LCD_Write_Data8(0x33);     // Gate volt control  default setting   VGL=-8.87  VGH=14.06     LCD_Write_REG(0xB7);     LCD_Write_Data8(0x35);     // Vcom volt 0.9v  default setting      LCD_Write_REG(0xBB);     LCD_Write_Data8(0x19);     // LCM control     LCD_Write_REG(0xC0);     LCD_Write_Data8(0x2C);     // VDV and VRH Command Enable      LCD_Write_REG(0xC2);     LCD_Write_Data8(0x01);     // VRH Set      LCD_Write_REG(0xC3);     LCD_Write_Data8(0x12);     // VDV Set     LCD_Write_REG(0xC4);     LCD_Write_Data8(0x20);     //Frame Rate Control in Normal Mode  60 Hz  00: 119Hz     LCD_Write_REG(0xC6);     LCD_Write_Data8(0x0F);     // Power Control 1   default value     LCD_Write_REG(0xD0);     LCD_Write_Data8(0xA4);     LCD_Write_Data8(0xA1);     //Positive Voltage Gamma Control      LCD_Write_REG(0xE0);     LCD_Write_Data8(0xD0);     LCD_Write_Data8(0x04);     LCD_Write_Data8(0x0D);     LCD_Write_Data8(0x11);     LCD_Write_Data8(0x13);     LCD_Write_Data8(0x2B);     LCD_Write_Data8(0x3F);     LCD_Write_Data8(0x54);     LCD_Write_Data8(0x4C);     LCD_Write_Data8(0x18);     LCD_Write_Data8(0x0D);     LCD_Write_Data8(0x0B);     LCD_Write_Data8(0x1F);     LCD_Write_Data8(0x23);     //Negative Voltage Gamma Control      LCD_Write_REG(0xE1);     LCD_Write_Data8(0xD0);     LCD_Write_Data8(0x04);     LCD_Write_Data8(0x0C);     LCD_Write_Data8(0x11);     LCD_Write_Data8(0x13);     LCD_Write_Data8(0x2C);     LCD_Write_Data8(0x3F);     LCD_Write_Data8(0x44);     LCD_Write_Data8(0x51);     LCD_Write_Data8(0x2F);     LCD_Write_Data8(0x1F);     LCD_Write_Data8(0x1F);     LCD_Write_Data8(0x20);     LCD_Write_Data8(0x23);     // Display Inversion On      LCD_Write_REG(0x21);     // turn off Sleep mode     LCD_Write_REG(0x11);     Delay_ms(20);     // Display On     LCD_Write_REG(0x29); }

2.4 设置操作区域函数

LCD屏的显示操作就是先指定需要填充颜色的像素区域或像素点,分别在0x0a、0x2b、0x2c中操作即可。

void address_set(uint16_t x1,uint16_t y1,uint16_t x2, uint16_t y2) {     if(x2>wide-1|| y2>length-1)return;     else     {         // choose x axle register         LCD_Write_REG(0x2A);         // write 16 bit          LCD_Write_Data8(x1>>8);          LCD_Write_Data8(x1);          LCD_Write_Data8(x2>>8);         LCD_Write_Data8(x2);          // choose y axle register             LCD_Write_REG(0x2B);         LCD_Write_Data8(y1>>8);          LCD_Write_Data8(y1);          LCD_Write_Data8(y2>>8);          LCD_Write_Data8(y2);          // reset to start colum / page position         LCD_Write_REG(0x2C);     } }

2.5 像素点填充

以清屏函数为例,先指定全屏区域作为填充区域,后在每个像素点中逐个填入颜色。

void LCD_SPI_Clear(uint16_t color) {     int i,j;     address_set(0,0, wide - 1, length - 1);  // choose total screen     for(i = 0; i < wide; i++)     {         for(j = 0; j < length; j++)         {             LCD_Write_Data(color);         }     }

2.4 字符和数字的显示

每个字符占用的像素点为8*16个,因此需要配置8*16个像素点中的每个像素的颜色来显示字符串。字符在文件的存储形式为16个字节的数据,每个字节的8位代表8个像素点的像素值,0代表背景色,1代表显示颜色,这就比较简单,也就是通过二维数组来存储字符串,若要存储图片,那么就还需要存储每个像素点具体像素值,这就需要三维的数组,而数字显示则是将实际的数字进行加减乘除运算得到对应的字符串并显示。

void Draw_one_charater(uint8_t x, uint8_t y,char a, uint16_t color) {     uint8_t temp;     // the show table only have value after space     a = a - ' ';     address_set(x,y,x + 7,y + 15);     for(uint8_t i = 0; i < 16; i++)     {         temp = asc2_1608[a*16 + i];         for(uint8_t j = 0; j < 8; j++) // write horizontal at first         {             if(temp&0x01)             {                 LCD_Write_Data(color);             }             else             {                 LCD_Write_Data(BLACK);             }             temp>>=1;         }     } }

void Show_String(uint8_t x, uint8_t y, char *string,uint8_t String_long) {     // character occupy 8*16 position  0 or 1 reprensent pixel show black or wihte     if(y+16>length)     {         return;     }     else     {         if(x + 8 * String_long                 Draw_one_charater(x + i *8, y,string[i], WHITE);             }         }         else         {             return;         }     } }

void Show_number(uint8_t x, uint8_t y, uint32_t number,uint8_t number_bit_in_ten) {     uint32_t temp;     char Display_Number;     // The MAX Display 10 bits in LCD uint32_t is 10 bit     uint8_t memory_nuber[10];      // ASCII: 0 -> 48 9 -> 57     temp = number;     if(x + number_bit_in_ten * 8 > wide)return;     else     {         for(uint8_t i = 0; i < number_bit_in_ten; i++)         {                     memory_nuber[i] = temp % 10;             temp = temp / 10;         }             for(uint8_t i = 0; i < number_bit_in_ten; i++)         {                     Display_Number = memory_nuber[number_bit_in_ten - i - 1] + 48;             Draw_one_charater(x + i * 8, y,Display_Number, YELLOW);         }     }  }

三、主函数和显示效果

主函数只需要添加初始化和清屏函数即可。

    LCD_Init();     LCD_SPI_Clear(BLACK);     LCD_Draw_Horizontal_Line(16,8,220);     LCD_Draw_Horizontal_Line(16,16,220);     LCD_Draw_Horizontal_Line(16,24,220);     LCD_Draw_Horizontal_Line(16,32,220);     LCD_Draw_Vetical_Line(16,8,32);     LCD_Draw_Vetical_Line(116,8,32);     LCD_Draw_Vetical_Line(220,8,32);     Show_String(72, 48, "char:",5);     Show_number(112,48,sizeof(char),1);     Show_String(72, 64, "short int:",10);     Show_number(152,64,sizeof(short int),1);     Show_String(72, 80, "int:",4);     Show_number(104,80,sizeof(int),1);

显示效果:

之前一直错误的以为int在电脑中占用4字节,在单片机中只占用1个字节,现在事实证明,和电脑中的一样;char-> 1bit  short int -> 2bit int -> 4bit



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有