[STM32U5] 【NUCLEO-U5A5ZJ-Q测评】+TFT屏显示驱动

[复制链接]
975|2
 楼主| jinglixixi 发表于 2023-12-22 13:16 | 显示全部楼层 |阅读模式
本帖最后由 jinglixixi 于 2023-12-22 23:22 编辑

前面介绍了驱动LCD屏的方法,稍有不足的是它的屏幕尺寸比较小,且引脚不便直接Arduino接口来使用。为此,这里选取了一款2.2TFT屏作为测试目标,其显示分辨率为320*240,采用SPI方式工作。
为进行测试,该显示屏与开发板的连接关系为:
CS---PA5
RST---PA6
D/C---PA7
SDA---PD14
SCL---PD15
BLK---PF12
对使用引脚的工作模式配置函数为:
  1. void Init_lcd(void)
  2. {
  3.     GPIO_InitTypeDefGPIO_InitStruct;
  4.     __HAL_RCC_GPIOA_CLK_ENABLE();
  5.     GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
  6.     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  7.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  8.     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  9.     __HAL_RCC_GPIOD_CLK_ENABLE();
  10.     GPIO_InitStruct.Pin = GPIO_PIN_14|GPIO_PIN_15;
  11.     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  12.     GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
  13.     HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
  14.     __HAL_RCC_GPIOF_CLK_ENABLE();
  15.     GPIO_InitStruct.Pin = GPIO_PIN_12;
  16.     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  17.     GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
  18.     HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
  19. }
为输出高低电平所作的语句定义为:
#define OLED_CS_Set()     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5,GPIO_PIN_SET)
#define OLED_CS_Clr()     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5,GPIO_PIN_RESET)
#define OLED_RST_Set()    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6,GPIO_PIN_SET)
#define OLED_RST_Clr()    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6,GPIO_PIN_RESET)
#define OLED_DC_Set()     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_SET)
#define OLED_DC_Clr()     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7,GPIO_PIN_RESET)
#define OLED_SDIN_Set()   HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14,GPIO_PIN_SET)
#define OLED_SDIN_Clr()   HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14,GPIO_PIN_RESET)
#define OLED_SCLK_Set()   HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15,GPIO_PIN_SET)
#define OLED_SCLK_Clr()   HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15,GPIO_PIN_RESET)
#define OLED_BLK_Set()    HAL_GPIO_WritePin(GPIOF, GPIO_PIN_12,GPIO_PIN_SET)
该显示屏的初始化函数为:
  1. voidLcd_Init(void)
  2. {
  3.     OLED_RST_Clr();
  4.     HAL_Delay(20);
  5.     OLED_RST_Set();
  6.     HAL_Delay(20);
  7.     LCD_WR_REG(0xCB);  
  8.     LCD_WR_DATA8(0x39);
  9.     LCD_WR_DATA8(0x2C);
  10.     LCD_WR_DATA8(0x00);
  11.     LCD_WR_DATA8(0x34);
  12.     LCD_WR_DATA8(0x02);
  13.     LCD_WR_REG(0xCF);  
  14.     LCD_WR_DATA8(0x00);
  15.     LCD_WR_DATA8(0XC1);
  16.     LCD_WR_DATA8(0X30);
  17.     LCD_WR_REG(0xE8);  
  18.     LCD_WR_DATA8(0x85);
  19.     LCD_WR_DATA8(0x00);
  20.     LCD_WR_DATA8(0x78);
  21.     LCD_WR_REG(0xEA);  
  22.     LCD_WR_DATA8(0x00);
  23.     LCD_WR_DATA8(0x00);
  24.     LCD_WR_REG(0xED);  
  25.     LCD_WR_DATA8(0x64);
  26.     LCD_WR_DATA8(0x03);
  27.     LCD_WR_DATA8(0X12);
  28.     LCD_WR_DATA8(0X81);
  29.     LCD_WR_REG(0xF7);  
  30.     LCD_WR_DATA8(0x20);
  31.     LCD_WR_REG(0xC0);
  32.     LCD_WR_DATA8(0x23);
  33.     LCD_WR_REG(0xC1);
  34.     LCD_WR_DATA8(0x10);
  35.     LCD_WR_REG(0xC5);
  36.     LCD_WR_DATA8(0x3e);
  37.     LCD_WR_DATA8(0x28);
  38.     LCD_WR_REG(0xC7);
  39.     LCD_WR_DATA8(0x86);
  40.     LCD_WR_REG(0x36);
  41.     LCD_WR_DATA8(0x48);
  42.     LCD_WR_REG(0x3A);
  43.     LCD_WR_DATA8(0x55);
  44.     LCD_WR_REG(0xB1);
  45.     LCD_WR_DATA8(0x00);
  46.     LCD_WR_DATA8(0x18);
  47.     LCD_WR_REG(0xB6);
  48.     LCD_WR_DATA8(0x08);
  49.     LCD_WR_DATA8(0x82);
  50.     LCD_WR_DATA8(0x27);
  51.     LCD_WR_REG(0xF2);
  52.     LCD_WR_DATA8(0x00);
  53.     LCD_WR_REG(0x26);
  54.     LCD_WR_DATA8(0x01);
  55.     LCD_WR_REG(0xE0);
  56.     LCD_WR_DATA8(0x0F);
  57.     LCD_WR_DATA8(0x31);
  58.     LCD_WR_DATA8(0x2B);
  59.     LCD_WR_DATA8(0x0C);
  60.     LCD_WR_DATA8(0x0E);
  61.     LCD_WR_DATA8(0x08);
  62.     LCD_WR_DATA8(0x4E);
  63.     LCD_WR_DATA8(0xF1);
  64.     LCD_WR_DATA8(0x37);
  65.     LCD_WR_DATA8(0x07);
  66.     LCD_WR_DATA8(0x10);
  67.     LCD_WR_DATA8(0x03);
  68.     LCD_WR_DATA8(0x0E);
  69.     LCD_WR_DATA8(0x09);
  70.     LCD_WR_DATA8(0x00);
  71.     LCD_WR_REG(0XE1);
  72.     LCD_WR_DATA8(0x00);
  73.     LCD_WR_DATA8(0x0E);
  74.     LCD_WR_DATA8(0x14);
  75.     LCD_WR_DATA8(0x03);
  76.     LCD_WR_DATA8(0x11);
  77.     LCD_WR_DATA8(0x07);
  78.     LCD_WR_DATA8(0x31);
  79.     LCD_WR_DATA8(0xC1);
  80.     LCD_WR_DATA8(0x48);
  81.     LCD_WR_DATA8(0x08);
  82.     LCD_WR_DATA8(0x0F);
  83.     LCD_WR_DATA8(0x0C);
  84.     LCD_WR_DATA8(0x31);
  85.     LCD_WR_DATA8(0x36);
  86.     LCD_WR_DATA8(0x0F);
  87.     LCD_WR_REG(0x11);
  88.     HAL_Delay(120);
  89.     LCD_WR_REG(0x29);
  90.     LCD_WR_REG(0x2c);
  91.     OLED_BLK_Set();
  92. }
