[C] 纯文本查看 复制代码
#ifndef __ST7789V_LCD_H__
#define __ST7789V_LCD_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "hal/hal_gpio.h"
#include "proj_config.h"
#include "hal/hal_clock.h"
#include "ln_test_common.h"
// 定义屏幕控制引脚
#define LCD_CS_PORT GPIOB_BASE
#define LCD_CS_PIN GPIO_PIN_6
#define LCD_RS_PORT GPIOB_BASE
#define LCD_RS_PIN GPIO_PIN_5
#define LCD_WR_PORT GPIOB_BASE
#define LCD_WR_PIN GPIO_PIN_4
#define LCD_RD_PORT GPIOB_BASE
#define LCD_RD_PIN GPIO_PIN_3
#define LCD_RESET_PORT GPIOB_BASE
#define LCD_RESET_PIN GPIO_PIN_7
// 定义数据总线引脚
#define LCD_DATA_PORT GPIOA_BASE
#define LCD_D0_PIN GPIO_PIN_11
#define LCD_D1_PIN GPIO_PIN_10
#define LCD_D2_PIN GPIO_PIN_9
#define LCD_D3_PIN GPIO_PIN_8
#define LCD_D4_PIN GPIO_PIN_7
#define LCD_D5_PIN GPIO_PIN_6
#define LCD_D6_PIN GPIO_PIN_5
#define LCD_D7_PIN GPIO_PIN_0
// 定义延时函数
#define LCD_DELAY_MS(ms) ln_delay_ms(ms)
//#define LCD_DELAY_US(us) ln_delay_us(us)
// 宏定义写入高低电平
#define LCD_CS_LOW() hal_gpio_pin_reset(LCD_CS_PORT,LCD_CS_PIN)
#define LCD_CS_HIGH() hal_gpio_pin_set(LCD_CS_PORT,LCD_CS_PIN)
#define LCD_RS_LOW() hal_gpio_pin_reset(LCD_RS_PORT,LCD_RS_PIN)
#define LCD_RS_HIGH() hal_gpio_pin_set(LCD_RS_PORT,LCD_RS_PIN)
#define LCD_WR_LOW() hal_gpio_pin_reset(GPIOB_BASE,LCD_WR_PIN)
#define LCD_WR_HIGH() hal_gpio_pin_set(GPIOB_BASE,LCD_WR_PIN)
#define LCD_RESET_LOW() hal_gpio_pin_reset(LCD_RESET_PORT,LCD_RESET_PIN)
#define LCD_RESET_HIGH() hal_gpio_pin_set(LCD_RESET_PORT,LCD_RESET_PIN)
#define USE_HORIZONTAL 2 //设置横屏或者竖屏显示 01为竖屏 23为横屏
#define LCD_WIDTH 240
#define LCD_HEIGHT 320
/* R G B */
/* 00000 000000 00000 */
//颜色定义
#define WHITE 0xFFFF
#define BLACK 0x0000
#define BLUE 0x001F
#define BRED 0XF81F
#define GRED 0XFFE0
#define GBLUE 0X07FF
#define RED 0xF800
#define MAGENTA 0xF81F
#define GREEN 0x07E0
#define CYAN 0x7FFF
#define YELLOW 0xFFE0
#define BROWN 0XBC40
#define BRRED 0XFC07
#define GRAY 0X8430
#define DARKBLUE 0X01CF
#define LIGHTBLUE 0X7D7C
#define GRAYBLUE 0X5458
#define LIGHTGREEN 0X841F
#define LGRAY 0XC618
#define LGRAYBLUE 0XA651
#define LBBLUE 0X2B12
//int ln_drv_spi_lcd_init(void);
//void ln_drv_spi_lcd_fill(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2,uint16_t *color);
void GPIO_Init_OUTPUT(uint32_t gpio_base, gpio_pin_t pin); //设置某个引脚为推挽输出
void LCD_GPIO_Init(); //初始化GPIO函数
void LCD_TR_Writ_BIT_DATABUS(uint32_t gpio_base, gpio_pin_t pin,uint8_t val); //判断数据01然后写入总线上
void LCD_WriteByte(uint8_t byte); //写入一个字节8位
void LCD_WriteCommand(uint8_t cmd); //写入命令
void LCD_WriteData(uint8_t data); //写入数据8位
void LCD_WriteData16(uint16_t data); //写入数据16位
void LCD_Init(); //屏幕初始化函数
void LCD_Clear(uint16_t color); //清屏函数
void LCD_DrawPoint(uint16_t xStart, uint16_t yStart, uint16_t color); //画点函数,在坐标(x,y)的位置画一个点
void LCD_SetWindow(uint16_t xStart, uint16_t yStart, uint16_t xEnd, uint16_t yEnd); //窗口设置函数
//填充一个颜色块
void LCD_FillBlock(uint16_t xStart, uint16_t yStart, uint16_t block_width, uint16_t block_height, uint16_t color);
/*
在坐标(x,y)的位置,填充一个宽和高分别为block_width、block_height的图片
block_data为指向图片点阵数据的指针,图片点阵数据格式为 RGB:565
*/
void LCD_DrawPic(uint16_t xStart, uint16_t yStart, uint16_t block_width, uint16_t block_height, const uint8_t *block_data);
//微秒延时
void delay_us(uint16_t us);
#ifdef __cplusplus
}
#endif
#endif /* __LN_DRV_SPI_LCD_H__ */
#include "ST7789V_lcd.h"
//设置某个引脚为推挽输出
void GPIO_Init_OUTPUT(uint32_t gpio_base, gpio_pin_t pin){
gpio_init_t_def gpio_init;
memset(&gpio_init,0,sizeof(gpio_init));
gpio_init.dir = GPIO_OUTPUT;
gpio_init.pin = pin;
gpio_init.speed = GPIO_HIGH_SPEED;
hal_gpio_init(gpio_base,&gpio_init);
}
//初始化GPIO函数
void LCD_GPIO_Init() {
//配置数据总线为输出模式
GPIO_Init_OUTPUT(LCD_DATA_PORT,LCD_D0_PIN);
GPIO_Init_OUTPUT(LCD_DATA_PORT,LCD_D1_PIN);
GPIO_Init_OUTPUT(LCD_DATA_PORT,LCD_D2_PIN);
GPIO_Init_OUTPUT(LCD_DATA_PORT,LCD_D3_PIN);
GPIO_Init_OUTPUT(LCD_DATA_PORT,LCD_D4_PIN);
GPIO_Init_OUTPUT(LCD_DATA_PORT,LCD_D5_PIN);
GPIO_Init_OUTPUT(LCD_DATA_PORT,LCD_D6_PIN);
GPIO_Init_OUTPUT(LCD_DATA_PORT,LCD_D7_PIN);
// 配置控制信号为输出模式
GPIO_Init_OUTPUT(LCD_CS_PORT,LCD_CS_PIN);
GPIO_Init_OUTPUT(LCD_RS_PORT,LCD_RS_PIN);
GPIO_Init_OUTPUT(LCD_WR_PORT,LCD_WR_PIN);
// GPIO_Init_OUTPUT(LCD_RD_PORT,LCD_RD_PIN);// 如果没有使用RD,可以忽略
GPIO_Init_OUTPUT(LCD_RESET_PORT,LCD_RESET_PIN);
// 默认状态
LCD_CS_HIGH();
LCD_RS_HIGH();
LCD_WR_HIGH();
LCD_RESET_HIGH();
}
//判断数据01然后写入总线上
void LCD_TR_Writ_BIT_DATABUS(uint32_t gpio_base, gpio_pin_t pin,uint8_t val){
if(val){
hal_gpio_pin_set(gpio_base,pin);
}else{
hal_gpio_pin_reset(gpio_base,pin);
}
}
//写入一个字节8位
void LCD_WriteByte(uint8_t byte) {
LCD_WR_HIGH();
// delay_us(1); // 确保时序
// 将字节写入总线数据
LCD_TR_Writ_BIT_DATABUS(LCD_DATA_PORT,LCD_D0_PIN,(byte >> 0) & 0x01);
LCD_TR_Writ_BIT_DATABUS(LCD_DATA_PORT,LCD_D1_PIN, (byte >> 1) & 0x01);
LCD_TR_Writ_BIT_DATABUS(LCD_DATA_PORT,LCD_D2_PIN, (byte >> 2) & 0x01);
LCD_TR_Writ_BIT_DATABUS(LCD_DATA_PORT,LCD_D3_PIN, (byte >> 3) & 0x01);
LCD_TR_Writ_BIT_DATABUS(LCD_DATA_PORT,LCD_D4_PIN, (byte >> 4) & 0x01);
LCD_TR_Writ_BIT_DATABUS(LCD_DATA_PORT,LCD_D5_PIN, (byte >> 5) & 0x01);
LCD_TR_Writ_BIT_DATABUS(LCD_DATA_PORT,LCD_D6_PIN, (byte >> 6) & 0x01);
LCD_TR_Writ_BIT_DATABUS(LCD_DATA_PORT,LCD_D7_PIN, (byte >> 7) & 0x01);
// 生成WR脉冲
LCD_WR_LOW();
delay_us(1); // 确保时序
LCD_WR_HIGH();
delay_us(1); // 确保时序
}
//写入命令
void LCD_WriteCommand(uint8_t cmd) {
LCD_CS_LOW();
LCD_RS_LOW(); // RS=0表示命令
LCD_WriteByte(cmd);
LCD_CS_HIGH();
}
//写入数据8位
void LCD_WriteData(uint8_t data) {
LCD_CS_LOW();
LCD_RS_HIGH(); // RS=1表示数据
LCD_WriteByte(data);
LCD_CS_HIGH();
}
//写入数据16位
void LCD_WriteData16(uint16_t data){
LCD_CS_LOW();
LCD_RS_HIGH(); // RS=1表示数据
LCD_WriteByte(data >> 8);
LCD_WriteByte(data);
LCD_CS_HIGH();
}
//屏幕初始化函数
void LCD_Init(){
//屏幕厂商
//初始化GPIO
LCD_GPIO_Init();
//复位屏幕
LCD_RESET_LOW();
LCD_DELAY_MS(120);
LCD_RESET_HIGH();
LCD_DELAY_MS(120);
//发送初始化命令
LCD_WriteCommand(0x11); //退出休眠模式
LCD_DELAY_MS(120);
LCD_WriteCommand(0xB2);
LCD_WriteData(0x0C);
LCD_WriteData(0x0C);
LCD_WriteData(0x00);
LCD_WriteData(0x33);
LCD_WriteData(0x33);
LCD_WriteCommand(0x35);
LCD_WriteData(0x00);
LCD_WriteCommand(0x36);
LCD_WriteData(0x00);
LCD_WriteCommand(0x3A);
LCD_WriteData(0x05);
LCD_WriteCommand(0xB7);
LCD_WriteData(0x06);
LCD_WriteCommand(0xBB);
LCD_WriteData(0x20);
LCD_WriteCommand(0xC0);
LCD_WriteData(0x2C);
LCD_WriteCommand(0xC2);
LCD_WriteData(0x01);
LCD_WriteCommand(0xC3);
LCD_WriteData(0x0F);
LCD_WriteCommand(0xC6);
LCD_WriteData(0x0F);
LCD_WriteCommand(0xD0);
LCD_WriteData(0xA7);
LCD_WriteCommand(0xD0);
LCD_WriteData(0xA4);
LCD_WriteData(0xA1);
LCD_WriteCommand(0xD6);
LCD_WriteData(0xA1);
LCD_WriteCommand(0xE0);
LCD_WriteData(0xF0);
LCD_WriteData(0x06);
LCD_WriteData(0x0E);
LCD_WriteData(0x08);
LCD_WriteData(0x09);
LCD_WriteData(0x17);
LCD_WriteData(0x37);
LCD_WriteData(0x54);
LCD_WriteData(0x4C);
LCD_WriteData(0x39);
LCD_WriteData(0x14);
LCD_WriteData(0x12);
LCD_WriteData(0x2F);
LCD_WriteData(0x34);
LCD_WriteCommand(0xE1);
LCD_WriteData(0xF0);
LCD_WriteData(0x0F);
LCD_WriteData(0x14);
LCD_WriteData(0x0C);
LCD_WriteData(0x0A);
LCD_WriteData(0x04);
LCD_WriteData(0x37);
LCD_WriteData(0x43);
LCD_WriteData(0x4C);
LCD_WriteData(0x36);
LCD_WriteData(0x12);
LCD_WriteData(0x14);
LCD_WriteData(0x2D);
LCD_WriteData(0x36);
LCD_WriteCommand(0x21); // 显示反转
LCD_WriteCommand(0x29); // 开启显示
LCD_WriteCommand(0x2C);
}
//清屏函数
void LCD_Clear(uint16_t color) {
// LCD_WriteCommand(0x2A); // 设置列地址
// LCD_WriteData(0x00);
// LCD_WriteData(0x00);
// LCD_WriteData(0x00);
// LCD_WriteData(0xEF);
// LCD_WriteCommand(0x2B); // 设置行地址
// LCD_WriteData(0x00);
// LCD_WriteData(0x00);
// LCD_WriteData(0x01);
// LCD_WriteData(0x3F);
// LCD_WriteCommand(0x2C); // 写入RAM
LCD_SetWindow(0,0,LCD_WIDTH-1,LCD_HEIGHT-1);
LCD_WriteCommand(0x2C); // 进入 RAM 写入模式
// 发送颜色数据
LCD_CS_LOW();
LCD_RS_HIGH();
for (uint32_t i = 0; i < LCD_WIDTH * LCD_HEIGHT; i++) {
LCD_WriteByte(color >> 8); // 高字节(D15-D8)
LCD_WriteByte(color & 0xFF); // 低字节(D7-D0)
}
LCD_CS_HIGH();
}
//画点函数,在坐标(x,y)的位置画一个点
void LCD_DrawPoint(uint16_t xStart, uint16_t yStart, uint16_t color)
{
LCD_WriteCommand(0x2a);
LCD_WriteData16(xStart);
LCD_WriteCommand(0x2b);
LCD_WriteData16(yStart);
LCD_WriteCommand(0x2c);
LCD_WriteData16(color);
}
//窗口设置函数
void LCD_SetWindow(uint16_t xStart, uint16_t yStart, uint16_t xEnd, uint16_t yEnd)
{
LCD_WriteCommand(0x2a);
LCD_WriteData16(xStart);
LCD_WriteData16(xEnd);
LCD_WriteCommand(0x2b);
LCD_WriteData16(yStart);
LCD_WriteData16(yEnd);
LCD_WriteCommand(0x2c);
}
//填充一个颜色块
void LCD_FillBlock(uint16_t xStart, uint16_t yStart, uint16_t block_width, uint16_t block_height, uint16_t color)
{
uint32_t i,j;
LCD_SetWindow( xStart, yStart, (xStart+block_width-1), (yStart+block_height-1) );
for(i=0;i<block_width;i++)
{
for(j=0;j<block_height;j++)
{
LCD_WriteData16(color);
}
}
}
/*
在坐标(x,y)的位置,填充一个宽和高分别为block_width、block_height的图片
block_data为指向图片点阵数据的指针,图片点阵数据格式为 RGB:565
*/
void LCD_DrawPic(uint16_t xStart, uint16_t yStart, uint16_t block_width, uint16_t block_height, const uint8_t *block_data)
{
uint32_t i,j;
LCD_SetWindow( xStart, yStart, (xStart+block_width-1), (yStart+block_height-1) );
for(i=0;i<block_width;i++)
{
for(j=0;j<block_height;j++)
{
LCD_WriteData(*(block_data+1));
LCD_WriteData(*block_data);
block_data += 2;
}
}
}
//微秒延时
void delay_us(uint16_t us)
{
uint32_t count; // ??????? __nop() ??
//40M
if(hal_clock_get_core_clk() == 40000000)
{
count = hal_clock_get_core_clk() / 40;
}
else
//160M
{
count = hal_clock_get_core_clk() / 160;
}
count = count * us;
while (count--) {
__nop(); // ?????????
}
}
用的是单片机是LN882H,屏幕是2寸的显示屏。显示屏是ST7789v的,8bit数据位的,我在使用8080时序去驱动屏幕的时候,屏幕一直是花屏的,小白头一次搞这个8080驱动屏幕,麻烦各位大佬给帮忙分析一下哪里的问题