本帖最后由 jinglixixi 于 2025-8-11 20:28 编辑
#申请原创#
前面介绍了以软件模拟的方式来驱动LCD屏,有了其成功的基础再来尝试硬件的驱动方式就方便了许多,因为硬件驱动的主要工作就是配置SPI的初始化函数及变更SPI发送字节数据的函数就,其他的基本无需进行调整。
为了驱动LCD显示屏,这里使用的是接口SPI1,相应的引脚连接关系为: CLK ---PA1 MOSI---PA7 DC ---PC7 CS ---PC9 RST---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);
- }
以指定色彩填充屏幕的函数为: - void Lcd_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 显示效果
|