jinglixixi 发表于 2025-8-11 20:18

【STM32U385RG 测评】+ LCD显示屏硬件驱动

本帖最后由 jinglixixi 于 2025-8-11 20:28 编辑

#申请原创#
前面介绍了以软件模拟的方式来驱动LCD屏,有了其成功的基础再来尝试硬件的驱动方式就方便了许多,因为硬件驱动的主要工作就是配置SPI的初始化函数及变更SPI发送字节数据的函数就,其他的基本无需进行调整。

为了驱动LCD显示屏,这里使用的是接口SPI1,相应的引脚连接关系为:CLK ---PA1MOSI---PA7DC ---PC7CS ---PC9RST---PC6

图1 所用接口


对SPI1的初始化函数为:void MX_SPI1_Init(void)
{
SPI_AutonomousModeConfTypeDef HAL_SPI_AutonomousMode_Cfg_Struct = {0};
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_1LINE;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 0x7;
hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
hspi1.Init.NSSPolarity = SPI_NSS_POLARITY_LOW;
hspi1.Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA;
hspi1.Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE;
hspi1.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE;
hspi1.Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE;
hspi1.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_DISABLE;
hspi1.Init.IOSwap = SPI_IO_SWAP_DISABLE;
hspi1.Init.ReadyMasterManagement = SPI_RDY_MASTER_MANAGEMENT_INTERNALLY;
hspi1.Init.ReadyPolarity = SPI_RDY_POLARITY_HIGH;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
    Error_Handler();
}
HAL_SPI_AutonomousMode_Cfg_Struct.TriggerState = SPI_AUTO_MODE_DISABLE;
HAL_SPI_AutonomousMode_Cfg_Struct.TriggerSelection = SPI_GRP1_GPDMA_CH0_TCF_TRG;
HAL_SPI_AutonomousMode_Cfg_Struct.TriggerPolarity = SPI_TRIG_POLARITY_RISING;
if (HAL_SPIEx_SetConfigAutonomousMode(&hspi1, &HAL_SPI_AutonomousMode_Cfg_Struct) !=   HAL_OK)
{
    Error_Handler();
}
}

实现SPI发送字节数据的函数为:void lcd_writebyte(uint8_t dat)
{
         lcd_st7735_cs_l();
         HAL_SPI_Transmit(&hspi1, &dat, 1, 1000);
         lcd_st7735_cs_h();
}

实现8位和16位数据发送的函数分别为:void lcd_st7735_write_dat8(uint8_t dat)
{
      
         lcd_st7735_rs_h();
         lcd_writebyte(dat);
}

void lcd_st7735_write_dat16(uint16_t dat)
{
         lcd_st7735_cs_l();
         lcd_st7735_rs_h();
         lcd_writebyte(dat>>8);
         lcd_writebyte(dat);
         lcd_st7735_cs_h();
}

向寄存器发送数据的函数分别为:void lcd_st7735_write_reg(uint8_t reg)
{
         lcd_st7735_rs_l();
         lcd_writebyte(reg);
         lcd_st7735_rs_h();
}

