[STM32U3] 【STM32U385RG 测评】+ TFT屏的显示驱动

[复制链接]
 楼主| jinglixixi 发表于 2025-7-13 12:05 | 显示全部楼层 |阅读模式
本帖最后由 jinglixixi 于 2025-7-13 12:06 编辑

由于STM32U385RG开发板没有配置相关的显示器件,为此先以模拟的方式完成TFT屏的显示驱动以为后面的硬件启动方式做好准备。
采用软件驱动的一大优势就是可以灵活地配置引脚的使用,从而不受引脚位置的制约。
为了省区接线的麻烦,这里是直接使用接口CN5,见图1所示。
4cb6248893add1fc410d61b7af8d5653
图1 CN5接口

为此,TFT显示屏的引脚连接关系为:
CS----PA5
REST----PA6
DC----PA7
SDI----PC9
SCK----PC6
LED----PC7

对所用引脚的配置函数为:
  1. void SPI_CONFIG()
  2. {
  3. __HAL_RCC_GPIOA_CLK_ENABLE();
  4. __HAL_RCC_GPIOC_CLK_ENABLE();
  5. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  6. GPIO_InitStruct.Pull = GPIO_NOPULL;
  7. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  8. GPIO_InitStruct.Pin = GPIO_PIN_5| GPIO_PIN_6| GPIO_PIN_7;
  9. HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  10. GPIO_InitStruct.Pin = GPIO_PIN_6| GPIO_PIN_7| GPIO_PIN_9;
  11. HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
  12. }

所用引脚输出高低电平的语句定义为:
#define LCD_CS_High()   HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET)
#define LCD_CS_Low()    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET)
#define LCD_REST_High() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_SET)
#define LCD_REST_Low()  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_RESET)
#define LCD_DC_High()   HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_SET)
#define LCD_DC_Low()    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_RESET)
#define LCD_SDI_High()  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, GPIO_PIN_SET)
#define LCD_SDI_Low()   HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, GPIO_PIN_RESET)
#define LCD_SCK_High()  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_SET)
#define LCD_SCK_Low()   HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_RESET)
#define LCD_LED_High()  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_SET)
#define LCD_LED_Low()   HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_RESET)

有了前面的准备,就可以为显示驱动配置相应的模拟SPI方式数据的函数了,其内容为:
  1. void LCD_Writ_Bus(unsigned char com)
  2. {
  3. unsigned char uci;
  4. for(uci=0;uci<8;uci++)
  5. {
  6. if(com & 0x80)
  7. {
  8. LCD_SDI_High();
  9. }
  10. else
  11. {
  12. LCD_SDI_Low();
  13. }
  14. com = com << 1;
  15. DelayUs(1);
  16. LCD_SCK_Low();
  17. LCD_SCK_High();
  18. }
  19. }

对所用的显示屏,其初始化函数为:
  1. void TFT_Init(void)
  2. {   
  3.     LCD_REST_Low();
  4.     DelayMs(20);
  5.     LCD_REST_High();
  6.     DelayMs(20);
  7.     LCD_CS_Low();  

  8.     LCD_WR_REG(0xCB);   
  9.     LCD_WR_DATA8(0x39);
  10.     LCD_WR_DATA8(0x2C);
  11.     LCD_WR_DATA8(0x00);
  12.     LCD_WR_DATA8(0x34);
  13.     LCD_WR_DATA8(0x02);

  14.     LCD_WR_REG(0xCF);  
  15.     LCD_WR_DATA8(0x00);
  16.     LCD_WR_DATA8(0XC1);
  17.     LCD_WR_DATA8(0X30);

  18.     LCD_WR_REG(0xE8);  
  19.     LCD_WR_DATA8(0x85);
  20.     LCD_WR_DATA8(0x00);
  21.     LCD_WR_DATA8(0x78);

  22.     LCD_WR_REG(0xEA);  
  23.     LCD_WR_DATA8(0x00);
  24.     LCD_WR_DATA8(0x00);

  25.     LCD_WR_REG(0xED);  
  26.     LCD_WR_DATA8(0x64);
  27.     LCD_WR_DATA8(0x03);
  28.     LCD_WR_DATA8(0X12);
  29.     LCD_WR_DATA8(0X81);

  30.     LCD_WR_REG(0xF7);  
  31.     LCD_WR_DATA8(0x20);
  32.   
  33.     LCD_WR_REG(0xC0);  
  34.     LCD_WR_DATA8(0x23);

  35.     LCD_WR_REG(0xC1);
  36.     LCD_WR_DATA8(0x10);  

  37.     LCD_WR_REG(0xC5);
  38.     LCD_WR_DATA8(0x3e);
  39.     LCD_WR_DATA8(0x28);

  40.     LCD_WR_REG(0xC7);
  41.     LCD_WR_DATA8(0x86);

  42.     LCD_WR_REG(0x36);
  43.     LCD_WR_DATA8(0xE8);
  44.   
  45.     LCD_WR_REG(0x3A);   
  46.     LCD_WR_DATA8(0x55);

  47.     LCD_WR_REG(0xB1);   
  48.     LCD_WR_DATA8(0x00);  
  49.     LCD_WR_DATA8(0x18);

  50.     LCD_WR_REG(0xB6);
  51.     LCD_WR_DATA8(0x08);
  52.     LCD_WR_DATA8(0x82);
  53.     LCD_WR_DATA8(0x27);  

  54.     LCD_WR_REG(0xF2);  
  55.     LCD_WR_DATA8(0x00);

  56.     LCD_WR_REG(0x26);
  57.     LCD_WR_DATA8(0x01);

  58.     LCD_WR_REG(0xE0);
  59.     LCD_WR_DATA8(0x0F);
  60.     LCD_WR_DATA8(0x31);
  61.     LCD_WR_DATA8(0x2B);
  62.     LCD_WR_DATA8(0x0C);
  63.     LCD_WR_DATA8(0x0E);
  64.     LCD_WR_DATA8(0x08);
  65.     LCD_WR_DATA8(0x4E);
  66.     LCD_WR_DATA8(0xF1);
  67.     LCD_WR_DATA8(0x37);
  68.     LCD_WR_DATA8(0x07);
  69.     LCD_WR_DATA8(0x10);
  70.     LCD_WR_DATA8(0x03);
  71.     LCD_WR_DATA8(0x0E);
  72.     LCD_WR_DATA8(0x09);
  73.     LCD_WR_DATA8(0x00);

  74.     LCD_WR_REG(0XE1);  
  75.     LCD_WR_DATA8(0x00);
  76.     LCD_WR_DATA8(0x0E);
  77.     LCD_WR_DATA8(0x14);
  78.     LCD_WR_DATA8(0x03);
  79.     LCD_WR_DATA8(0x11);
  80.     LCD_WR_DATA8(0x07);
  81.     LCD_WR_DATA8(0x31);
  82.     LCD_WR_DATA8(0xC1);
  83.     LCD_WR_DATA8(0x48);
  84.     LCD_WR_DATA8(0x08);
  85.     LCD_WR_DATA8(0x0F);
  86.     LCD_WR_DATA8(0x0C);
  87.     LCD_WR_DATA8(0x31);
  88.     LCD_WR_DATA8(0x36);
  89.     LCD_WR_DATA8(0x0F);

  90.     LCD_WR_REG(0x11);  
  91.     DelayMs(120);
  92.                                 
  93.     LCD_WR_REG(0x29);  
  94.     LCD_WR_REG(0x2c);
  95.     LCD_LED_High();
  96. }

