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

[复制链接]
543|0
jinglixixi 发表于 2025-8-11 20:18 | 显示全部楼层 |阅读模式
本帖最后由 jinglixixi 于 2025-8-11 20:28 编辑

#申请原创#

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


为了驱动LCD显示屏,这里使用的是接口SPI1,相应的引脚连接关系为:
CLK ---PA1
MOSI---PA7
DC ---PC7
CS ---PC9
RST---PC6

snap.jpg
图1 所用接口



SPI1的初始化函数为:
  1. void MX_SPI1_Init(void)
  2. {
  3.   SPI_AutonomousModeConfTypeDef HAL_SPI_AutonomousMode_Cfg_Struct = {0};
  4.   hspi1.Instance = SPI1;
  5.   hspi1.Init.Mode = SPI_MODE_MASTER;
  6.   hspi1.Init.Direction = SPI_DIRECTION_1LINE;
  7.   hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  8.   hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  9.   hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  10.   hspi1.Init.NSS = SPI_NSS_SOFT;
  11.   hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
  12.   hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  13.   hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  14.   hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  15.   hspi1.Init.CRCPolynomial = 0x7;
  16.   hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
  17.   hspi1.Init.NSSPolarity = SPI_NSS_POLARITY_LOW;
  18.   hspi1.Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA;
  19.   hspi1.Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE;
  20.   hspi1.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE;
  21.   hspi1.Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE;
  22.   hspi1.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_DISABLE;
  23.   hspi1.Init.IOSwap = SPI_IO_SWAP_DISABLE;
  24.   hspi1.Init.ReadyMasterManagement = SPI_RDY_MASTER_MANAGEMENT_INTERNALLY;
  25.   hspi1.Init.ReadyPolarity = SPI_RDY_POLARITY_HIGH;
  26.   if (HAL_SPI_Init(&hspi1) != HAL_OK)
  27.   {
  28.     Error_Handler();
  29.   }
  30.   HAL_SPI_AutonomousMode_Cfg_Struct.TriggerState = SPI_AUTO_MODE_DISABLE;
  31.   HAL_SPI_AutonomousMode_Cfg_Struct.TriggerSelection = SPI_GRP1_GPDMA_CH0_TCF_TRG;
  32.   HAL_SPI_AutonomousMode_Cfg_Struct.TriggerPolarity = SPI_TRIG_POLARITY_RISING;
  33.   if (HAL_SPIEx_SetConfigAutonomousMode(&hspi1, &HAL_SPI_AutonomousMode_Cfg_Struct) !=   HAL_OK)
  34.   {
  35.     Error_Handler();
  36.   }
  37. }

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

实现8位和16位数据发送的函数分别为:
  1. void lcd_st7735_write_dat8(uint8_t dat)
  2. {
  3.         
  4.          lcd_st7735_rs_h();
  5.          lcd_writebyte(dat);
  6. }

  7. void lcd_st7735_write_dat16(uint16_t dat)
  8. {
  9.          lcd_st7735_cs_l();
  10.          lcd_st7735_rs_h();
  11.          lcd_writebyte(dat>>8);
  12.          lcd_writebyte(dat);
  13.          lcd_st7735_cs_h();
  14. }

向寄存器发送数据的函数分别为:
  1. void lcd_st7735_write_reg(uint8_t reg)
  2. {
  3.          lcd_st7735_rs_l();
  4.          lcd_writebyte(reg);
  5.          lcd_st7735_rs_h();
  6. }