对所用显示屏的初始化函数为:void init_lcd_st7735(void)
{
lcd_st7735_cs_h();
lcd_st7735_rst_l();
HAL_Delay(20);
lcd_st7735_rst_h();
HAL_Delay(20);
lcd_st7735_write_reg(0x11);
HAL_Delay(120);
lcd_st7735_write_reg(0xB1);
lcd_st7735_write_dat8(0x01);
lcd_st7735_write_dat8(0x2C);
lcd_st7735_write_dat8(0x2D);
lcd_st7735_write_reg(0xB2);
lcd_st7735_write_dat8(0x01);
lcd_st7735_write_dat8(0x2C);
lcd_st7735_write_dat8(0x2D);
lcd_st7735_write_reg(0xB3);
lcd_st7735_write_dat8(0x01);
lcd_st7735_write_dat8(0x2C);
lcd_st7735_write_dat8(0x2D);
lcd_st7735_write_dat8(0x01);
lcd_st7735_write_dat8(0x2C);
lcd_st7735_write_dat8(0x2D);
lcd_st7735_write_reg(0xB4);
lcd_st7735_write_dat8(0x07);
lcd_st7735_write_reg(0xC0);
lcd_st7735_write_dat8(0xA2);
lcd_st7735_write_dat8(0x02);
lcd_st7735_write_dat8(0x84);
lcd_st7735_write_reg(0xC1);
lcd_st7735_write_dat8(0xC5);
lcd_st7735_write_reg(0xC2);
lcd_st7735_write_dat8(0x0A);
lcd_st7735_write_dat8(0x00);
lcd_st7735_write_reg(0xC3);
lcd_st7735_write_dat8(0x8A);
lcd_st7735_write_dat8(0x2A);
lcd_st7735_write_reg(0xC4);
lcd_st7735_write_dat8(0x8A);
lcd_st7735_write_dat8(0xEE);
lcd_st7735_write_reg(0xC5);
lcd_st7735_write_dat8(0x0E);
lcd_st7735_write_reg(0x36);
lcd_st7735_write_dat8(0xC0);
lcd_st7735_write_reg(0xe0);
lcd_st7735_write_dat8(0x0f);
lcd_st7735_write_dat8(0x1a);
lcd_st7735_write_dat8(0x0f);
lcd_st7735_write_dat8(0x18);
lcd_st7735_write_dat8(0x2f);
lcd_st7735_write_dat8(0x28);
lcd_st7735_write_dat8(0x20);
lcd_st7735_write_dat8(0x22);
lcd_st7735_write_dat8(0x1f);
lcd_st7735_write_dat8(0x1b);
lcd_st7735_write_dat8(0x23);
lcd_st7735_write_dat8(0x37);
lcd_st7735_write_dat8(0x00);
lcd_st7735_write_dat8(0x07);
lcd_st7735_write_dat8(0x02);
lcd_st7735_write_dat8(0x10);
lcd_st7735_write_reg(0xe1);
lcd_st7735_write_dat8(0x0f);
lcd_st7735_write_dat8(0x1b);
lcd_st7735_write_dat8(0x0f);
lcd_st7735_write_dat8(0x17);
lcd_st7735_write_dat8(0x33);
lcd_st7735_write_dat8(0x2c);
lcd_st7735_write_dat8(0x29);
lcd_st7735_write_dat8(0x2e);
lcd_st7735_write_dat8(0x30);
lcd_st7735_write_dat8(0x30);
lcd_st7735_write_dat8(0x39);
lcd_st7735_write_dat8(0x3f);
lcd_st7735_write_dat8(0x00);
lcd_st7735_write_dat8(0x07);
lcd_st7735_write_dat8(0x03);
lcd_st7735_write_dat8(0x10);
lcd_st7735_write_reg(0x2a);
lcd_st7735_write_dat8(0x00);
lcd_st7735_write_dat8(0x00);
lcd_st7735_write_dat8(0x00);
lcd_st7735_write_dat8(0x7f);
lcd_st7735_write_reg(0x2b);
lcd_st7735_write_dat8(0x00);
lcd_st7735_write_dat8(0x00);
lcd_st7735_write_dat8(0x00);
lcd_st7735_write_dat8(0x9f);
lcd_st7735_write_reg(0xF0);
lcd_st7735_write_dat8(0x01);
lcd_st7735_write_reg(0xF6);
lcd_st7735_write_dat8(0x00);
lcd_st7735_write_reg(0x3A);
lcd_st7735_write_dat8(0x05);
lcd_st7735_write_reg(0x29);      
}

以指定色彩填充屏幕的函数为:voidLcd_Clear(Color)
{
   uint16_t i,j;
   lcd_address_set(0,0,128-1,160-1);
   lcd_st7735_write_reg(0x2c);
   for(i=0;i<128;i++)
   {
         for(j=0;j<160;j++)
         {
               lcd_st7735_write_dat16(Color);
         }
   }
}

实现字符及字符串显示的函数分别为:void LCD_ShowChar(unsigned int x,unsigned int y,char num,char mode)
{
      char temp;
      char pos,t;
      unsigned int x0=x;
      unsigned int colortemp=POINT_COLOR;   
      if(x>LCD_W-16||y>LCD_H-16)return;                           
      num=num-' ';
      lcd_address_set(x,y,x+8-1,y+16-1);            
      if(!mode)
      {
                for(pos=0;pos<16;pos++)
                {
                        temp=asc2_1608[(unsigned int)num*16+pos];
                        for(t=0;t<8;t++)
                        {               
                              if(temp&0x01) POINT_COLOR=colortemp;
                              else POINT_COLOR=BACK_COLOR;
                              lcd_st7735_write_dat16(POINT_COLOR);
                              temp>>=1;
                              x++;
                        }
                        x=x0;
                        y++;
                }      
      }
      else
      {
                for(pos=0;pos<16;pos++)
                {
                  temp=asc2_1608[(unsigned int)num*16+pos];
                  for(t=0;t<8;t++)
                  {               
                        if(temp&0x01) LCD_DrawPoint(x+t,y+pos,POINT_COLOR);
                        temp>>=1;
                  }
                }
      }
      POINT_COLOR=colortemp;                                          
}

void LCD_ShowString(unsigned int x,unsigned int y,const char *p)
{         
    while(*p!='\0')
    {      
      if(x>LCD_W-16){x=0;y+=16;}
      if(y>LCD_H-16){y=x=0;}
      LCD_ShowChar(x,y,*p,0);
      x+=8;
      p++;
    }
}

经程序的编译和下载,其测试效果如图2和图3所示,说明显示驱动有效。
图2 整体连接

图3 显示效果
页: [1]
查看完整版本: 【STM32U385RG 测评】+ LCD显示屏硬件驱动