实现驱动测试的以色彩填充屏幕的函数为:
  1. void LCD_Clear(unsigned int Color)
  2. {
  3.         char VH,VL;
  4.         unsigned int i,j;
  5.         VH=Color>>8;
  6.         VL=Color;        
  7.         Address_set(0,0,LCD_H-1,LCD_W-1);
  8.         for(i=0;i<LCD_H;i++)
  9.         {
  10.                    for (j=0;j<LCD_W;j++)
  11.                    {
  12.                         LCD_WR_DATA8(VH);
  13.                         LCD_WR_DATA8(VL);        
  14.                    }
  15.         }
  16. }

经测试,该驱动是有效的。
在添加字库及显示函数的基础上,即可进行字符串的显示需求。
其显示字符的函数为:
  1. void LCD_ShowChar(unsigned int x,unsigned int y,char num)
  2. {
  3.         char temp;
  4.         char pos,t;
  5.         unsigned int x0=x;
  6.         unsigned int colortemp=POINT_COLOR;
  7.         if(x>LCD_W-16||y>LCD_H-16) return;                                    
  8.         num=num-' ';
  9.         Address_set(x,y,x+8-1,y+16-1);      
  10.         for(pos=0;pos<16;pos++)
  11.         {
  12.                     temp=asc2_1608[(unsigned int)num*16+pos];
  13.                     for(t=0;t<8;t++)
  14.                     {                 
  15.                                 if(temp&0x01)  POINT_COLOR=colortemp;
  16.                                 else POINT_COLOR=BACK_COLOR;
  17.                                 LCD_WR_DATA(POINT_COLOR);        
  18.                                 temp>>=1;
  19.                                 x++;
  20.                     }
  21.                     x=x0;
  22.                     y++;
  23.         }
  24.         POINT_COLOR=colortemp;                                          
  25. }

对应的字符串显示函数为:
  1. void LCD_ShowString(unsigned int x,unsigned int y,const char *p)
  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;}
  7.         LCD_ShowChar(x,y,*p,0);
  8.         x+=8;
  9.         p++;
  10.     }  
  11. }

进行字符串形式测试的主程序为:
  1. int main(void)
  2. {
  3.   HAL_Init();
  4.   SystemClock_Config();
  5.   MX_ICACHE_Init();
  6.   SPI_CONFIG();
  7.   TFT_Init();
  8.   LCD_Clear(RED);
  9.   BACK_COLOR=RED;
  10.   POINT_COLOR=WHITE;
  11.   LCD_ShowString(20,20,"STM32U385RG");
  12.   while (1);
  13. }

经程序的编译和下载,其测试效果如图2所示。
f125c40e38463c0512b1759ea6bcda2f
图2 显示效果

后续的任务是将模拟SPI发送数据的函数替换为以硬件的发送来实现,即硬件方式的显示驱动。

小小蚂蚁举千斤 发表于 2025-7-28 23:22 | 显示全部楼层
TFT屏的显示驱动
您需要登录后才可以回帖 登录 | 注册

本版积分规则

517

主题

2932

帖子

39

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