STM32并口屏应用实例:点亮你的显示世界之原理篇

系列内容章节如下:
STM32并口屏应用实例:点亮你的显示世界之原理篇
STM32并口屏应用实例:点亮你的显示世界之程序篇
STM32并口屏应用实例:点亮你的显示世界之应用篇


  在嵌入式系统开发中,显示设备是与用户交互的重要界面之一。STM32作为一款功能强大的微控制器,支持多种外设接口,其中并口屏的驱动应用非常广泛,其抗干扰性比其他接口更为出色。本文将通过一个实际案例,介绍如何使用STM32驱动并口屏,并展示其原理和实现过程。

一、并口屏简介

  并口屏是一种通过并行数据线与控制器连接的显示屏,常见的有TFT-LCD屏。与串行接口相比,并口屏的数据传输速度快,适合高分辨率和高刷新率的应用场景。例如,8位并口屏通过8根数据线同时传输数据,大大提高了通信效率。

二、硬件连接

  以STM32F103VET6为例,我们使用其GPIO端口连接一个8位并口的液晶显示屏(如ST75256/JLX25664,256*64像素点)。以下是硬件连接的要点:

  1. 数据线连接将TFT屏的8位数据线(D0-D7)分别连接到STM32的GPIO端口(如PD9-PD15、PC6)。

  2. 控制信号连接
    • CS(片选信号):连接到STM32的一个GPIO引脚(如PB12)。
    • RS(寄存器选择信号):连接到另一个GPIO引脚(如PD8)。
    • WR(写信号):连接到GPIO引脚(如PB15)。
    • RD(读信号):连接到GPIO引脚(如PB14),本例中暂不使用。
    • RST(复位信号):连接到GPIO引脚(如PB13)。
    • BLK(背光控制):连接到GPIO引脚(如PB9),可通过PWM控制背光亮度,本例中暂不使用。

  3. 电源连接
    确保TFT屏的电源供电稳定,通常需要3.3V或5V电源。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

三、参考程序

3.1 IO驱动代码

  通过IO控制宏来实现对LCD的控制端口电平的控制。其中,并口数据写入8位数据,每个bit位对应D0-D7。

/********************************************************************************************************
函数名称: 	Drv_LCD_CS          
功能描述: 	
输 入:   	无
输 出:   	无                 
*********************************************************************************************************/
void Drv_LCD_CS(uint8_t cmd)
{
	if(LCD_ENABLE == cmd)
	{
		BSP_LCD_CS_ON_ENABLE;
	}
	else if(LCD_DISENABLE == cmd)
	{
		BSP_LCD_CS_OFF_ENABLE;
	}
}

/*********************************************************************************************************
函数名称: 	Drv_LCD_Reset          
功能描述: 	
输 入:   	无
输 出:   	无                 
*********************************************************************************************************/
void Drv_LCD_Reset(uint8_t cmd)
{
	if(LCD_ENABLE == cmd)
	{
		BSP_LCD_RESET_ON_ENABLE;
	}
	else if(LCD_DISENABLE == cmd)
	{
		BSP_LCD_RESET_OFF_ENABLE;
	}
}

/*****************************************************************************************************
函数名称: 	Drv_LCD_RD          
功能描述: 	
输 入:   	无
输 出:   	无                 
*****************************************************************************************************/
void Drv_LCD_RD(uint8_t cmd)
{
	if(LCD_ENABLE == cmd)
	{
		BSP_LCD_RD_ON_ENABLE;
	}
	else if(LCD_DISENABLE == cmd)
	{
		BSP_LCD_RD_OFF_ENABLE;
	}
}

/********************************************************************************************************
函数名称: 	Drv_LCD_WR          
功能描述: 	
输 入:   	无
输 出:   	无                 
******************************************************************************************************/
void Drv_LCD_WR(uint8_t cmd)
{
	if(LCD_ENABLE == cmd)
	{
		BSP_LCD_WR_ON_ENABLE;
	}
	else if(LCD_DISENABLE == cmd)
	{
		BSP_LCD_WR_OFF_ENABLE;
	}
}

/*******************************************************************************************************
函数名称: 	Drv_LCD_RS          
功能描述: 	
输 入:   	无
输 出:   	无                 
****************************************************************************************************/
void Drv_LCD_RS(uint8_t cmd)
{
	if(LCD_ENABLE == cmd)
	{
		BSP_LCD_RS_ON_ENABLE;
	}
	else if(LCD_DISENABLE == cmd)
	{
		BSP_LCD_RS_OFF_ENABLE;
	}
}

