Mini_croe_Sick/User/device/lcd.c
2025-04-10 17:17:56 +08:00

169 lines
4.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "lcd.h"
#include "lcd_font.h"
// 写命令
static void LCD_WriteCommand(uint8_t cmd) {
LCD_DC_LOW();
LCD_CS_LOW();
HAL_SPI_Transmit(&hspi1, &cmd, 1, HAL_MAX_DELAY);
LCD_CS_HIGH();
}
// 写数据
static void LCD_WriteData(uint8_t data) {
LCD_DC_HIGH();
LCD_CS_LOW();
HAL_SPI_Transmit(&hspi1, &data, 1, HAL_MAX_DELAY);
LCD_CS_HIGH();
}
// 写16位数据
static void LCD_WriteData16(uint16_t data) {
uint8_t buf[2] = {data >> 8, data & 0xFF};
LCD_DC_HIGH();
LCD_CS_LOW();
HAL_SPI_Transmit(&hspi1, buf, 2, HAL_MAX_DELAY);
LCD_CS_HIGH();
}
// 初始化LCD
void LCD_Init(void) {
// 复位屏幕
LCD_RST_LOW();
HAL_Delay(10);
LCD_RST_HIGH();
HAL_Delay(10);
// 初始化命令序列以ST7789为例
LCD_WriteCommand(0x36); // Memory Data Access Control
LCD_WriteData(0xC0); // RGB Color Order
LCD_WriteCommand(0x3A); // Interface Pixel Format
LCD_WriteData(0x05); // 16-bit/pixel
LCD_WriteCommand(0xB2); // Porch Setting
LCD_WriteData(0x0C);
LCD_WriteData(0x0C);
LCD_WriteData(0x00);
LCD_WriteData(0x33);
LCD_WriteData(0x33);
LCD_WriteCommand(0xB7); // Gate Control
LCD_WriteData(0x35);
LCD_WriteCommand(0xBB); // VCOM Setting
LCD_WriteData(0x19);
LCD_WriteCommand(0xC0); // LCM Control
LCD_WriteData(0x2C);
LCD_WriteCommand(0xC2); // VDV and VRH Command Enable
LCD_WriteData(0x01);
LCD_WriteCommand(0xC3); // VRH Set
LCD_WriteData(0x12);
LCD_WriteCommand(0xC4); // VDV Set
LCD_WriteData(0x20);
LCD_WriteCommand(0xC6); // Frame Rate Control
LCD_WriteData(0x0F);
LCD_WriteCommand(0xD0); // Power Control 1
LCD_WriteData(0xA4);
LCD_WriteData(0xA1);
LCD_WriteCommand(0xE0); // Positive Voltage Gamma Control
LCD_WriteData(0xD0);
LCD_WriteData(0x04);
LCD_WriteData(0x0D);
LCD_WriteData(0x11);
LCD_WriteData(0x13);
LCD_WriteData(0x2B);
LCD_WriteData(0x3F);
LCD_WriteData(0x54);
LCD_WriteData(0x4C);
LCD_WriteData(0x18);
LCD_WriteData(0x0D);
LCD_WriteData(0x0B);
LCD_WriteData(0x1F);
LCD_WriteData(0x23);
LCD_WriteCommand(0xE1); // Negative Voltage Gamma Control
LCD_WriteData(0xD0);
LCD_WriteData(0x04);
LCD_WriteData(0x0C);
LCD_WriteData(0x11);
LCD_WriteData(0x13);
LCD_WriteData(0x2C);
LCD_WriteData(0x3F);
LCD_WriteData(0x44);
LCD_WriteData(0x51);
LCD_WriteData(0x2F);
LCD_WriteData(0x1F);
LCD_WriteData(0x1F);
LCD_WriteData(0x20);
LCD_WriteData(0x23);
LCD_WriteCommand(0x21); // Inversion On
LCD_WriteCommand(0x11); // Sleep Out
HAL_Delay(120);
LCD_WriteCommand(0x29); // Display On
}
// 清屏
void LCD_Clear(uint16_t color) {
LCD_WriteCommand(0x2A); // Column Address Set
LCD_WriteData16(X_OFFSET); // 起始列地址
LCD_WriteData16(X_OFFSET + LCD_WIDTH - 1); // 结束列地址
LCD_WriteCommand(0x2B); // Row Address Set
LCD_WriteData16(Y_OFFSET); // 起始行地址
LCD_WriteData16(Y_OFFSET + LCD_HEIGHT - 1); // 结束行地址
LCD_WriteCommand(0x2C); // Memory Write
for (uint32_t i = 0; i < LCD_WIDTH * LCD_HEIGHT; i++) {
LCD_WriteData16(color);
}
}
// 绘制单个像素
void LCD_DrawPixel(uint16_t x, uint16_t y, uint16_t color) {
if (x >= LCD_WIDTH || y >= LCD_HEIGHT) return; // 超出屏幕范围则返回
LCD_WriteCommand(0x2A); // 设置列地址
LCD_WriteData16(X_OFFSET + x);
LCD_WriteData16(X_OFFSET + x);
LCD_WriteCommand(0x2B); // 设置行地址
LCD_WriteData16(Y_OFFSET + y);
LCD_WriteData16(Y_OFFSET + y);
LCD_WriteCommand(0x2C); // 写入内存
LCD_WriteData16(color);
}
// 在指定位置显示一个字符
void LCD_DrawChar(uint16_t x, uint16_t y, char ch, uint16_t color, uint16_t bgColor) {
if (ch < 32 || ch > 126) return; // 字符范围检查 (ASCII 32-126)
const uint8_t *charData = ascii_1206[ch - 32]; // 获取字符点阵数据
for (uint8_t i = 0; i < FONT_HEIGHT; i++) { // 遍历字符的高度
uint8_t line = charData[i]; // 获取字符的每一行数据
for (uint8_t j = 0; j < FONT_WIDTH; j++) { // 遍历字符的宽度
if (line & (1 << j)) { // 判断当前像素是否为1
LCD_DrawPixel(x + j, y + i, color); // 绘制前景色
} else {
LCD_DrawPixel(x + j, y + i, bgColor); // 绘制背景色
}
}
}
}
// 在指定位置显示字符串
void LCD_DrawString(uint16_t x, uint16_t y, const char *str, uint16_t color, uint16_t bgColor) {
while (*str) {
LCD_DrawChar(x, y, *str, color, bgColor); // 显示单个字符
x += FONT_WIDTH; // 移动到下一个字符位置
str++;
}
}