以模拟方式发送字节数据的函数为:
  1. voidLCD_Writ_Bus(u8 dat)
  2. {
  3.     u8i;
  4.     OLED_CS_Clr();
  5.     for(i=0;i<8;i++)
  6.     {
  7.         if(dat&0x80)
  8.         OLED_SDIN_Set();
  9.         else
  10.         OLED_SDIN_Clr();
  11.         dat<<=1;
  12.         Delay_Us(2);
  13.         OLED_SCLK_Clr();
  14.         Delay_Us(2);
  15.         OLED_SCLK_Set();
  16.     }
  17.     OLED_CS_Set();
  18. }
以指定色彩清除屏幕的函数为:
  1. voidLCD_Clear(u16 Color)
  2. {
  3.     u16i,j;
  4.     LCD_Address_Set(0,0,LCD_W-1,LCD_H-1);
  5.     for(i=0;i<LCD_W;i++)
  6.     {
  7.        for (j=0;j<LCD_H;j++)
  8.        {
  9.           LCD_WR_DATA(Color);
  10.        }
  11.     }
  12. }
在使用色彩清屏函数进行测试的情况下,证明以上函数可以驱动该显示屏。
随后,又为其配置了字符串和图像函数。

其字符串显示函数为:
  1. voidLCD_ShowString(u16 x,u16 y,const u8 *p,u16 color)
  2. {
  3.     while(*p!='\0')
  4.     {
  5.        if(x>LCD_W-16) {x=0;y+=16;}
  6.        if(y>LCD_H-16) {y=x=0;LCD_Clear(RED);}
  7.        LCD_ShowChar(x,y,*p,0,color);
  8.        x+=8;
  9.        p++;
  10.     }
  11. }
其图像显示函数为:
  1. voidLCD_ShowPicture(u16 x1,u16 y1,u16 x2,u16 y2)
  2. {
  3.       inti;
  4.       LCD_Address_Set(x1,y1,x2,y2);
  5.       for(i=0;i<12800;i++)
  6.       {
  7.             LCD_WR_DATA8(gImage_RW[i*2]);
  8.             LCD_WR_DATA8(gImage_RW[i*2+1]);
  9.       }
  10. }
实现图1显示效果的主程序为:
  1. int main(void)
  2. {
  3.         HAL_Init();
  4.         SystemClock_Config();
  5.         SystemPower_Config();
  6.         MX_ICACHE_Init();
  7.         Init_lcd ();
  8.         Lcd_Init();
  9.         BACK_COLOR=RED;
  10.         LCD_Clear(RED);
  11.         LCD_ShowString(20,5,"NUCLEO-U5A5ZJ-Q",YELLOW);
  12.         LCD_ShowString(20,25,"0.96'LCD",YELLOW);
  13.         LCD_ShowString(20,50,"jinglixixi",YELLOW);        
  14.         LCD_ShowPicture(20,120,179,199);
  15.         while (1);
  16. }
1.jpg
1 显示效果
前面为了进行测试是采用飞线的方式来连接显示屏,那直接将显示屏插入Arduino接口能使显示屏工作吗?
回答是不能,由图2可知在通常情况下VREFP引脚是连接3.3V参考电压的,但对于该开发板它是悬空状态,且连接到了CN12的引脚4

为了能给显示屏提供3.3V的工作电源,只需给CN12的引脚4接上3.3V电源即可。
2.jpg
2  Arduino接口

在为显示屏提供工作电源后,其测试效果如图3所示。这样终于可以有效地减少连线的麻烦了,且提高了工作的可靠性。
3.jpg
3 测试效果

Jacquetry 发表于 2024-1-12 16:52 | 显示全部楼层
用IO输出高电平能带动屏幕吗
 楼主| jinglixixi 发表于 2024-1-12 21:38 | 显示全部楼层
Jacquetry 发表于 2024-1-12 16:52
用IO输出高电平能带动屏幕吗

功率小的没问题
您需要登录后才可以回帖 登录 | 注册

本版积分规则

521

主题

2949

帖子

39

粉丝
快速回复 在线客服 返回列表 返回顶部