/*********************************************************************************************************
函数名称: 	Drv_LCD_TX          
功能描述: 	
输 入:   	无
输 出:   	无                 
********************************************************************************************************/
void Drv_LCD_TX(uint8_t data)
{
	BSP_LCD_D0((GPIO_PinState)((data)&0x01));
	BSP_LCD_D1((GPIO_PinState)((data>>1)&0x01));
	BSP_LCD_D2((GPIO_PinState)((data>>2)&0x01));
	BSP_LCD_D3((GPIO_PinState)((data>>3)&0x01));	
	BSP_LCD_D4((GPIO_PinState)((data>>4)&0x01));
	BSP_LCD_D5((GPIO_PinState)((data>>5)&0x01));
	BSP_LCD_D6((GPIO_PinState)((data>>6)&0x01));	
	BSP_LCD_D7((GPIO_PinState)((data>>7)&0x01));
}

3.2 LCD初始化程序和命令/数据写入接口

命令写入

static void Api_transfer_cmd_lcd(uint8_t cmd)
{
	Drv_LCD_CS(LCD_DISENABLE);
	Drv_LCD_RS(LCD_DISENABLE);
	Drv_LCD_RD(LCD_DISENABLE);
	Drv_LCD_WR(LCD_DISENABLE);
	Drv_LCD_TX(cmd);
	Drv_LCD_RD(LCD_ENABLE);
	Drv_LCD_CS(LCD_ENABLE);
	Drv_LCD_RD(LCD_DISENABLE);
	Drv_LCD_TX(0x00);
}

数据写入

static void Api_transfer_data_lcd(uint8_t data)
{
	Drv_LCD_CS(LCD_DISENABLE);
	Drv_LCD_RS(LCD_ENABLE);
	Drv_LCD_RD(LCD_DISENABLE);
	Drv_LCD_WR(LCD_DISENABLE);
	Drv_LCD_TX(data);
	Drv_LCD_RD(LCD_ENABLE);
	Drv_LCD_CS(LCD_ENABLE);
	Drv_LCD_RD(LCD_DISENABLE);
	Drv_LCD_TX(0x00);
}

LCD初始化

void Api_init_lcd(void)
{
	Drv_LCD_Reset(LCD_DISENABLE);
	osDelay(100);
	Drv_LCD_Reset(LCD_ENABLE);
	osDelay(100);
	
	Api_transfer_cmd_lcd(0x30);
	Api_transfer_cmd_lcd(0x94);
	Api_transfer_cmd_lcd(0x31);	
	Api_transfer_cmd_lcd(0xD7);		
	Api_transfer_data_lcd(0x9F);
	
	Api_transfer_cmd_lcd(0x32);
	Api_transfer_data_lcd(0x00);
	Api_transfer_data_lcd(0x01);
	Api_transfer_data_lcd(0x05);
	
	Api_transfer_cmd_lcd(0x20);	
	Api_transfer_data_lcd(0x01);	
	Api_transfer_data_lcd(0x03);
	Api_transfer_data_lcd(0x05);	
	Api_transfer_data_lcd(0x07);	
	Api_transfer_data_lcd(0x09);	
	Api_transfer_data_lcd(0x0B);
	Api_transfer_data_lcd(0x0D);	
	Api_transfer_data_lcd(0x10);	
	Api_transfer_data_lcd(0x11);
	Api_transfer_data_lcd(0x13);	
	Api_transfer_data_lcd(0x15);
	Api_transfer_data_lcd(0x17);
	Api_transfer_data_lcd(0x19);	
	Api_transfer_data_lcd(0x1B);
	Api_transfer_data_lcd(0x1D);
	Api_transfer_data_lcd(0x1F);	
	
	Api_transfer_cmd_lcd(0x30);
	Api_transfer_cmd_lcd(0x75);
	Api_transfer_data_lcd(0x00);
	Api_transfer_data_lcd(0xFF);

	Api_transfer_cmd_lcd(0x15);
	Api_transfer_data_lcd(0x00);
	Api_transfer_data_lcd(0xFF);

	Api_transfer_cmd_lcd(0xBC);
	Api_transfer_data_lcd(0x00);
	Api_transfer_data_lcd(0xA6);
	
	Api_transfer_data_lcd(0x0C);

	Api_transfer_cmd_lcd(0xCA);
	Api_transfer_data_lcd(0x00);
	Api_transfer_data_lcd(0x3F);
	Api_transfer_data_lcd(0x20);

	Api_transfer_cmd_lcd(0xF0);
	Api_transfer_data_lcd(0x10);
	
	Api_transfer_cmd_lcd(0x81);
	Api_transfer_data_lcd(0x12);	
	Api_transfer_data_lcd(0x02);	

	Api_transfer_cmd_lcd(0x20);	
	Api_transfer_data_lcd(0x0B);	
	osDelay(1);
	
	Api_transfer_cmd_lcd(0xAF);
}

  其中的命令和命令数据请参照对应的LCD规格书。一般初始化程序会有参考代码,只不过应用的芯片不一样,需要根据我们自己使用的芯片去实现命令写入和数据写入的代码,达到我们需要的控制需求。
