NV3041A-01芯片屏幕
您提供的这款屏幕驱动芯片是一款功能高度集成、性能优良的解决方案,尤其适合空间受限的便携式产品。集成度高: 集成了电源、显存、时序控制,极大简化了系统设计。节省MCU资源: 拥有全帧显存,MCU更新完画面后即可休眠,功耗低。接口灵活: 支持从低速SPI到高速并行接口,适配不同性能的MCU。供电简单: 仅需单一3.3V供电,内部自己产生所有高压。结构紧凑: 专为COG工艺设计,屏幕模块体积小。这款芯片


1. 核心概览
这是一款集成了电源管理、显示内存(RAM)、时序控制等多种功能的单片显示驱动芯片(通常称为Driver IC)。它采用COG(Chip-On-Glass) 工艺,直接将芯片绑定在玻璃基板上,使得屏幕模块非常轻薄紧凑。它需要外接一个主控MCU(单片机)来向其发送图像数据和指令。
2. 详细特性解释
◆ 显示分辨率选项
-
480 (RGB) × 272 (V): 宽480像素,高272像素。这是一种常见的宽屏分辨率,也称为WVGA( Wide Video Graphics Array)。
-
320 (RGB) × 240 (V): 宽320像素,高240像素。这是一种经典的方屏分辨率,也称为QVGA(Quarter Video Graphics Array)。
注意: 这里的“(RGB)”表示每个像素由红、绿、蓝三个子像素组成。所以实际的物理驱动通道数会更高(480 x 3 = 1440个源极通道)。
◆ LCD驱动输出电路
这说明了芯片直接驱动液晶屏的能力。
-
Source Outputs: 720 Channels: 源极输出720通道。这正好对应480 (RGB) × 3 = 1440个子像素,但通常芯片会以奇偶或分组方式驱动,所以通道数可以是物理子像素数的一半(720通道通过分时等方式驱动1440列)。
-
Gate Outputs: 544 Channels: 栅极输出544通道。这用于逐行扫描,272行分辨率只需272通道,544通道意味着它可以支持最高544行的屏幕(可能是为其他型号预留或内部设计冗余)。
-
Common Electrode Output: 公共电极输出,用于形成驱动液晶的电场。
◆ 64灰阶与6位DAC
-
64 gray scale: 可以显示64级灰度。
-
true 6 bit DAC: 使用一个6位的数模转换器(DAC)来产生64种不同的电压电平,以精确控制每个子像素的亮度,从而混合出
64^3 = 262,144种颜色(即26万色)。这是实现64级灰度的硬件基础。
◆ 接口(与主控MCU的连接方式)
这是芯片非常关键的部分,定义了它如何接收数据。
-
8080-I/8080-II系列MCU接口: 这是一种并行接口,以Intel 8080系列MCU命名。速度快,但需要大量引脚。
-
8-bits/9-bits/16-bits: 支持不同位宽的数据传输。16位模式(R5G6B5)最常用,一次传输一个像素的颜色数据。
-
-
3-wire/4-wire Serial Peripheral Interface (SPI): 串行外设接口。引脚需求少(3-4根),但速度较慢,适合分辨率较低或刷新率要求不高的场景。
-
2 data lane SPI: 双线SPI,通过两条数据线同时传输数据,速度比单线SPI快一倍。
-
Q-SPI: 四线SPI(Quad SPI),通过四条数据线同时传输,速度更快。是现代SPI接口的主流高性能模式。
-
总结: 接口选择提供了灵活性,高速应用用并行8080接口,节省引脚用SPI接口,追求平衡则用Q-SPI。
◆ 芯片内置电路(高度集成化的体现)
这些功能通常需要外部元件实现,但这款芯片将其集成 inside,大大简化了外围电路设计。
-
DC/DC Converter: 直流-直流转换器(电荷泵)。用于从较低的输入电压(如3.3V)生成驱动LCD所需的各种高低电压(如VGH、VGL等)。
-
Timing Controller: 时序控制器。产生驱动LCD源极和栅极所需的所有精确时序信号,是显示驱动的“大脑”。
-
Graphic RAM: 293760 bytes: 显存(帧缓存)。这个大小非常关键:
480 x 272 x 18-bit / 8 ≈ 293760 bytes。这意味着芯片内部有一块内存,可以存储一整帧480x272分辨率、18位色深(RGB各6位)的图像数据。MCU只需将图像数据写入这块内存,芯片就会自动循环读取并显示出来,极大减轻了MCU的负担(无需持续刷新)。 -
Non-Volatile (NV) Memory: 非易失性存储器。用于存储屏幕的初始化寄存器设置和出厂默认值。通电后芯片可以自动从NV Memory加载配置,无需MCU每次开机都重新发送一大串初始化命令。
◆ 供电电压范围
定义了芯片不同部分正常工作所需的电压。
-
I/O Voltage (1.65V ~ VCI): 用于与MCU通信的IO引脚电平,兼容1.8V等低电压逻辑。
-
Analog Voltage (VCI: 3.0V ~ 3.6V): 模拟电路的核心电压,通常是3.3V。
-
Charge pump Voltage (VCIP: 3.0V ~ 3.6V): 电荷泵的输入电压。
◆ 片上电源系统(由内部DC/DC产生)
这些是驱动LCD面板本身所需的特殊电压。
-
GVDD, GVCL: 用于驱动源极(Source)的灰度电压的正负参考电压。
-
VGH (Gate High): 打开TFT开关管的高电平电压(~15V)。
-
VGL (Gate Low): 关闭TFT开关管的低电平电压(~ -10V)。
◆ 优化布局用于COG组装
-
COG (Chip-On-Glass): 指芯片通过ACF(各向异性导电胶)直接压接绑定在LCD玻璃基板的引线上。这种工艺使显示屏模块非常薄、轻、结构紧凑。芯片的引脚布局和尺寸专门为这种工艺进行了优化。

