特征
- 三个独立芯片选择引脚,可设置极性,支持三个设备,时序独立设置
- 数据总线和地址总线分开。
- 每个设备支持1MB空间
- 8/16位数据宽度
- 支持8080模式LCD接口
- 支持PDMA
- 支持设置读写空闲时间
- 可选内部HCLK分频得到MCLK或者外部EBI_MCLK
- 支持地址总线和数据总线分开
配置
- 时钟使能
EBI (CLK_HCLKEN[9])
- 复位模块
EBIRST (SYS_AHBIPRST[3])
- 引脚

功能
地址映射
三个片选分别对应地址如下:

连接
地址总线和数据总线分开模式


读写时序

tASU:地址建立时间,CS拉低到RD或WR拉低的时间,连续读模式CACCESS=1,tASU不需要.
tACC:RD,WD拉低的时间,数据访问时间,即给对方去读数据的时间。
tAHD:数据保持时间,即RD,WR拉高后到CS拉高的时间。
寄存器
使用EBI驱动LCD设计
硬件设计
LCD选型

对应如下:


(链接就不上了,可以以图搜图搜索购买同款)
原理图和PCB设计
使用KiCAD设计了原理图和PCB

生产焊接


在生产时刚好淘宝下单将BOM表的物料采购下,我手里大部分都有就买了个FFC的座子,和2.54的排母。
打样加上物料30块多点就搞定了。
焊接手工,十来分钟就搞定了。
回来的PCB


焊接之后,由于手头没有洗板水所以焊接后残留很多松香渣滓,可以买点高浓度酒精97%以上清洗下。
插入到开发板
原理分析
用的CS0片选,所以地址空间为0x6000_0000 ~ 0x600F_FFFF

由于RS引脚接到了ADDR10,而且使用的是16bit模式,所以地址中的1<<11位对应ADDR10即RS。
如果是8位模式则一一对应,地址中的1<<10位对应ADDR10即RS
写地址0x | 1<<11则ADDR10为1,RS=1表示数据
写地址0x | 0<< 11则ADDR10为0,RS=0表示命令
所以读写命令或者数据只需要读写地址0x | 1<<11和0x | 0<< 11即可。
液晶屏的参数如下