对所用显示屏的初始化函数为:
  1. void init_lcd_st7735(void)
  2. {
  3.   lcd_st7735_cs_h();
  4.   lcd_st7735_rst_l();
  5.   HAL_Delay(20);
  6.   lcd_st7735_rst_h();
  7.   HAL_Delay(20);
  8.   lcd_st7735_write_reg(0x11);  
  9.   HAL_Delay(120);
  10.   lcd_st7735_write_reg(0xB1);
  11.   lcd_st7735_write_dat8(0x01);
  12.   lcd_st7735_write_dat8(0x2C);
  13.   lcd_st7735_write_dat8(0x2D);
  14.   lcd_st7735_write_reg(0xB2);
  15.   lcd_st7735_write_dat8(0x01);
  16.   lcd_st7735_write_dat8(0x2C);
  17.   lcd_st7735_write_dat8(0x2D);
  18.   lcd_st7735_write_reg(0xB3);
  19.   lcd_st7735_write_dat8(0x01);
  20.   lcd_st7735_write_dat8(0x2C);
  21.   lcd_st7735_write_dat8(0x2D);
  22.   lcd_st7735_write_dat8(0x01);
  23.   lcd_st7735_write_dat8(0x2C);
  24.   lcd_st7735_write_dat8(0x2D);
  25.   lcd_st7735_write_reg(0xB4);
  26.   lcd_st7735_write_dat8(0x07);
  27.   lcd_st7735_write_reg(0xC0);
  28.   lcd_st7735_write_dat8(0xA2);
  29.   lcd_st7735_write_dat8(0x02);
  30.   lcd_st7735_write_dat8(0x84);
  31.   lcd_st7735_write_reg(0xC1);
  32.   lcd_st7735_write_dat8(0xC5);
  33.   lcd_st7735_write_reg(0xC2);
  34.   lcd_st7735_write_dat8(0x0A);
  35.   lcd_st7735_write_dat8(0x00);
  36.   lcd_st7735_write_reg(0xC3);
  37.   lcd_st7735_write_dat8(0x8A);
  38.   lcd_st7735_write_dat8(0x2A);
  39.   lcd_st7735_write_reg(0xC4);
  40.   lcd_st7735_write_dat8(0x8A);
  41.   lcd_st7735_write_dat8(0xEE);
  42.   lcd_st7735_write_reg(0xC5);
  43.   lcd_st7735_write_dat8(0x0E);
  44.   lcd_st7735_write_reg(0x36);
  45.   lcd_st7735_write_dat8(0xC0);
  46.   lcd_st7735_write_reg(0xe0);
  47.   lcd_st7735_write_dat8(0x0f);
  48.   lcd_st7735_write_dat8(0x1a);
  49.   lcd_st7735_write_dat8(0x0f);
  50.   lcd_st7735_write_dat8(0x18);
  51.   lcd_st7735_write_dat8(0x2f);
  52.   lcd_st7735_write_dat8(0x28);
  53.   lcd_st7735_write_dat8(0x20);
  54.   lcd_st7735_write_dat8(0x22);
  55.   lcd_st7735_write_dat8(0x1f);
  56.   lcd_st7735_write_dat8(0x1b);
  57.   lcd_st7735_write_dat8(0x23);
  58.   lcd_st7735_write_dat8(0x37);
  59.   lcd_st7735_write_dat8(0x00);
  60.   lcd_st7735_write_dat8(0x07);
  61.   lcd_st7735_write_dat8(0x02);
  62.   lcd_st7735_write_dat8(0x10);
  63.   lcd_st7735_write_reg(0xe1);
  64.   lcd_st7735_write_dat8(0x0f);
  65.   lcd_st7735_write_dat8(0x1b);
  66.   lcd_st7735_write_dat8(0x0f);
  67.   lcd_st7735_write_dat8(0x17);
  68.   lcd_st7735_write_dat8(0x33);
  69.   lcd_st7735_write_dat8(0x2c);
  70.   lcd_st7735_write_dat8(0x29);
  71.   lcd_st7735_write_dat8(0x2e);
  72.   lcd_st7735_write_dat8(0x30);
  73.   lcd_st7735_write_dat8(0x30);
  74.   lcd_st7735_write_dat8(0x39);
  75.   lcd_st7735_write_dat8(0x3f);
  76.   lcd_st7735_write_dat8(0x00);
  77.   lcd_st7735_write_dat8(0x07);
  78.   lcd_st7735_write_dat8(0x03);
  79.   lcd_st7735_write_dat8(0x10);
  80.   lcd_st7735_write_reg(0x2a);
  81.   lcd_st7735_write_dat8(0x00);
  82.   lcd_st7735_write_dat8(0x00);
  83.   lcd_st7735_write_dat8(0x00);
  84.   lcd_st7735_write_dat8(0x7f);
  85.   lcd_st7735_write_reg(0x2b);
  86.   lcd_st7735_write_dat8(0x00);
  87.   lcd_st7735_write_dat8(0x00);
  88.   lcd_st7735_write_dat8(0x00);
  89.   lcd_st7735_write_dat8(0x9f);
  90.   lcd_st7735_write_reg(0xF0);
  91.   lcd_st7735_write_dat8(0x01);
  92.   lcd_st7735_write_reg(0xF6);
  93.   lcd_st7735_write_dat8(0x00);
  94.   lcd_st7735_write_reg(0x3A);
  95.   lcd_st7735_write_dat8(0x05);
  96.   lcd_st7735_write_reg(0x29);        
  97. }

以指定色彩填充屏幕的函数为:
  1. void  Lcd_Clear(Color)
  2. {
  3.      uint16_t i,j;
  4.      lcd_address_set(0,0,128-1,160-1);
  5.      lcd_st7735_write_reg(0x2c);
  6.      for(i=0;i<128;i++)
  7.      {
  8.            for(j=0;j<160;j++)
  9.            {
  10.                lcd_st7735_write_dat16(Color);
  11.            }
  12.      }
  13. }

实现字符及字符串显示的函数分别为:
  1. void LCD_ShowChar(unsigned int x,unsigned int y,char num,char mode)
  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.         lcd_address_set(x,y,x+8-1,y+16-1);            
  10.         if(!mode)
  11.         {
  12.                 for(pos=0;pos<16;pos++)
  13.                 {
  14.                         temp=asc2_1608[(unsigned int)num*16+pos];
  15.                         for(t=0;t<8;t++)
  16.                         {                 
  17.                                 if(temp&0x01) POINT_COLOR=colortemp;
  18.                                 else POINT_COLOR=BACK_COLOR;
  19.                                 lcd_st7735_write_dat16(POINT_COLOR);
  20.                                 temp>>=1;
  21.                                 x++;
  22.                         }
  23.                         x=x0;
  24.                         y++;
  25.                 }        
  26.         }
  27.         else
  28.         {
  29.                 for(pos=0;pos<16;pos++)
  30.                 {
  31.                     temp=asc2_1608[(unsigned int)num*16+pos];
  32.                     for(t=0;t<8;t++)
  33.                     {                 
  34.                         if(temp&0x01) LCD_DrawPoint(x+t,y+pos,POINT_COLOR);
  35.                         temp>>=1;
  36.                     }
  37.                 }
  38.         }
  39.         POINT_COLOR=colortemp;                                          
  40. }

  41. void LCD_ShowString(unsigned int x,unsigned int y,const char *p)
  42. {         
  43.     while(*p!='\0')
  44.     {      
  45.         if(x>LCD_W-16){x=0;y+=16;}
  46.         if(y>LCD_H-16){y=x=0;}
  47.         LCD_ShowChar(x,y,*p,0);
  48.         x+=8;
  49.         p++;
  50.     }  
  51. }

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

图片2.png
图3 显示效果

您需要登录后才可以回帖 登录 | 注册

本版积分规则

525

主题

2959

帖子

39

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