在这里插入图片描述

3.3 显示程序设计

  因为显示内容包含中文、英文、特殊字符;显示内容还有字号大小的区分,根据我们的具体显示需求通过设计对应的显示接口(PS:项目开需求/时间发导向性: 一般的网上会有一些通用的接口,显示的时候通过传入字号大小去匹配显示对应字符字库,如果时间和MCU空间能够满足,也可以去这么做。但是一般的项目中对字体调节的需求不大,而且调试通用函数费时费力,有兴趣的可以自己开发玩一玩)。

3.3.1 显示原理

  请留意页的定义:PAGE,与平时所讲的“页”并不是一个意思,在此表示 8 个行就是一个“页”,
一个个 256*64 点阵的屏分为 8 个“页”,从第 0“页”到第 7“页”。
  DB7–DB0 的排列方向:数据是从下向上排列的。最低位 D0 是在最上面,最高位 D7 是在最下面。
每一位(bit)数据对应一个点阵,通常“1”代表点亮该点阵,“0”代表关掉该点阵.如下图所示:
在这里插入图片描述
  整个LCD显示屏就是由这些页(像素点阵)组成。
在这里插入图片描述
  所以,显示原理就是通过工具降我们要显示的字符转换成点阵数据,然后通过显示接口将显示内容写入到对应的页和列。
在这里插入图片描述

3.3.2 显示示例

   进一步的,通过在LCD的页,列坐标上写入定义好的数据,将会显示出我们需要的内容。程序设计将在下一章STM32并口屏应用实例:点亮你的显示世界之程序篇内容中作详细讲解分析。

char cmd_str[20];

Api_display_string_8x16(type,  20, 1, (uchar *)"4.");
Api_display_label_16x16(type,  36, 1, AlarmInfo16x16, sizeof(AlarmInfo16x16)/32);
Api_display_string_8x16(type, 100, 1, (uchar *)":");
Api_display_label_16x16(type, 134, 1, AlarmNONE16x16, sizeof(AlarmNONE16x16)/32);

Api_display_string_8x16(type, 20, 3, (uchar *)"5.ModSta1 :");
memset(cmd_str, 0, 20);
snprintf(cmd_str, 20, "0x%08X", pSt_DisPara.pU32_DCstatus1);
Api_display_string_8x16(type, 118, 3, (uchar *)cmd_str);

Api_display_string_8x16(type, 20, 5, (uchar *)"6.ModSta2 :");
memset(cmd_str, 0, 20);
snprintf(cmd_str, 20, "0x%08X", pSt_DisPara.pU32_DCstatus2)

四、效果展示

  通过上述代码,我们成功驱动了8位并口的液晶屏,实现了参数的显示。如下:

特殊符号显示
中英文字符串显示
十六进制数据显示
十进制数据显示

在这里插入图片描述

五、总结

  本文通过一个实际案例,展示了如何使用STM32驱动8位并口屏。通过硬件连接和软件编程,我们实现了屏幕的初始化、数据传输和显示功能。并口屏以其快速的数据传输能力,在嵌入式显示领域具有广泛的应用前景。希望本文能为你的项目提供参考和启发。

  一般LCD都会设计多种通信接口,例如,在我们示例中所应用的JLX25664有设计IIC接口、4线SPI接口,并口包括6800和8080系列的并口,区别只是在通信调用接口不同,寄存器地址和寄存器数据控制写入的逻辑大差不差,需要的可进一步阅读LCD规格书。如果自己找不到的话需要的可以联系交流。

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Geek__1992

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值