锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

华大HC32F460 SPI 驱动 ST7735S LCD显示器

时间:2022-09-11 01:30:00 100pin矩形连接器

华大HC32F460 SPI 驱动 ST7735S LCD显示器

前言:

STM32改HC32F460 更换芯片后发现SPI硬件无法驱动屏幕。这个小问题已经解决了很长时间了。最后,使用逻辑分析仪分析顺序,然后解决它。解决方案是SPI发送字节数据后,硬件延迟.

CPU和LCD硬件连接

在这里插入图片描述

ST77735S 时序


4线SPI写入时序

GPIO模拟SPI时序数据的逻辑分析仪 时序没问题

硬件的第一次测量SPI时序数据出错 时序错误

硬件使用正常SPI时序

注意事项: SPI时钟用的是Pclk一点钟,我的主频是2000MHz Pclk1 是100MHz ,SPI 8分频 后是12.5MHz,

与以下代码中的发送后硬件延迟有很大关系.

#define LCD_WD(dat) SPI_SendData8(SPI_UNIT, dat);delay(50); 
/**************头文件引用******************/ #include "inc.h"  //#include "DEV_LCDFONT.h" //#include "DEV_PIC.h"  //模块名称 ///管脚定义 /* * LCD_RES PA07 //SPI1_MISO复位 * LCD_A0 PB00 // * LCD_SI PB01 (MOSI) SPI1_MOSI * LCD_SCL PB02 (SCLK) SPI1_SCK * LCD_CS PB10 SPI1_SS0 1--2 SPI1_MOSI SPI1_MISO SPI1_SS0 SPI1_SCK */ //SPI1  #define LCD_SPI1_ON //#define LCD_SPI1_OFF    ///模块功能 #define USE_HORIZONTAL 2 ///设置横屏或竖屏显示屏 0或1为竖屏 2或3为横屏   #if USE_HORIZONTAL==0||USE_HORIZONTAL==1 #define LCD_W 128 #define LCD_H 160  #else #define LCD_W 160 #define LCD_H 128 #endif #ifdef LCD_SPI1_OFF  #define SPI_LCD_SCL PortB,Pin02 #define SPI_LCD_SI PortB,Pin01 #define SPI_LCD_CS PortB,Pin10 #define SPI_LCD_A0 PortB,Pin00 #define SPI_LCD_RES PortA,Pin07 typedef enum { 
          LCD_RES, LCD_A0, LCD_SI, LCD_SCL, LCD_CS, LCD_ALL }LCD_TYPE; GPIO_STRUCT LCD_GPIO[LCD_ALL]= { 
          SPI_LCD_RES,Pin_Mode_Out,0,//LCD_RES  SPI_LCD_A0,Pin_Mode_Out,0,//LCD_A0  SPI_LCD_SI,Pin_Mode_Out,0,//LCD_SI  SPI_LCD_SCL,Pin_Mode_Out,0,//LCD_SCL  SPI_LCD_CS,Pin_Mode_Out,0 //LCD_CS  }; //-----------------LCD端口定义----------------  #define LCD_SCLK_Clr() PORT_ResetBits(SPI_LCD_SCL)//SCL=SCLK #define LCD_SCLK_Set() PORT_SetBits(SPI_LCD_SCL) #define LCD_MOSI_Clr() PORT_ResetBits(SPI_LCD_SI)//SDA=MOSI #define LCD_MOSI_Set() PORT_SetBits(SPI_LCD_SI) #define LCD_RES_Clr() PORT_ResetBits(SPI_LCD_RES)//RES #define LCD_RES_Set() PORT_SetBits(SPI_LCD_RES) #define LCD_DC_Clr() PORT_ResetBits(SPI_LCD_A0)//DC #define LCD_DC_Set() PORT_SetBits(SPI_LCD_A0) #define LCD_CS_Clr() PORT_ResetBits(SPI_LCD_CS)//CS #define LCD_CS_Set() PORT_SetBits(SPI_LCD_CS) #endif  #ifdef LCD_SPI1_ON #define SPI_LCD_SCL PortB,Pin02 #define SPI_LCD_SI PortB,Pin01 #define SPI_LCD_CS PortB,Pin10 #define SPI_LCD_A0 PortB,Pin00 #define SPI_LCD_RES PortA,Pin07 #define SPI_SCK_PORT (PortB)//(PortB) #define SPI_SCK_PIN (Pin02)//(Pin02) #define SPI_SCK_FUNC (Func_Spi1_Sck) /* SPI_MOSI Port/Pin definition */ #define SPI_MOSI_PORT (PortB)//(PortB) #define SPI_MOSI_PIN (Pin01)//(Pin01) #define SPI_MOSI_FUNC (Func_Spi1_Mosi) #define SPI_UNIT (M4_SPI1) #define SPI_UNIT_CLOCK (PWC_FCG1_PERIPH_SPI1) #define SPI_MASTER_MODE typedef enum { 
          LCD_RES, LCD_A0, LCD_CS, LCD_ALL }LCD_TYPE; GPIO_STRUCT LCD_GPIO[LCD_ALL]= { 
          SPI_LCD_RES,Pin_Mode_Out,0,//LCD_RES  SPI_LCD_A0,Pin_Mode_Out,0,//LCD_A0  SPI_LCD_CS,Pin_Mode_Out,0 //LCD_CS  }; #define LCD_RES_Clr() PORT_ResetBits(SPI_LCD_RES)//RES #define LCD_RES_Set() PORT_SetBits(SPI_LCD_RES) #define LCD_DC_Clr() PORT_ResetBits(SPI_LCD_A0)//DC #define LCD_DC_Set() PORT_SetBits(SPI_LCD_A0) #define LCD_CS_Clr() PORT_ResetBits(SPI_LCD_CS)//CS #define LCD_CS_Set() PORT_SetBits(SPI_LCD_CS) static void Spi_Config(void) { 
          stc_spi_init_t stcSpiInit; /* configuration structure initialization */ MEM_ZERO_STRUCT(stcSpiInit); /* Configuration peripheral clock */ PWC_Fcg1PeriphClockCmd(SPI_UNIT_CLOCK, Enable); /* Configuration SPI pin */ PORT_SetFunc(SPI_SCK_PORT, SPI_SCK_PIN, SPI_SCK_FUNC, Disable); PORT_SetFunc(SPI_MOSI_PORT, SPI_MOSI_PIN, SPI_MOSI_FUNC, Disable); /* Configuration SPI structure */ stcSpiInit.enClkDiv = SpiClkDiv8; stcSpiInit.enFrameNumber = SpiFrameNumber1; stcSpiInit.enDataLength = SpiDataLengthBit8; stcSpiInit.enFirstBitPosition = SpiFirstBitPositionMSB; stcSpiInit.enSckPolarity = SpiSckIdleLevelHigh;//空闲时是高电平 stcSpiInit.enSckPhase = SpiSckOddChangeEvenSample; stcSpiInit.enReadBufferObject = SpiReadReceiverBuffer; stcSpiInit.enWorkMode = SpiWorkMode3Line; stcSpiInit.enTransMode = SpiTransFullDuplex; stcSpiInit.enCommAutoSuspendEn = Disable; stcSpiInit.enModeFaultErrorDetectEn = Disable; stcSpiInit.enParitySelfDetectEn = Disable; stcSpiInit.enParityEn = Disable; stcSpiInit.enParity = SpiParityEven; #ifdef SPI_MASTER_MODE stcSpiInit.enMasterSlaveMode = SpiModeMaster; stcSpiInit.stcDelayConfig.enSsSetupDelayOption = SpiSsSetupDelayCustomValue; stcSpiInit.stcDelayConfig.enSsSetupDelayTime = SpiSsSetupDelaySck1; stcSpiInit.stcDelayConfig.enSsHoldDelayOption = SpiSsHoldDelayCustomValue; stcSpiInit.stcDelayConfig.enSsHoldDelayTime = SpiSsHoldDelaySck1; stcSpiInit.stcDelayConfig.enSsIntervalTimeOption = SpiSsIntervalCustomValue; stcSpiInit.stcDelayConfig.enSsIntervalTime = SpiSsIntervalSck6PlusPck2; #endif #ifdef SPI_SLAVE_MODE stcSpiInit.enMasterSlaveMode = SpiModeSlave; #endif SPI_Init(SPI_UNIT, &stcSpiInit); SPI_Cmd(SPI_UNIT, Enable); } #endif /****************************************************************************** 函数说明:LCD串行数据写入函数 入口数据:dat 要写入的串行数据 返回值: 无 ******************************************************************************/ #ifdef LCD_SPI1_OFF  void LCD_Writ_Bus(u8 dat) { 
          u8 i; LCD_CS_Clr(); for(i=0;i<8;i++) { 
          LCD_SCLK_Clr(); if(dat&0x80) { 
          LCD_MOSI_Set(); } else { 
          LCD_MOSI_Clr(); } LCD_SCLK_Set(); dat<<=1; } LCD_CS_Set(); } #endif #ifdef LCD_SPI1_ON void delay(int t) { 
          while(t--); } #define LCD_WD(dat) SPI_SendData8(SPI_UNIT, dat);delay(50); #endif /****************************************************************************** 函数说明:LCD写入数据 入口数据:dat 写入的数据 返回值: 无 ******************************************************************************/ void LCD_WR_DATA8(u8 dat) { 
          LCD_WD(dat); } /****************************************************************************** 函数说明:LCD写入数据 入口数据:dat 写入的数据 返回值: 无 ******************************************************************************/ void LCD_WR_DATA(u16 dat) { 
          LCD_WD(dat>>8); LCD_WD(dat); } //功能模块初始化 void DEV_LCD_Init(void) { 
          for(int i =LCD_RES;i <= LCD_CS;i++) { 
          rxm_w(DEV_GPIO,&LCD_GPIO[i],NULL); } } /****************************************************************************** 函数说明:LCD写入命令 入口数据:dat 写入的命令 返回值: 无 ******************************************************************************/ void LCD_WR_REG(u8 dat) { 
          LCD_DC_Clr();//写命令 LCD_WR_DATA8(dat); LCD_DC_Set();//写数据 } /****************************************************************************** 函数说明:设置起始和结束地址 入口数据:x1,x2 设置列的起始和结束地址 y1,y2 设置行的起始和结束地址 返回值: 无 ******************************************************************************/ void LCD_Address_Set(u16 x1,u16 y1,u16 x2,u16 y2) { 
          if(USE_HORIZONTAL==0) { 
          LCD_WR_REG(0x2a);//列地址设置 LCD_WR_DATA(x1+2); LCD_WR_DATA(x2+2); LCD_WR_REG(0x2b);//行地址设置 LCD_WR_DATA(y1+1); LCD_WR_DATA(y2+1); LCD_WR_REG(0x2c);//储存器写 } else if(USE_HORIZONTAL==1) { 
          LCD_WR_REG(0x2a);//列地址设置 LCD_WR_DATA(x1+2); LCD_WR_DATA(x2+2); LCD_WR_REG(0x2b);//行地址设置 LCD_WR_DATA(y1+1); LCD_WR_DATA(y2+1); LCD_WR_REG(0x2c);//储存器写 } else if(USE_HORIZONTAL==2) { 
          LCD_WR_REG(0x2a);//列地址设置 LCD_WR_DATA(x1+1); LCD_WR_DATA(x2+1); LCD_WR_REG(0x2b);//行地址设置 LCD_WR_DATA(y1+2); LCD_WR_DATA(y2+2); LCD_WR_REG(0x2c);//储存器写 } else { 
          LCD_WR_REG(0x2a);//列地址设置 LCD_WR_DATA(x1+1); LCD_WR_DATA(x2+1); LCD_WR_REG(0x2b);//行地址设置 LCD_WR_DATA(y1+2); LCD_WR_DATA(y2+2); LCD_WR_REG(0x2c);//储存器写 } } void delay_ms(u16 time) { 
          Ddl_Delay1ms(time); } void LCD_BLK_Set(void) { 
          rxm_io(DEV_OUTPUT,BLED,1); } void LCD_Init(void) { 
          DEV_LCD_Init();//初始化GPIO #ifdef LCD_SPI1_ON Spi_Config(); //SPI初始化 #endif  LCD_RES_Clr();//复位 delay_ms(100); LCD_RES_Set(); delay_ms(100); LCD_BLK_Set(); //打开背光 delay_ms(100); LCD_CS_Clr(); //************* Start Initial Sequence **********// LCD_WR_REG(0x11); //Sleep out  delay_ms(120); //Delay 120ms  //------------------------------------ST7735S Frame Rate-----------------------------------------//  LCD_WR_REG(0xB1); LCD_WR_DATA8(0x05); LCD_WR_DATA8(0x3C); LCD_WR_DATA8(0x3C); LCD_WR_REG(0xB2); LCD_WR_DATA8(0x05); LCD_WR_DATA8(0x3C); LCD_WR_DATA8(0x3C); LCD_WR_REG(0xB3); LCD_WR_DATA8(0x05); LCD_WR_DATA8(0x3C); LCD_WR_DATA8(0x3C); LCD_WR_DATA8(0x05); LCD_WR_DATA8(0x3C); LCD_WR_DATA8(0x3C); //------------------------------------End ST7735S Frame Rate---------------------------------//  LCD_WR_REG(0xB4); //Dot inversion  LCD_WR_DATA8(0x03); //------------------------------------ST7735S Power Sequence---------------------------------//  LCD_WR_REG(0xC0); LCD_WR_DATA8(0x28); LCD_WR_DATA8(0x08); LCD_WR_DATA8(0x04); LCD_WR_REG(0xC1); LCD_WR_DATA8(0XC0); LCD_WR_REG(0xC2); LCD_WR_DATA8(0x0D); LCD_WR_DATA8(0x00); LCD_WR_REG(0xC3); LCD_WR_DATA8(0x8D); LCD_WR_DATA8(0x2A); LCD_WR_REG(0xC4); LCD_WR_DATA8(0x8D); LCD_WR_DATA8(0xEE); //---------------------------------End ST7735S Power Sequence-------------------------------------//  LCD_WR_REG(0xC5); //VCOM  LCD_WR_DATA8(0x1A); LCD_WR_REG(0x36); //MX, MY, RGB mode  if(USE_HORIZONTAL==0)LCD_WR_DATA8(0x00); else if(USE_HORIZONTAL==1)LCD_WR_DATA8(0xC0); else if(USE_HORIZONTAL==2)LCD_WR_DATA8(0x70); else LCD_WR_DATA8(0xA0); //------------------------------------ST7735S Gamma Sequence---------------------------------//  LCD_WR_REG(0xE0); LCD_WR_DATA8(0x04); LCD_WR_DATA8(0x22); LCD_WR_DATA8(0x07); LCD_WR_DATA8(0x0A); LCD_WR_DATA8(0x2E); LCD_WR_DATA8(0x30); LCD_WR_DATA8(0x25); LCD_WR_DATA8(0x2A); LCD_WR_DATA8(0x28); LCD_WR_DATA8(0x26); LCD_WR_DATA8(0x2E); LCD_WR_DATA8(0x3A); LCD_WR_DATA8(0x00); LCD_WR_DATA8(0x01); LCD_WR_DATA8(0x03); LCD_WR_DATA8(0x13); LCD_WR_REG(0xE1); LCD_WR_DATA8(0x04); LCD_WR_DATA8(0x16); LCD_WR_DATA8( 

相关文章