根据以上
先确认HCLK时钟分频2^x次得到MCLK,x=0~7最大分频128。
sysGetClock(SYS_HCLK))可以获取HCLK单位为M
分频x则MCLK为x/HCLK uS = 1000*x/HCLK nS
nu_clocks可以打印当前时钟配置
代码编写
见lcd.c
#include <rtconfig.h> #include <rtdevice.h> #include "nuc980.h" #include "nu_ebi.h" #include "nu_sys.h" #include <rthw.h> #include <drv_gpio.h> #define LCD_XSIZE 320 #define LCD_YSIZE 240 #define CMD_ADDR (0x | 0u<<11) #define DAT_ADDR (0x | 1u<<11) #define LLCD_WRITE_CMD(cmd) *((volatile uint16_t*)CMD_ADDR)=cmd #define LLCD_WRITE_DATA(dat) *((volatile uint16_t*)DAT_ADDR)=dat #define LLCD_READ_DATA() *((volatile uint16_t*)DAT_ADDR) #define MCLK_DIVSET 5 /* 0~7 75m 26ns */ #define MCLK_DIVVAL 32 /* 1~128分频 */ #define R2R 100 /* >10nS */ #define W2X 100 /* >10nS */ #define TAHD 100 /* >10nS */ #define TACC 3000 /* >355nS */ void lcd_init(void) { uint32_t hclk = sysGetClock(SYS_HCLK); uint32_t r2r; uint32_t w2x; uint32_t tahd; uint32_t tacc; /* 1. 引脚配置 */ /* PA12背光 EBI_ADDR8 */ rt_pin_mode(NU_GET_PININDEX(NU_PA, 12), PIN_MODE_OUTPUT); /* PA11复位 EBI_ADDR9 */ rt_pin_mode(NU_GET_PININDEX(NU_PA, 11), PIN_MODE_OUTPUT); /* PA10 EBI_ADDR10 (LCD_RS) MFP1 PA9 EBI_nCS0 MFP1 PA8 EBI_nRE MFP1 PA7 EBI_nWE MFP1 PC0~PC15 EBI_DATA0~EBI_DATA15 MFP1 */ M32(REG_SYS_GPC_MFPL) = 0x; /*PC0~PC15 MFP1 */ M32(REG_SYS_GPC_MFPH) = 0x; M32(REG_SYS_GPA_MFPL) = (M32(REG_SYS_GPA_MFPL) & 0x0FFFFFFF) | 0x; /* PA7 MFP1 */ M32(REG_SYS_GPA_MFPH) = (M32(REG_SYS_GPA_MFPH) & 0xFFFFF000) | 0x00000111; /* PA8 PA9 PA10 MFP1 */ /* 2. 时钟配置 */ M32(REG_CLK_HCLKEN) |= (1u<<9); /* 使能时钟 */ /* 3. 复位 */ M32(REG_SYS_AHBIPRST) |= (1u<<3); /* 复位EBI */ M32(REG_SYS_AHBIPRST) &= ~(1u<<3); /* 结束复位 */ /* 4. 时序 */ EBI->CTL0 |= 1u<<24; /* EBI write buffer Enabled */ EBI->CTL0 = (EBI->CTL0 & (~(0x07<<8))) | (MCLK_DIVVAL<<8); EBI->CTL0 |= 0u<<4; /* Continuous data access mode tASU cycle is bypass. */ EBI->CTL0 |= 1u<<1; /* 16bit. */ r2r = R2R/(1000*MCLK_DIVVAL/hclk) & 0x0F; if(r2r==0) { r2r=1; } w2x = W2X/(1000*MCLK_DIVVAL/hclk) & 0x0F; if(w2x==0) { w2x=1; } tahd = TAHD/(1000*MCLK_DIVVAL/hclk) & 0x07; if(tahd==0) { tahd=1; } tacc = TACC/(1000*MCLK_DIVVAL/hclk) & 0x1F; if(tacc==0) { tacc=1; } EBI->TCTL0 = (r2r<<24) | (0 <<23) | (0<<22) | (w2x<<12) | ((tahd-1)<<8) | ((tacc-1)<<3); EBI->CTL0 |= 1u<<0; /* EBI function Enabled. */ /* 5. LCD复位 */ rt_pin_write(NU_GET_PININDEX(NU_PA, 11), PIN_LOW); /* 手册P48 延时大于10uS */ rt_thread_mdelay(1); rt_pin_write(NU_GET_PININDEX(NU_PA, 11), PIN_HIGH); /* LCD寄存器初始化 */ rt_thread_mdelay(120); //---------------------------------------------------------------------------------------------------// LLCD_WRITE_CMD (0x11); rt_thread_mdelay(120); //Delay 120ms //------------------------------display and color format setting--------------------------------// LLCD_WRITE_CMD (0x36); LLCD_WRITE_DATA (0x00); LLCD_WRITE_CMD (0x3a); LLCD_WRITE_DATA (0x05); //--------------------------------ST7789V Frame rate setting----------------------------------// LLCD_WRITE_CMD (0xb2); LLCD_WRITE_DATA (0x0c); LLCD_WRITE_DATA (0x0c); LLCD_WRITE_DATA (0x00); LLCD_WRITE_DATA (0x33); LLCD_WRITE_DATA (0x33); LLCD_WRITE_CMD (0xb7); LLCD_WRITE_DATA (0x35); //---------------------------------ST7789V Power setting--------------------------------------// LLCD_WRITE_CMD (0xbb); LLCD_WRITE_DATA (0x28); LLCD_WRITE_CMD (0xc0); LLCD_WRITE_DATA (0x2c); LLCD_WRITE_CMD (0xc2); LLCD_WRITE_DATA (0x01); LLCD_WRITE_CMD (0xc3); LLCD_WRITE_DATA (0x0b); LLCD_WRITE_CMD (0xc4); LLCD_WRITE_DATA (0x20); LLCD_WRITE_CMD (0xc6); LLCD_WRITE_DATA (0x0f); LLCD_WRITE_CMD (0xd0); LLCD_WRITE_DATA (0xa4); LLCD_WRITE_DATA (0xa1); //--------------------------------ST7789V gamma setting---------------------------------------// LLCD_WRITE_CMD (0xe0); LLCD_WRITE_DATA (0xd0); LLCD_WRITE_DATA (0x01); LLCD_WRITE_DATA (0x08); LLCD_WRITE_DATA (0x0f); LLCD_WRITE_DATA (0x11); LLCD_WRITE_DATA (0x2a); LLCD_WRITE_DATA (0x36); LLCD_WRITE_DATA (0x55); LLCD_WRITE_DATA (0x44); LLCD_WRITE_DATA (0x3a); LLCD_WRITE_DATA (0x0b); LLCD_WRITE_DATA (0x06); LLCD_WRITE_DATA (0x11); LLCD_WRITE_DATA (0x20); LLCD_WRITE_CMD (0xe1); LLCD_WRITE_DATA (0xd0); LLCD_WRITE_DATA (0x02); LLCD_WRITE_DATA (0x07); LLCD_WRITE_DATA (0x0a); LLCD_WRITE_DATA (0x0b); LLCD_WRITE_DATA (0x18); LLCD_WRITE_DATA (0x34); LLCD_WRITE_DATA (0x43); LLCD_WRITE_DATA (0x4a); LLCD_WRITE_DATA (0x2b); LLCD_WRITE_DATA (0x1b); LLCD_WRITE_DATA (0x1c); LLCD_WRITE_DATA (0x22); LLCD_WRITE_DATA (0x1f); LLCD_WRITE_CMD (0x29); /* 开背光 */ rt_pin_write(NU_GET_PININDEX(NU_PA, 12), PIN_HIGH); #if 0 /* 逻辑分析仪测试波形使用 */ while(1) { LLCD_WRITE_CMD(0x00); LLCD_WRITE_CMD(0x01); LLCD_WRITE_CMD(0x02); LLCD_WRITE_CMD(0x03); LLCD_WRITE_DATA(0x00); LLCD_WRITE_DATA(0x01); LLCD_WRITE_DATA(0x02); LLCD_WRITE_DATA(0x03); LLCD_READ_DATA(); rt_thread_mdelay(1); } #endif } void lcd_setpoint(uint16_t x ,uint16_t y, uint16_t color) { LLCD_WRITE_CMD(0x2A); LLCD_WRITE_DATA(x>>8); LLCD_WRITE_DATA(x&0XFF); LLCD_WRITE_CMD(0x2B); LLCD_WRITE_DATA(y>>8); LLCD_WRITE_DATA(y&0XFF); LLCD_WRITE_CMD(0x2C); LLCD_WRITE_DATA(color); } void lcd_clear(uint16_t color) { LLCD_WRITE_CMD(0x2A); LLCD_WRITE_DATA(0); LLCD_WRITE_DATA(0); LLCD_WRITE_CMD(0x2B); LLCD_WRITE_DATA(0); LLCD_WRITE_DATA(0); LLCD_WRITE_CMD(0x2C); for(uint32_t i=0;i<LCD_XSIZE*LCD_YSIZE;i++) { LLCD_WRITE_DATA(color); } }
讯享网
硬件/时序调试
焊接完后要先确认是否有短路,再上电。
讯享网 #if 0 /* 逻辑分析仪测试波形使用 */ while(1) { LLCD_WRITE_CMD(0x00); LLCD_WRITE_CMD(0x01); LLCD_WRITE_CMD(0x02); LLCD_WRITE_CMD(0x03); LLCD_WRITE_DATA(0x00); LLCD_WRITE_DATA(0x01); LLCD_WRITE_DATA(0x02); LLCD_WRITE_DATA(0x03); LLCD_READ_DATA(); rt_thread_mdelay(1); } #endif

刷屏测试
#if LCD_TEST lcd_clear(0xF800); rt_thread_mdelay(1000); lcd_clear(0x07E00); rt_thread_mdelay(1000); lcd_clear(0x0001F); rt_thread_mdelay(1000); #endif
源码
NK-980IOT-TEST: NK-980IOT-TEST
LCD相关资料在lcd-pcb目录下。
总结
EBI接口驱动8080接口的LCD非常方便,本次设计也比较顺利,一次就成功,其中逻辑分析仪非常重要,用来分析时序没有他不行,另外嘉立创的打样活动非常不错,可以去看看。
下次测试下性能,优化下时序,将时序尽可能提高到最快,尽可能提高刷屏速度。
后面再移植GUI,暂时选定lvgl或者emwin。
后面再添加ADC测评,添加驱动支持。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/51633.html