本帖最后由 jinglixixi 于 2023-12-22 23:22 编辑
前面介绍了驱动LCD屏的方法,稍有不足的是它的屏幕尺寸比较小,且引脚不便直接Arduino接口来使用。为此,这里选取了一款2.2寸TFT屏作为测试目标,其显示分辨率为320*240,采用SPI方式工作。 为进行测试,该显示屏与开发板的连接关系为: CS---PA5 RST---PA6 D/C---PA7 SDA---PD14 SCL---PD15 BLK---PF12 对使用引脚的工作模式配置函数为: void Init_lcd(void)
{
GPIO_InitTypeDefGPIO_InitStruct;
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
__HAL_RCC_GPIOD_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_14|GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
__HAL_RCC_GPIOF_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
}
为输出高低电平所作的语句定义为: #define OLED_CS_Set() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5,GPIO_PIN_SET) #define OLED_CS_Clr() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5,GPIO_PIN_RESET) #define OLED_RST_Set() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6,GPIO_PIN_SET) #define OLED_RST_Clr() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6,GPIO_PIN_RESET) #define OLED_DC_Set() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_SET) #define OLED_DC_Clr() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7,GPIO_PIN_RESET) #define OLED_SDIN_Set() HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14,GPIO_PIN_SET) #define OLED_SDIN_Clr() HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14,GPIO_PIN_RESET) #define OLED_SCLK_Set() HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15,GPIO_PIN_SET) #define OLED_SCLK_Clr() HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15,GPIO_PIN_RESET) #define OLED_BLK_Set() HAL_GPIO_WritePin(GPIOF, GPIO_PIN_12,GPIO_PIN_SET) 该显示屏的初始化函数为: voidLcd_Init(void)
{
OLED_RST_Clr();
HAL_Delay(20);
OLED_RST_Set();
HAL_Delay(20);
LCD_WR_REG(0xCB);
LCD_WR_DATA8(0x39);
LCD_WR_DATA8(0x2C);
LCD_WR_DATA8(0x00);
LCD_WR_DATA8(0x34);
LCD_WR_DATA8(0x02);
LCD_WR_REG(0xCF);
LCD_WR_DATA8(0x00);
LCD_WR_DATA8(0XC1);
LCD_WR_DATA8(0X30);
LCD_WR_REG(0xE8);
LCD_WR_DATA8(0x85);
LCD_WR_DATA8(0x00);
LCD_WR_DATA8(0x78);
LCD_WR_REG(0xEA);
LCD_WR_DATA8(0x00);
LCD_WR_DATA8(0x00);
LCD_WR_REG(0xED);
LCD_WR_DATA8(0x64);
LCD_WR_DATA8(0x03);
LCD_WR_DATA8(0X12);
LCD_WR_DATA8(0X81);
LCD_WR_REG(0xF7);
LCD_WR_DATA8(0x20);
LCD_WR_REG(0xC0);
LCD_WR_DATA8(0x23);
LCD_WR_REG(0xC1);
LCD_WR_DATA8(0x10);
LCD_WR_REG(0xC5);
LCD_WR_DATA8(0x3e);
LCD_WR_DATA8(0x28);
LCD_WR_REG(0xC7);
LCD_WR_DATA8(0x86);
LCD_WR_REG(0x36);
LCD_WR_DATA8(0x48);
LCD_WR_REG(0x3A);
LCD_WR_DATA8(0x55);
LCD_WR_REG(0xB1);
LCD_WR_DATA8(0x00);
LCD_WR_DATA8(0x18);
LCD_WR_REG(0xB6);
LCD_WR_DATA8(0x08);
LCD_WR_DATA8(0x82);
LCD_WR_DATA8(0x27);
LCD_WR_REG(0xF2);
LCD_WR_DATA8(0x00);
LCD_WR_REG(0x26);
LCD_WR_DATA8(0x01);
LCD_WR_REG(0xE0);
LCD_WR_DATA8(0x0F);
LCD_WR_DATA8(0x31);
LCD_WR_DATA8(0x2B);
LCD_WR_DATA8(0x0C);
LCD_WR_DATA8(0x0E);
LCD_WR_DATA8(0x08);
LCD_WR_DATA8(0x4E);
LCD_WR_DATA8(0xF1);
LCD_WR_DATA8(0x37);
LCD_WR_DATA8(0x07);
LCD_WR_DATA8(0x10);
LCD_WR_DATA8(0x03);
LCD_WR_DATA8(0x0E);
LCD_WR_DATA8(0x09);
LCD_WR_DATA8(0x00);
LCD_WR_REG(0XE1);
LCD_WR_DATA8(0x00);
LCD_WR_DATA8(0x0E);
LCD_WR_DATA8(0x14);
LCD_WR_DATA8(0x03);
LCD_WR_DATA8(0x11);
LCD_WR_DATA8(0x07);
LCD_WR_DATA8(0x31);
LCD_WR_DATA8(0xC1);
LCD_WR_DATA8(0x48);
LCD_WR_DATA8(0x08);
LCD_WR_DATA8(0x0F);
LCD_WR_DATA8(0x0C);
LCD_WR_DATA8(0x31);
LCD_WR_DATA8(0x36);
LCD_WR_DATA8(0x0F);
LCD_WR_REG(0x11);
HAL_Delay(120);
LCD_WR_REG(0x29);
LCD_WR_REG(0x2c);
OLED_BLK_Set();
}
以模拟方式发送字节数据的函数为: voidLCD_Writ_Bus(u8 dat)
{
u8i;
OLED_CS_Clr();
for(i=0;i<8;i++)
{
if(dat&0x80)
OLED_SDIN_Set();
else
OLED_SDIN_Clr();
dat<<=1;
Delay_Us(2);
OLED_SCLK_Clr();
Delay_Us(2);
OLED_SCLK_Set();
}
OLED_CS_Set();
}
以指定色彩清除屏幕的函数为: voidLCD_Clear(u16 Color)
{
u16i,j;
LCD_Address_Set(0,0,LCD_W-1,LCD_H-1);
for(i=0;i<LCD_W;i++)
{
for (j=0;j<LCD_H;j++)
{
LCD_WR_DATA(Color);
}
}
}
在使用色彩清屏函数进行测试的情况下,证明以上函数可以驱动该显示屏。 随后,又为其配置了字符串和图像函数。
其字符串显示函数为: voidLCD_ShowString(u16 x,u16 y,const u8 *p,u16 color)
{
while(*p!='\0')
{
if(x>LCD_W-16) {x=0;y+=16;}
if(y>LCD_H-16) {y=x=0;LCD_Clear(RED);}
LCD_ShowChar(x,y,*p,0,color);
x+=8;
p++;
}
}
其图像显示函数为: voidLCD_ShowPicture(u16 x1,u16 y1,u16 x2,u16 y2)
{
inti;
LCD_Address_Set(x1,y1,x2,y2);
for(i=0;i<12800;i++)
{
LCD_WR_DATA8(gImage_RW[i*2]);
LCD_WR_DATA8(gImage_RW[i*2+1]);
}
}
实现图1显示效果的主程序为: int main(void)
{
HAL_Init();
SystemClock_Config();
SystemPower_Config();
MX_ICACHE_Init();
Init_lcd ();
Lcd_Init();
BACK_COLOR=RED;
LCD_Clear(RED);
LCD_ShowString(20,5,"NUCLEO-U5A5ZJ-Q",YELLOW);
LCD_ShowString(20,25,"0.96'LCD",YELLOW);
LCD_ShowString(20,50,"jinglixixi",YELLOW);
LCD_ShowPicture(20,120,179,199);
while (1);
}
图1 显示效果 前面为了进行测试是采用飞线的方式来连接显示屏,那直接将显示屏插入Arduino接口能使显示屏工作吗? 回答是不能,由图2可知在通常情况下VREFP引脚是连接3.3V参考电压的,但对于该开发板它是悬空状态,且连接到了CN12的引脚4。
为了能给显示屏提供3.3V的工作电源,只需给CN12的引脚4接上3.3V电源即可。 图2 Arduino接口
在为显示屏提供工作电源后,其测试效果如图3所示。这样终于可以有效地减少连线的麻烦了,且提高了工作的可靠性。 图3 测试效果
|