TE 引脚是一个输出信号,其核心作用是将 LCD 控制器内部的刷新时序反馈给 MCU,让 MCU 知道何时向显存写入数据是安全的,从而避免屏幕出现"撕裂"现象。
// 1. 配置 TE 控制寄存器 (0xE7),使能输出
NV3041_WriteCommand(0xE7); // TE_CTRL 命令
NV3041_WriteData(0x10); // 设置 D4=1 (te_out_oe=1),使能输出
// 2. 发送 TEON 命令 (0x35),选择模式并启动输出
NV3041_WriteCommand(0x35); // TEON 命令
NV3041_WriteData(0x01); // 设置 D0=1 (te_sel=1),选择模式1 (V-Blanking + H-Blanking)
// MCU 端中断处理函数
void TE_GPIO_EXTI_Callback(void) {
// 检测到 TE 信号的边沿(表示进入消隐期)
if(HAL_GPIO_ReadPin(TE_GPIO_Port, TE_Pin)) {
// 安全:现在可以开始更新显存了!
update_frame_buffer(); // 你的画面更新函数
}
}
// 主循环中
while (1) {
// 主循环处理其他任务...
// 屏幕更新由 TE 中断同步触发,不会在这里盲目更新
}
简单来说:TE 引脚就像是 LCD 对 MCU 说:"我准备好接收新数据了,现在可以安全地写了!"
当 RDX 引脚被 MCU 拉低时,NV3041A 会将内部数据或状态寄存器的内容输出到数据总线上,MCU 可以读取这些数据。
软件模拟8080驱动屏幕(已跑通):
.c
#include "k_NV3041A_lcd_driver.h"
#include "system/includes.h"
#include "kph_para.h"
para_info kph_para;
static void timer_cfg(u32 freq, u32 us)
{
JL_TIMER_TypeDef *TMR = JL_TIMER4;//选择定时器4
u8 timer_irq = IRQ_TIMER4_IDX;//选择定时器4
const u8 timer_index[16] = {0, 4, 1, 5, 2, 6, 3, 7, 8, 12, 9, 13, 10, 14, 11, 15};
const u32 timer_table[16] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768};
u32 clock = clk_get("timer");
u8 psc = 0;
u8 tmp = 0;
u32 prd = 0;
u32 ts = us / (1000 * 1000);//计算秒
u32 tu = us % (1000 * 1000);//计算秒剩余us
u8 i;
float tp = 0;
if (freq >= clock) {
freq = clock;
} else if (freq <= 1) {
freq = 1;
if (ts) {
tp = (float)tu / (1000 * 1000);
}
}
/*求prd值*/
prd = clock / freq;
if (prd > 65535) {
for (psc = 0; psc < 16; psc++) {
prd = (u32)(clock / (timer_table[psc]) / freq);
if (prd <= 65535) {
break;
} else if (psc == 15) {
prd = 65535;
break;
}
}
}
prd = ts ? (prd * ts + tp * prd) : prd;
psc = timer_index[psc];
TMR->CON = 0;
TMR->CNT = 0;
TMR->CON |= BIT(14);
TMR->PRD = prd;
TMR->CON |= psc << 4; //lsb_clk分频
TMR->CON |= BIT(0);
while (!(TMR->CON & BIT(15)));
TMR->CON |= BIT(14);
TMR->CON = 0;
}
void time_delay(u32 us)//延时us级别
{
u32 freq = 1000000 / us;
timer_cfg(freq, us);//传参:当只需要设置频率,则us = 0
}
// 简单的延时函数实现
void Delayms(unsigned int ms)
{
// 使用系统提供的延时函数
if(ms < 10) {
return;
}
os_time_dly(ms/10);
}
/**
* @brief 设置数据总线值 (8位)
* @param data 要发送的8位数据
*/
static void set_data_bus(uint8_t data) {
// 使用宏定义来设置每个数据位
// if (data & 0x01) {LCD_D0_HIGH();} else {LCD_D0_LOW();}
// if (data & 0x02) {LCD_D1_HIGH();} else {LCD_D1_LOW();}
// if (data & 0x04) {LCD_D2_HIGH();} else {LCD_D2_LOW();}
// if (data & 0x08) {LCD_D3_HIGH();} else {LCD_D3_LOW();}
// if (data & 0x10) {LCD_D4_HIGH();} else {LCD_D4_LOW();}
// if (data & 0x20) {LCD_D5_HIGH();} else {LCD_D5_LOW();}
// if (data & 0x40) {LCD_D6_HIGH();} else {LCD_D6_LOW();}
// if (data & 0x80) {LCD_D7_HIGH();} else {LCD_D7_LOW();}
gpio_direction_output(LCD_DATA_D0, (data >> 0) & 0x01);
gpio_direction_output(LCD_DATA_D1, (data >> 1) & 0x01);
gpio_direction_output(LCD_DATA_D2, (data >> 2) & 0x01);
gpio_direction_output(LCD_DATA_D3, (data >> 3) & 0x01);
gpio_direction_output(LCD_DATA_D4, (data >> 4) & 0x01);
gpio_direction_output(LCD_DATA_D5, (data >> 5) & 0x01);
gpio_direction_output(LCD_DATA_D6, (data >> 6) & 0x01);
gpio_direction_output(LCD_DATA_D7, (data >> 7) & 0x01);
}
/**
* @brief 产生WRX写脉冲
*/
static void generate_wrx_pulse(void) {
// 需要短暂延时,确保建立时间和保持时间
// 这里用空循环实现简短延时,具体时间需要根据你的MCU频率调整
// time_delay(5);
WR_GPIO_HIGH(); // WRX拉高 (上升沿)
// time_delay(5);
}
/**
* @brief 写命令到NV3041A (8080并行接口)
* @param cmd 命令字节
*/
void NV3041_SPI_Write_cmd(uint8_t cmd) {
// 1. 设置DCX为低电平 (命令模式)
DC_GPIO_LOW();
// 2. 片选有效 (低电平有效)
CS_GPIO_LOW();
RD_GPIO_HIGH();
WR_GPIO_LOW(); // WRX拉低 (下降沿)
// 3. 设置数据总线
set_data_bus(cmd);
// 4. 产生WRX写脉冲 (上升沿锁存数据)
generate_wrx_pulse();
// 5. 恢复DCX为高电平 (数据模式)
DC_GPIO_HIGH();
// 6. 释放片选
CS_GPIO_HIGH();
}
/**
* @brief 写数据到NV3041A (8080并行接口)
* @param data 数据字节
*/
void NV3041_SPI_Write_data(uint8_t data) {
// 1. DCX为高电平 (数据模式)
DC_GPIO_HIGH();
// 2. 片选有效 (低电平有效)
CS_GPIO_LOW();
RD_GPIO_HIGH();
WR_GPIO_LOW(); // WRX拉低 (下降沿)
// 3. 设置数据总线
set_data_bus(data);
// 4. 产生WRX写脉冲 (下降沿锁存数据)
generate_wrx_pulse();
DC_GPIO_LOW();
// 5. 释放片选
CS_GPIO_HIGH();
}
//推挽输出
void gpio_push_pull_init(unsigned int gpio,int value)
{
gpio_set_pull_up(gpio, 0);
gpio_set_pull_down(gpio, 0);
gpio_direction_output(gpio, value);
}
//浮空输入
void gpio_pull_float_init(unsigned int gpio)
{
gpio_set_pull_up(gpio, 0);
gpio_set_pull_down(gpio, 0);
gpio_set_die(gpio, 1);
gpio_direction_input(gpio);
}
static void *TE_IntHandler(void) //外部中断处理
{
printf("hello,lcd");
}
void TE_gpio_init(void)
{
port_wakeup_reg(EVENT_IO_0, LCD_TE, EDGE_POSITIVE, TE_IntHandler);//gpio中断模式使用
}
/**
* @brief 设置数据总线为输出模式(用于写操作)
*/
static void set_data_bus_output(void) {
gpio_push_pull_init(LCD_DATA_D0, 0);
gpio_push_pull_init(LCD_DATA_D1, 0);
gpio_push_pull_init(LCD_DATA_D2, 0);
gpio_push_pull_init(LCD_DATA_D3, 0);
gpio_push_pull_init(LCD_DATA_D4, 0);
gpio_push_pull_init(LCD_DATA_D5, 0);
gpio_push_pull_init(LCD_DATA_D6, 0);
gpio_push_pull_init(LCD_DATA_D7, 0);
}
/**
* @brief 设置数据总线为输入模式(用于读操作)
*/
static void set_data_bus_input(void) {
// 根据你的SDK配置为输入模式,可能需要使用不同的函数
gpio_pull_float_init(LCD_DATA_D0);
gpio_pull_float_init(LCD_DATA_D1);
gpio_pull_float_init(LCD_DATA_D2);
gpio_pull_float_init(LCD_DATA_D3);
gpio_pull_float_init(LCD_DATA_D4);
gpio_pull_float_init(LCD_DATA_D5);
gpio_pull_float_init(LCD_DATA_D6);
gpio_pull_float_init(LCD_DATA_D7);
}
//初始化LCD GPIO
void NV3041A_lcd_gpio_init(void)
{
set_data_bus_output();
gpio_push_pull_init(LCD_DC,0);
gpio_push_pull_init(LCD_RD,0);
gpio_push_pull_init(LCD_WR,0);
gpio_push_pull_init(LCD_CS,0);
gpio_push_pull_init(LCD_RESET,0);
// TE_gpio_init();
}
/**
* @brief 从数据总线读取一个字节
* @return 读取到的数据
*/
static uint8_t read_data_bus(void) {
uint8_t data = 0;
data |= (gpio_read(LCD_DATA_D0) << 0);
data |= (gpio_read(LCD_DATA_D1) << 1);
data |= (gpio_read(LCD_DATA_D2) << 2);
data |= (gpio_read(LCD_DATA_D3) << 3);
data |= (gpio_read(LCD_DATA_D4) << 4);
data |= (gpio_read(LCD_DATA_D5) << 5);
data |= (gpio_read(LCD_DATA_D6) << 6);
data |= (gpio_read(LCD_DATA_D7) << 7);
return data;
}
/**
* @brief 设置显示窗口(定义要更新的区域)
* @param x_start 起始列地址
* @param y_start 起始行地址
* @param x_end 结束列地址
* @param y_end 结束行地址
*/
void NV3041_SetWindow(uint16_t x_start, uint16_t y_start, uint16_t x_end, uint16_t y_end) {
// 设置列地址 (X方向)
NV3041_SPI_Write_cmd(0x2A); // COL_ADR 命令
NV3041_SPI_Write_data(x_start >> 8); // 起始地址高字节
NV3041_SPI_Write_data(x_start & 0xFF); // 起始地址低字节
NV3041_SPI_Write_data(x_end >> 8); // 结束地址高字节
NV3041_SPI_Write_data(x_end & 0xFF); // 结束地址低字节
// 设置行地址 (Y方向)
NV3041_SPI_Write_cmd(0x2B); // ROW_ADR 命令
NV3041_SPI_Write_data(y_start >> 8); // 起始地址高字节
NV3041_SPI_Write_data(y_start & 0xFF); // 起始地址低字节
NV3041_SPI_Write_data(y_end >> 8); // 结束地址高字节
NV3041_SPI_Write_data(y_end & 0xFF); // 结束地址低字节
}
/**
* @brief 填充整个屏幕为指定颜色
* @param color RGB565格式的颜色值
*/
void NV3041_FillScreen(uint16_t color) {
// 1. 设置显示窗口为全屏
NV3041_SetWindow(0, 0, WIDTH-1, HEIGHT-1); // 480x272 屏幕
// 2. 发送内存写命令
NV3041_SPI_Write_cmd(0x2C); // MEMWR 命令
// 3. 写入整个屏幕的像素数据
uint32_t total_pixels = WIDTH * HEIGHT;
uint8_t high_byte = color >> 8; // 颜色高字节
uint8_t low_byte = color & 0xFF; // 颜色低字节
for(uint32_t i = 0; i < total_pixels; i++) {
NV3041_SPI_Write_data(high_byte);
NV3041_SPI_Write_data(low_byte);
}
}
void NV3041A_lcd_driver(void)
{
//NV3041A-01+HK4.3IPS 外置VCOM pixel 5-6-5 code--16bit 20240425
NV3041_SPI_Write_cmd(0xff);
NV3041_SPI_Write_data(0xa5);
NV3041_SPI_Write_cmd(0xE7);//TE_output_en
NV3041_SPI_Write_data(0x10);
NV3041_SPI_Write_cmd(0x35);//TE_ interface_en
NV3041_SPI_Write_data(0x01);
NV3041_SPI_Write_cmd(0x3A);
NV3041_SPI_Write_data(0x01);//00---666//01--565
NV3041_SPI_Write_cmd(0x40);
NV3041_SPI_Write_data(0x01); //01:IPS/00:TN
NV3041_SPI_Write_cmd(0x41);
NV3041_SPI_Write_data(0x01);//01--8bit//03--16bit
NV3041_SPI_Write_cmd(0x55);
NV3041_SPI_Write_data(0x01);
NV3041_SPI_Write_cmd(0x44);//VBP
NV3041_SPI_Write_data(0x15);//21
NV3041_SPI_Write_cmd(0x45);//VFP
NV3041_SPI_Write_data(0x15);//21
NV3041_SPI_Write_cmd(0x7d);//vdds_trim[2:0]
NV3041_SPI_Write_data(0x03);//2.07V
NV3041_SPI_Write_cmd(0xc1);//avdd_clp_en avdd_clp[1:0] avcl_clp_en avcl_clp[1:0]
NV3041_SPI_Write_data(0xab);//6.74V/-5.16V
NV3041_SPI_Write_cmd(0xc2);//vgh_clp_en vgl_clp[2:0]
NV3041_SPI_Write_data(0x17);
NV3041_SPI_Write_cmd(0xc3);//vgl_clp_en vgl_clp[2:0]
NV3041_SPI_Write_data(0x10);//-10.951
NV3041_SPI_Write_cmd(0xc6);//avdd_ratio_sel avcl_ratio_sel vgh_ratio_sel[1:0] vgl_ratio_sel[1:0]
NV3041_SPI_Write_data(0x3a);//35
NV3041_SPI_Write_cmd(0xc7);//mv_clk_sel[1:0] avdd_clk_sel[1:0] avcl_clk_sel[1:0]
NV3041_SPI_Write_data(0x25); //2e
NV3041_SPI_Write_cmd(0xc8);// VGL_CLK_sel
NV3041_SPI_Write_data(0x11);
NV3041_SPI_Write_cmd(0x7a);// user_vgsp
NV3041_SPI_Write_data(0x55);
NV3041_SPI_Write_cmd(0x6f);// user_gvdd
NV3041_SPI_Write_data(0x2f);
NV3041_SPI_Write_cmd(0x78);// user_gvcl
NV3041_SPI_Write_data(0x29);
NV3041_SPI_Write_cmd(0x73);//osc
NV3041_SPI_Write_data(0x08);
NV3041_SPI_Write_cmd(0x74);
NV3041_SPI_Write_data(0x15);//12
NV3041_SPI_Write_cmd(0xc9);
NV3041_SPI_Write_data(0x00);
NV3041_SPI_Write_cmd(0x67);
NV3041_SPI_Write_data(0x33);//11
//gate_ed
NV3041_SPI_Write_cmd(0x51);//gate_st_o[7:0]
//NV3041_SPI_Write_data(0x4b);
NV3041_SPI_Write_data(0x20);
NV3041_SPI_Write_cmd(0x52);//gate_ed_o[7:0]
NV3041_SPI_Write_data(0x7c);
NV3041_SPI_Write_cmd(0x53);//gate_st_e[7:0]
//NV3041_SPI_Write_data(0x45);
NV3041_SPI_Write_data(0x1c);
NV3041_SPI_Write_cmd(0x54);//gate_ed_e[7:0]
NV3041_SPI_Write_data(0x77);
////sorce old
NV3041_SPI_Write_cmd(0x46);//fsm_hbp_o[5:0]
NV3041_SPI_Write_data(0x0a);
NV3041_SPI_Write_cmd(0x47);//fsm_hfp_o[5:0]
NV3041_SPI_Write_data(0x2a);
NV3041_SPI_Write_cmd(0x48);//fsm_hbp_e[5:0]
NV3041_SPI_Write_data(0x0a);
NV3041_SPI_Write_cmd(0x49);//fsm_hfp_e[5:0]
NV3041_SPI_Write_data(0x1a);
NV3041_SPI_Write_cmd(0x56);//src_ld_wd[1:0] src_ld_st[5:0]
NV3041_SPI_Write_data(0x43);
NV3041_SPI_Write_cmd(0x57);//pn_cs_en src_cs_st[5:0]
NV3041_SPI_Write_data(0x42);
NV3041_SPI_Write_cmd(0x58);//src_cs_p_wd[6:0]
NV3041_SPI_Write_data(0x3c);
NV3041_SPI_Write_cmd(0x59);//src_cs_n_wd[6:0]
NV3041_SPI_Write_data(0x64);
NV3041_SPI_Write_cmd(0x5a);//src_pchg_st_o[6:0]
NV3041_SPI_Write_data(0x41);
NV3041_SPI_Write_cmd(0x5b);//src_pchg_wd_o[6:0]
NV3041_SPI_Write_data(0x3c);
NV3041_SPI_Write_cmd(0x5c);//src_pchg_st_e[6:0]
NV3041_SPI_Write_data(0x02);
NV3041_SPI_Write_cmd(0x5d);//src_pchg_wd_e[6:0]
NV3041_SPI_Write_data(0x3c);
NV3041_SPI_Write_cmd(0x5e);//src_pol_sw[7:0]
NV3041_SPI_Write_data(0x1f);
NV3041_SPI_Write_cmd(0x60);//src_op_st_o[7:0]
NV3041_SPI_Write_data(0x80);
NV3041_SPI_Write_cmd(0x61);//src_op_st_e[7:0]
NV3041_SPI_Write_data(0x3f);
NV3041_SPI_Write_cmd(0x62);//src_op_ed_o[9:8] src_op_ed_e[9:8]
NV3041_SPI_Write_data(0x21);
NV3041_SPI_Write_cmd(0x63);//src_op_ed_o[7:0]
NV3041_SPI_Write_data(0x07);
NV3041_SPI_Write_cmd(0x64);//src_op_ed_e[7:0]
NV3041_SPI_Write_data(0xe0);
NV3041_SPI_Write_cmd(0x65);//chopper
NV3041_SPI_Write_data(0x01);//01-A2,02--A1
NV3041_SPI_Write_cmd(0xca); //avdd_mux_st_o[7:0]
NV3041_SPI_Write_data(0x20);
NV3041_SPI_Write_cmd(0xcb); //avdd_mux_ed_o[7:0]
NV3041_SPI_Write_data(0x52);
NV3041_SPI_Write_cmd(0xcc); //avdd_mux_st_e[7:0]
NV3041_SPI_Write_data(0x10);
NV3041_SPI_Write_cmd(0xcD); //avdd_mux_ed_e[7:0]
NV3041_SPI_Write_data(0x42);
NV3041_SPI_Write_cmd(0xD0); //avcl_mux_st_o[7:0]
NV3041_SPI_Write_data(0x20);
NV3041_SPI_Write_cmd(0xD1); //avcl_mux_ed_o[7:0]
NV3041_SPI_Write_data(0x52);
NV3041_SPI_Write_cmd(0xD2); //avcl_mux_st_e[7:0]
NV3041_SPI_Write_data(0x10);
NV3041_SPI_Write_cmd(0xD3); //avcl_mux_ed_e[7:0]
NV3041_SPI_Write_data(0x42);
NV3041_SPI_Write_cmd(0xD4); //vgh_mux_st[7:0]
NV3041_SPI_Write_data(0x0a);
NV3041_SPI_Write_cmd(0xD5); //vgh_mux_ed[7:0]
NV3041_SPI_Write_data(0x32);
NV3041_SPI_Write_cmd(0xe5); //DVDD_TRIM
NV3041_SPI_Write_data(0x06); //1.65 05
NV3041_SPI_Write_cmd(0xe6); //ESD_CTRL
NV3041_SPI_Write_data(0x00);
NV3041_SPI_Write_cmd(0x6e); //LVD_en
NV3041_SPI_Write_data(0x14);
//gammma 01
NV3041_SPI_Write_cmd(0x80); //gam_vrp0 63
NV3041_SPI_Write_data(0x02);//04
NV3041_SPI_Write_cmd(0xA0); //gam_VRN0 63
NV3041_SPI_Write_data(0x02);//00
NV3041_SPI_Write_cmd(0x81); //gam_vrp1 62
NV3041_SPI_Write_data(0x04);//07
NV3041_SPI_Write_cmd(0xA1); //gam_VRN1 62-
NV3041_SPI_Write_data(0x04);//05
NV3041_SPI_Write_cmd(0x82); //gam_vrp2 61
NV3041_SPI_Write_data(0x01);//06
NV3041_SPI_Write_cmd(0xA2); //gam_VRN2 61-
NV3041_SPI_Write_data(0x01);//04
NV3041_SPI_Write_cmd(0x83); //gam_vrp3 2
NV3041_SPI_Write_data(0x07);//39
NV3041_SPI_Write_cmd(0xA3); //gam_VRN3 2-
NV3041_SPI_Write_data(0x07);//39
NV3041_SPI_Write_cmd(0x84); //gam_vrp4 1
NV3041_SPI_Write_data(0x0a);//3A
NV3041_SPI_Write_cmd(0xA4); //gam_VRN4 1-
NV3041_SPI_Write_data(0x0a);//3A
NV3041_SPI_Write_cmd(0x85); //gam_vrp5 0
NV3041_SPI_Write_data(0x0f);//3F
NV3041_SPI_Write_cmd(0xA5); //gam_VRN5 0-
NV3041_SPI_Write_data(0x0f);//3F
NV3041_SPI_Write_cmd(0x86); //gam_prp0 50
NV3041_SPI_Write_data(0x13);//2C
NV3041_SPI_Write_cmd(0xA6); //gam_PRN0 50-
NV3041_SPI_Write_data(0x13);//2a
NV3041_SPI_Write_cmd(0x87); //gam_prp1 14
NV3041_SPI_Write_data(0x17);//43//19
NV3041_SPI_Write_cmd(0xA7); //gam_PRN1 14-
NV3041_SPI_Write_data(0x1b);//47//19
NV3041_SPI_Write_cmd(0x88); //gam_pkp0 59
NV3041_SPI_Write_data(0x07);//08
NV3041_SPI_Write_cmd(0xA8); //gam_PKN0 59-
NV3041_SPI_Write_data(0x07);//08
NV3041_SPI_Write_cmd(0x89); //gam_pkp1 57
NV3041_SPI_Write_data(0x0f);//0F
NV3041_SPI_Write_cmd(0xA9); //gam_PKN1 57-
NV3041_SPI_Write_data(0x0E);//0F
NV3041_SPI_Write_cmd(0x8a); //gam_pkp2 54
NV3041_SPI_Write_data(0x17);//1a
NV3041_SPI_Write_cmd(0xAa); //gam_PKN2 54-
NV3041_SPI_Write_data(0x17);//1a
NV3041_SPI_Write_cmd(0x8b); //gam_PKP3 44
NV3041_SPI_Write_data(0x11);//10
NV3041_SPI_Write_cmd(0xAb); //gam_PKN3 44-
NV3041_SPI_Write_data(0x10);//10
NV3041_SPI_Write_cmd(0x8c); //gam_PKP4 38
NV3041_SPI_Write_data(0x16);//16
NV3041_SPI_Write_cmd(0xAc); //gam_PKN4 38-
NV3041_SPI_Write_data(0x16);//16
NV3041_SPI_Write_cmd(0x8d); //gam_PKP5 32
NV3041_SPI_Write_data(0x15);//14
NV3041_SPI_Write_cmd(0xAd); //gam_PKN5 32-
NV3041_SPI_Write_data(0x15);//14
NV3041_SPI_Write_cmd(0x8e); //gam_PKP6 26
NV3041_SPI_Write_data(0x14);//11
NV3041_SPI_Write_cmd(0xAe); //gam_PKN6 26-
NV3041_SPI_Write_data(0x14);//11
NV3041_SPI_Write_cmd(0x8f); //gam_PKP7 20
NV3041_SPI_Write_data(0x16);//14//16
NV3041_SPI_Write_cmd(0xAf); //gam_PKN7 20-
NV3041_SPI_Write_data(0x16);//14//16
NV3041_SPI_Write_cmd(0x90); //gam_PKP8 10
NV3041_SPI_Write_data(0x06);//06
NV3041_SPI_Write_cmd(0xB0); //gam_PKN8 10-
NV3041_SPI_Write_data(0x06);//06
NV3041_SPI_Write_cmd(0x91); //gam_PKP9 6
NV3041_SPI_Write_data(0x0f);//0F//0f
NV3041_SPI_Write_cmd(0xB1); //gam_PKN9 6-
NV3041_SPI_Write_data(0x0e);//0F//0e
NV3041_SPI_Write_cmd(0x92); //gam_PKP10 4
NV3041_SPI_Write_data(0x14);//16
NV3041_SPI_Write_cmd(0xB2); //gam_PKN10 4-
NV3041_SPI_Write_data(0x14);//16
NV3041_SPI_Write_cmd(0xff);
NV3041_SPI_Write_data(0x00);
NV3041_SPI_Write_cmd(0x11);
time_delay(200);
NV3041_SPI_Write_cmd(0x29);
time_delay(120);
printf("发送完成");
}
/**
* @brief 简单的读取ID尝试
*/
void Simple_Read_ID_Test(void) {
// 先发送读ID命令
NV3041_SPI_Write_cmd(0x04); // RD_SYSID
// 然后尝试读取(可能需要在读之前加延时)
// Delayms(10);
// 尝试读取一个字节
set_data_bus_input();
CS_GPIO_LOW(); // 片选
DC_GPIO_HIGH();
RD_GPIO_HIGH();
time_delay(5);
RD_GPIO_LOW();
time_delay(5);
RD_GPIO_HIGH();
time_delay(5);
uint8_t data = read_data_bus();
CS_GPIO_HIGH();
set_data_bus_output();
printf("读取到的第一个字节: 0x%02X\r\n", data);
}
void func_test(void)
{
printf("func_test");
NV3041A_lcd_driver();
time_delay(200);
// 填充整个屏幕为红色
NV3041_FillScreen(RGB565_RED);
while(1)
{
// os_time_dly(300); //3秒
NV3041_FillScreen(RGB565_RED);
// os_time_dly(300);
NV3041_FillScreen(RGB565_GREEN);
// os_time_dly(300);
NV3041_FillScreen(RGB565_BLUE);
}
// while(1)
// {
// WR_GPIO_LOW();
// WR_GPIO_HIGH();
// }
}
void k_test(void)
{
NV3041_SPI_Write_cmd(0xff);
NV3041_SPI_Write_data(0xa5);
NV3041_SPI_Write_cmd(0xE7);//TE_output_en
NV3041_SPI_Write_data(0x10);
NV3041_SPI_Write_cmd(0x35);//TE_ interface_en
NV3041_SPI_Write_data(0x01);
}
void minimal_test(void) {
// 只做最基础的初始化
// check_reset();
NV3041_SPI_Write_cmd(0x11); // Sleep Out
time_delay(120);
NV3041_SPI_Write_cmd(0x29); // Display On
time_delay(50);
// 如果这样屏幕能亮,说明电源基本正常
}
void lcd_reset(void)
{
RESET_GPIO_HIGH();
time_delay(100);
RESET_GPIO_LOW();
time_delay(200);
RESET_GPIO_HIGH();
time_delay(100);
}
void lcd_init(void)
{
printf("lcd_init");
NV3041A_lcd_gpio_init();
lcd_reset();
// Simple_Read_ID_Test();
// sys_timeout_add_to_task("sys_timer", NULL, func_test, 2000);
if (thread_fork("func_test", 10, 512, 0, &kph_para.lcd_init_id, func_test, NULL) != OS_NO_ERR)
{
printf("thread fork fail\n");
}
}
.h
#ifndef __K_NV3041A_LCD_DRIVER_H__
#define __K_NV3041A_LCD_DRIVER_H__
#include "app_config.h"
#include "system/includes.h"
#include "device/device.h"
#include <time.h>
#include <sys/time.h>
#include "device/gpio.h"
#include "asm/gpio.h"
#include "wifi/wifi_connect.h"
#include "server/audio_server.h"
#include "asm/port_waked_up.h"
#define WIDTH 480
#define HEIGHT 272
/**
* @brief RGB565颜色宏定义
*/
#define RGB565_RED 0xF800 // 红色: 11111 000000 00000
#define RGB565_GREEN 0x07E0 // 绿色: 00000 111111 00000
#define RGB565_BLUE 0x001F // 蓝色: 00000 000000 11111
#define RGB565_WHITE 0xFFFF // 白色: 11111 111111 11111
#define RGB565_BLACK 0x0000 // 黑色: 00000 000000 00000
#define RGB565_YELLOW 0xFFE0 // 黄色: 11111 111111 00000
#define LCD_DATA_D0 IO_PORTC_01
#define LCD_DATA_D1 IO_PORTC_02
#define LCD_DATA_D2 IO_PORTC_03
#define LCD_DATA_D3 IO_PORTC_04
#define LCD_DATA_D4 IO_PORTC_05
#define LCD_DATA_D5 IO_PORTC_06
#define LCD_DATA_D6 IO_PORTC_07
#define LCD_DATA_D7 IO_PORTC_08
#define LCD_TE IO_PORTH_04
#define LCD_DC IO_PORTH_03
#define LCD_RD IO_PORTC_09
#define LCD_WR IO_PORTC_10
#define LCD_CS IO_PORTC_00
#define LCD_RESET IO_PORTH_05
#define LCD_D0_HIGH() gpio_direction_output(LCD_DATA_D0,1)
#define LCD_D0_LOW() gpio_direction_output(LCD_DATA_D0,0)
#define LCD_D1_HIGH() gpio_direction_output(LCD_DATA_D1,1)
#define LCD_D1_LOW() gpio_direction_output(LCD_DATA_D1,0)
#define LCD_D2_HIGH() gpio_direction_output(LCD_DATA_D2,1)
#define LCD_D2_LOW() gpio_direction_output(LCD_DATA_D2,0)
#define LCD_D3_HIGH() gpio_direction_output(LCD_DATA_D3,1)
#define LCD_D3_LOW() gpio_direction_output(LCD_DATA_D3,0)
#define LCD_D4_HIGH() gpio_direction_output(LCD_DATA_D4,1)
#define LCD_D4_LOW() gpio_direction_output(LCD_DATA_D4,0)
#define LCD_D5_HIGH() gpio_direction_output(LCD_DATA_D5,1)
#define LCD_D5_LOW() gpio_direction_output(LCD_DATA_D5,0)
#define LCD_D6_HIGH() gpio_direction_output(LCD_DATA_D6,1)
#define LCD_D6_LOW() gpio_direction_output(LCD_DATA_D6,0)
#define LCD_D7_HIGH() gpio_direction_output(LCD_DATA_D7,1)
#define LCD_D7_LOW() gpio_direction_output(LCD_DATA_D7,0)
#define WR_GPIO_HIGH() gpio_direction_output(LCD_WR,1)
#define WR_GPIO_LOW() gpio_direction_output(LCD_WR,0)
//DCX = “H” is data DCX = “L” is command
#define DC_GPIO_LOW() gpio_direction_output(LCD_DC,0)
#define DC_GPIO_HIGH() gpio_direction_output(LCD_DC,1)
#define CS_GPIO_LOW() gpio_direction_output(LCD_CS,0)
#define CS_GPIO_HIGH() gpio_direction_output(LCD_CS,1)
//低电平复位,高电平正常工作
#define RESET_GPIO_LOW() gpio_direction_output(LCD_RESET,0)
#define RESET_GPIO_HIGH() gpio_direction_output(LCD_RESET,1)
//下降沿屏幕发送数据到总线上,上升沿总线上数据被读取
#define RD_GPIO_LOW() gpio_direction_output(LCD_RD,0)
#define RD_GPIO_HIGH() gpio_direction_output(LCD_RD,1)
#endif
更多推荐



所有评论(0)