蓝桥杯—STM32G431RBT6(LCD的液晶显示,由原理及实践,配置及lcd函数)
目录
一、LCD的原理(了解)
LCD属性
OLED与LCD对比
二、使用步骤
1.引入库
2.代码部分
code.c(含详解)
code.h
main.c
效果展示
开源代码:
一、LCD的原理(了解)
LCD属性
LCD 是英文 “Liquid Crystal Display” 的缩写,中文名为 “液晶显示屏”。它是一种采用液晶控制透光度技术来实现色彩显示的设备。
- LCD 由上下电极基板之间封装的液晶材料构成。液晶分子在不加电时平行排列,上下扭曲 90°。外部入射光经过上偏振片后形成偏振光,通过平行排列的液晶材料后被旋转 90°,然后通过与上偏振片垂直的下偏振片,此时偏振光被反射板反射回来,呈现透明状态。
- 当上下电极加上一定电压时,液晶分子在电极部分转变为垂直排列,失去旋光性,从上偏振片射入的偏振光不会被旋转,光无法通过下偏振片返回,因此呈现黑色。通过在电极上制作各种文字、数字、图形,改变电压来控制液晶分子的排列,就能实现各种状态的显示。
- 结构组成2:
- 液晶面板:包括偏振膜(分为上偏光片和下偏光片,作用类似于栅栏,根据需求阻隔光波的不同分量)、玻璃基板(分为上基板和下基板,用于夹持液晶材料)、黑色矩阵(用于分隔彩色滤光片中的红、绿、蓝三原色,防止色彩混淆和光线泄漏,也可隐藏内部电极走线或薄膜晶体管)、彩色滤光片(产生红、绿、蓝三种基色光,实现全彩色显示)、取向膜(使液晶分子能够在微观尺寸的层面上实现均匀的排列和取向)、透明电极(分为公共电极和像素电极,输入信号电压加载在两者之间)、液晶层等。
- 背光模组:LCD 产品本身不发光,必须依赖背光模组中的光源发射才能获得显示性能。背光模块包括照明光源(主要有冷阴极荧光灯和发光二极管光源)、反射板(将光源发出的光线完全引导至导光板,减少能量损失)、导光板(将侧面光源发出的光线引导到面板的正面)、扩散片(将背光模组的侧光修正为均匀的面光源,实现光学扩散效果)、棱镜片(通过折射和全反射,将散射光线聚集到特定的角度,实现屏幕增亮的显示效果)及框架等。
- 分类方式1:
- 按使用和显示内容分类2:
- 字段式:与 LED 数码显示器有些相同,由长条笔划状或一些特殊固定图形与汉字显示像素组成,常见的是 7 段显示器,特殊图形与字符类的段型液晶显示屏一般要到生产厂家定做,在数字仪表、计数器、家电产品中应用较多。
- 点阵字符式:一般是一个功能模块,由小面积的液晶显示屏和驱动电路组合而成。模块中内置有 192 种字符、数字、字母、标点符号等可显示的字型点阵图形库,提供可控制的并行或串行接口以及通信协议。市场上常见的通用液晶显示器有 1 行、2 行和 4 行,每行可显示 8、12、16、24 或 32 个 5×7 点阵字符。
- 点阵图形式:具有比点阵式液晶显示器更大的显示面积,点阵的大小从 80×32 到 1024×768 不等。具有良好的显示灵活性和较大的自由度,可以显示各种图形、字符和汉字等,但控制较为复杂,硬件连线较多,占用单片机的资源也较多。
- 按物理结构分类:主要有 TN(Twisted Nematic,扭曲向列型)、STN(Super Twisted Nematic,超扭曲向列型)、DSTN(Double-layer Super Twisted Nematic,双层超扭曲向列型)和 TFT(Thin Film Transistor,薄膜晶体管型)等。其中,TFT-LCD 是目前的主流显示技术,具有视角大、温度范围广等优点。
- 优点:
- 画质清晰:能够呈现出高分辨率、高清晰度的图像和文字,画面效果好,无变形情况产生。
- 能耗低:相比其他显示技术,如阴极射线管(CRT)显示器,LCD 的能耗较低,比较省电,适合于各种便携式电子设备1。
- 无辐射:对人体健康的影响较小,长时间使用也不会对人体造成明显的伤害2。
- 体积小、重量轻:便于携带和安装,适用于各种空间有限的场合,如笔记本电脑、平板电脑、智能手机等1。
- 寿命长:在正常使用情况下,LCD 的使用寿命较长,能够稳定工作较长时间。
- 缺点:
- 色彩表现相对较弱:与 OLED 等新型显示技术相比,LCD 的色彩饱和度和对比度相对较低,颜色不够鲜艳。
- 视角有限:在较大的视角下,LCD 的显示效果会受到一定的影响,可能会出现颜色失真、亮度降低等问题。
- 响应时间较长:对于快速运动的图像,LCD 的响应速度可能不够快,容易出现拖影现象。
- 存在漏光问题:由于背光层的存在,LCD 屏幕在一些情况下可能会出现漏光现象,一般会从屏幕和边框的缝隙间露出。
OLED与LCD对比
OLED 与 LCD 在多个方面存在区别:
- 发光原理:
- OLED:有机发光二极管,通过有机材料涂层通电后自发光,每个像素都能独立发光、控光,无需背光源。
- LCD:液晶显示屏,本身不发光,依靠底层白色背光板照射,通过液晶分子的扭曲向列产生电场效应来控制光的通过和阻挡,从而显示图像。
- 厚度与重量:
- OLED:更轻薄,因无需背光源和液晶层,可使设备做得更薄,且重量轻,利于实现产品轻薄化设计,如轻薄手机、可穿戴设备等。
- LCD:由于有背光板等结构,整体厚度较厚,在一些对厚度要求高的设备中应用受限。
- 对比度:
- OLED:对比度高,能实现深邃的黑色和明亮的白色,黑色区域像素可完全关闭不发光,呈现纯粹黑色,使画面更鲜明、通透,层次感强,在显示暗场景或高对比度图像时优势明显。
- LCD:相比之下对比度较低,背光源发光使黑色显示不够纯粹,呈现灰色,影响画面的对比度和视觉效果,暗处细节表现可能欠佳。
- 视角1:
- OLED:视角广,从不同角度观看,图像质量基本保持不变,色彩和亮度的衰减较小,在多人同时观看或大角度观看场景下能提供良好视觉体验。
- LCD:视角相对较窄,偏离正面视角较大时,亮度、色彩和对比度会有明显下降,影响观看效果。
- 响应时间123:
- OLED:响应时间短,像素点的发光和熄灭切换速度快,能有效减少运动模糊和残影现象,在显示动态画面,如快速运动的视频、游戏等场景时,画面更清晰、流畅。
- LCD:响应时间较长,液晶分子的转动和响应速度相对较慢,在快速切换画面时容易产生拖影,影响视觉体验。
- 能耗123:
- OLED:能耗较低,特别是在显示黑色或深色画面时,像素点不发光,可大幅降低电量消耗;但在高亮度显示全白画面等特定场景下,由于每个像素都处于高亮度工作状态,能耗可能较高。
- LCD:无论显示什么内容,背光源都需持续工作,且存在一定的光透过和能量损耗,整体能耗相对较高。不过在一些低亮度使用场景下,能耗差异可能不明显。
- 色彩表现:
- OLED:色彩鲜艳、饱和度高,色域广,能呈现更丰富、生动的色彩,具有更好的色彩还原能力,在显示色彩丰富的图像和视频时视觉冲击力强。
- LCD:色彩表现相对较为平实,虽然近年来技术不断进步,高端 LCD 屏幕的色彩表现也有很大提升,但在色彩鲜艳度和饱和度方面通常仍不及 OLED。
- 寿命:
- OLED:早期存在寿命较短的问题,有机材料的发光效率和稳定性随使用时间增长会逐渐下降,可能出现烧屏现象,即屏幕长时间显示某个静态图像后,该图像的残影会永久留在屏幕上。不过,随着技术改进,OLED 的寿命已得到一定提升。
- LCD:一般使用无机材料,寿命相对较长,正常使用情况下,屏幕老化和性能衰减速度较慢,出现烧屏等问题的概率较低。
- 价格:
- OLED:制造成本较高,生产工艺复杂,且良品率相对较低,尤其是高端 OLED 屏幕,导致其价格普遍较高,常用于高端电子设备。
- LCD:技术成熟,生产规模大,成本相对较低,价格较为亲民,在中低端电子设备中应用广泛。
- 柔韧性:
- OLED:柔韧性好,可实现弯曲、折叠等形态,为设计创新提供更多可能,如曲面屏、折叠屏手机等产品。
- LCD:由于液晶层和背光层的存在,柔韧性较差,难以实现大幅度弯曲,设计形态相对受限。
- 频闪问题:
- OLED:在低亮度下,大多采用低频 PWM 调光方式,通过屏幕亮灭交替来调节亮度,虽然肉眼难以察觉频闪,但可能会导致部分人眼疲劳、偏头痛等问题。
- LCD:通常采用 DC 调光或高频 PWM 调光,在正常使用情况下,频闪现象相对不明显,对人眼的影响较小。
二、使用步骤
1.引入库
STM32CUBEMX将引脚配置如下图:
2.代码部分
LCD常用函数
void LCD_SetTextColor(vu16 Color); //LCD字体的颜色
void LCD_SetBackColor(vu16 Color); //LCD背景板的颜色
void LCD_ClearLine(u8 Line); // 清除行
void LCD_DisplayStringLine(u8 Line, u8 *ptr); //在指定行显示字符串
line行号,一共10行 line0-line9
sprintf()
函数将格式化后的内容填充到一个指定的字符数组中,而不是直接输出到屏幕等输出设备。而printf()
主要用于将格式化后的信息输出到标准输出设备(如屏幕)。(需要添加头文件stdio.h),与display string line搭配使用。
buffer
通常是指缓冲区,用于存储数据;
format
是格式字符串,指定了输出的格式;
[argument]
是要格式化的参数。
格式化输出是指按照特定的格式规则,将数据以一定的样式呈现出来的输出方式。通过格式化输出,可以使数据更具可读性和规范性,例如指定数字的显示位数、小数点位置,字符串的对齐方式等。常见的格式化输出函数如 printf()
、sprintf()
等。比如说,要将一个整数以特定的格式输出,如显示为带有前导零的四位数字,这就是一种格式化输出。
code.c(含详解)
#include "headfile.h"
void led_show(uint8_t led,uint8_t mode)
{
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
if(mode)
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8<<(led-1),GPIO_PIN_RESET);
else
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8<<(led -1),GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}
uint8_t Key_Scan(void)
{
uint8_t Key_val=0;
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==GPIO_PIN_RESET)
{
Key_val=1;
}
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==GPIO_PIN_RESET)
{
Key_val=2;
}if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)==GPIO_PIN_RESET)
{
Key_val=3;
}if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==GPIO_PIN_RESET)
{
Key_val=4;
}
return Key_val;
}
extern uint8_t key_rval;
uint8_t Key_up,Key_down,key_old;
uint8_t count;
void Key_Proc(void)
{
key_rval=Key_Scan();
Key_down=key_rval&(key_rval^key_old);
Key_up=~key_rval&(key_rval^key_old);
key_old=key_rval;
if(Key_down==1)
{
count++;//如果变量 Key_down 的值等于 1,则将变量 count 的值增加 1。
//这是一个简单的条件判断和操作,用于根据特定条件来改变某个变量的值。
}
}
char buf[21];//这定义了一个字符数组 buf,它可以存储长度为 20 的字符串(因为最后一个位置要留给字符串结束符 '\0')。
void Lcd_proc(void)
{
sprintf(buf," count:%d ",count);//"count:%d" 是格式字符串,其中 %d 表示要插入一个整数变量 count 。
//执行完这行代码后,buf 中就会存储一个包含 "count:" 和 count 的具体数值的字符串。
LCD_DisplayStringLine(Line4,(uint8_t*)buf);//“LCD_DisplayStringLine(Line4, (uint8_t*)buf)” 表示在特定的行(Line4)上显示字符串,
//其中字符串的内容来自于指向 uint8_t 类型的指针 buf 所指向的缓冲区。
}
code.h
#ifndef _code_h
#define _code_h
#include "stm32g4xx.h" // Device header
void led_show(uint8_t led,uint8_t mode);
void key_scan(void);
void Lcd_proc(void);
void Key_Proc(void);
#endif
main.c
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2024 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "headfile.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
uint8_t key_rval;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
LCD_Init();
LCD_Clear(Red);
LCD_SetBackColor(Blue);
LCD_SetTextColor(White);
LCD_DisplayStringLine(Line0,(uint8_t*)" jinke! ");
//这行代码是将字符串 " jinke! " 强制转换为指向 uint8_t 类型数据的指针。
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
Key_Proc();
Lcd_proc();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV3;
RCC_OscInitStruct.PLL.PLLN = 20;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
效果展示
开源代码:
通过网盘分享的文件:9-TEST5-LCD配置基础.zip
链接: https://pan.baidu.com/s/1DemTy4Ddf-SMafSFxUis-Q?pwd=0820 提取码: 0820