本帖最后由 qjp1988113 于 2021-10-24 21:19 编辑
套件没有屏幕。但好在LCD的接口兼容原子的。我手里有块不知道几手的驱动为NT35310 LCD~正好拿来用~这了用并口8080的方式驱动,GD32F303这个用EXMC 的驱动方式来驱动,它跟
STM32的FSMC几乎相同~
让我们先来看看外部存储器控制器(EXMC) :
外部存储器控制器EXMC,用来访问各种片外存储器,通过配置寄存器,EXMC可以把AMBA协议转换为专用的片外存储器
通信协议,包括SRAM,ROM,NOR Flash,NAND Flash,PC卡。用户还可以调整配置寄存器中的时间参数来提高通信效率。EXMC的访问空间被划分为许多个块(Bank),每个块支持特定的存储器类型,用户可以通过对Bank的控制寄存器配置来控制外部存储器。
主要特性
支持片外存储器类型:
SRAM;PSRAM;ROM;NOR Flash;8 位或 16 位 NAND Flash;16 位 PC Card;
AMBA 协议与各种片外存储器协议转换;
时序参数可编程可以满足用户特定需求;
每个 Bank 有独立的片选信号;
对于部分存储器类型支持独立的读写时序;
对于 NAND Flash 内置硬件 ECC;
支持 8 位,或 16 位总线带宽;
NOR Flash 和 PSRAM 支持地址总线和数据总线的复用;
提供写使能和字节选择信号;
当 AMBA 总线宽度与外部存储器数据宽度不同时,会自动分割操作。
我们看看他们的地址区域划分:
我们这了选用BANK0,我们看下它的地址映射~
我们对LCD主要要确定的就是它映射后读写的地址:
//使用NOR/SRAM的 Bank0.sector1,地址位HADDR[27,26]=01 A23作为数据命令区分线
//注意设置时GD32内部会右移一位对其! (时间设备的地址往左移一位与GD32内部地址才对对应)
//由于使用半字(16BIT)的连接方式,MCU内部地址线HADDR[25:1]→ FSMC_A[24:0]
//即实际连线的位置往左移动一格,才与实际MCU地址对其
//这里选择A23作为数据线,实际A23对于地址0x800000 对于MCU地址需往左移一位即0x1000000
//那么当A23=0时,即LCD_RS=0时,地址0x64000000
//那么当A23=1时,即LCD_RS=1时,地址0x64000000+0x1000000=0x65000000
#define BANK0_LCD_D ((uint32_t)0x65000000) /*!< LCD data address */
#define BANK0_LCD_C ((uint32_t)0x64000000) /*!< LCD register address */
这样我们就得到了它地址的由来,然后直接读写地址,即可完成LCD的控制~
lcd.h(仅修改读写地址,其他未改变)
- #ifndef __LCD_H
- #define __LCD_H
- #include "sys.h"
- #include "stdlib.h"
- //////////////////////////////////////////////////////////////////////////////////
- //LCD重要参数集
- typedef struct
- {
- u16 width; //LCD 宽度
- u16 height; //LCD 高度
- u16 id; //LCD ID
- u8 dir; //横屏还是竖屏控制:0,竖屏;1,横屏。
- u16 wramcmd; //开始写gram指令
- u16 setxcmd; //设置x坐标指令
- u16 setycmd; //设置y坐标指令
- }_lcd_dev;
- //LCD参数
- extern _lcd_dev lcddev; //管理LCD重要参数
- //LCD的画笔颜色和背景色
- extern u16 POINT_COLOR;//默认红色
- extern u16 BACK_COLOR; //背景颜色.默认为白色
- //////////////////////////////////////////////////////////////////////////////////
- //-----------------LCD端口定义----------------
- #define LCD_LED PBout(11) //LCD背光 PB11
- //使用NOR/SRAM的 Bank0.sector1,地址位HADDR[27,26]=01 A23作为数据命令区分线
- //注意设置时GD32内部会右移一位对其! (时间设备的地址往左移一位与GD32内部地址才对对应)
- //由于使用半字(16BIT)的连接方式,MCU内部地址线HADDR[25:1]→ FSMC_A[24:0]
- //即实际连线的位置往左移动一格,才与实际MCU地址对其
- //这里选择A23作为数据线,实际A23对于地址0x800000 对于MCU地址需往左移一位即0x1000000
- //那么当A23=0时,即LCD_RS=0时,地址0x64000000
- //那么当A23=1时,即LCD_RS=1时,地址0x64000000+0x1000000=0x65000000
- #define BANK0_LCD_D ((uint32_t)0x65000000) /*!< LCD data address */
- #define BANK0_LCD_C ((uint32_t)0x64000000) /*!< LCD register address */
lcd.c(主要都对写命令和数据做了修改,其他不变)
- #include "lcd.h"
- #include "stdlib.h"
- #include "font.h"
- #include "usart.h"
- #include "delay.h"
- //LCD的画笔颜色和背景色
- u16 POINT_COLOR=0x0000; //画笔颜色
- u16 BACK_COLOR=0xFFFF; //背景色
-
- //管理LCD重要参数
- //默认为竖屏
- _lcd_dev lcddev;
-
- //写寄存器函数 CMD
- //regval:寄存器值
- void LCD_WR_REG(u16 regval)
- {
- *(__IO uint16_t *) (BANK0_LCD_C) = regval;;//写入要写的寄存器序号
- }
- //写LCD数据
- //data:要写入的值 DATA
- void LCD_WR_DATA(u16 data)
- {
- *(__IO uint16_t *) (BANK0_LCD_D)= data;
- }
- //读LCD数据
- //返回值:读到的值
- u16 LCD_RD_DATA(void)
- {
- vu16 ram; //防止被优化
- ram = *(__IO uint16_t *) (BANK0_LCD_D);
- return ram;
- }
- //写寄存器
- //LCD_Reg:寄存器地址
- //LCD_RegValue:要写入的数据
- void LCD_WriteReg(u16 LCD_Reg,u16 LCD_RegValue)
- {
- *(__IO uint16_t *) (BANK0_LCD_C)= LCD_Reg;//写入要写的寄存器序号
- *(__IO uint16_t *) (BANK0_LCD_D)= LCD_RegValue; //写入数据
- }
- //读寄存器
- //LCD_Reg:寄存器地址
- //返回值:读到的数据
- u16 LCD_ReadReg(u16 LCD_Reg)
- {
- *(__IO uint16_t *) (BANK0_LCD_C)= LCD_Reg;//写入要读的寄存器序号
- delay_us(5);
- return LCD_RD_DATA(); //返回读到的值
- }
- //开始写GRAM
- void LCD_WriteRAM_Prepare(void)
- {
- *(__IO uint16_t *) (BANK0_LCD_C)=lcddev.wramcmd;
- }
- //LCD写GRAM
- //RGB_Code:颜色值
- void LCD_WriteRAM(u16 RGB_Code)
- {
- *(__IO uint16_t *) (BANK0_LCD_D) = RGB_Code;//写十六位GRAM
- }
在main函数里面调用:
- LCD_Init();
- KEY_Init(); //按键初始化
- POINT_COLOR=RED;
- sprintf((char*)lcd_id,"LCD ID:%04X",lcddev.id);//将LCD ID打印到lcd_id数组。
- while(1)
- {
- switch(x)
- {
- case 0:LCD_Clear(WHITE);break;
- case 1:LCD_Clear(BLACK);break;
- case 2:LCD_Clear(BLUE);break;
- case 3:LCD_Clear(RED);break;
- case 4:LCD_Clear(MAGENTA);break;
- case 5:LCD_Clear(GREEN);break;
- case 6:LCD_Clear(CYAN);break;
- case 7:LCD_Clear(YELLOW);break;
- case 8:LCD_Clear(BRRED);break;
- case 9:LCD_Clear(GRAY);break;
- case 10:LCD_Clear(LGRAY);break;
- case 11:LCD_Clear(BROWN);break;
- }
- POINT_COLOR=RED;
- LCD_ShowString(30,40,240,24,24,"OPENIOT GD32F302 ^_^");
- LCD_ShowString(30,70,200,16,16,"TFTLCD TEST");
- LCD_ShowString(30,90,200,16,16,"qjp1988113@elecfans");
- LCD_ShowString(30,110,200,16,16,lcd_id); //显示LCD ID
- LCD_ShowString(30,130,200,12,12,"2021/10/24");
- x++;
- if(x==12)x=0;
- LED0=!LED0;
- delay_ms(1000);
- }
- }
这了驱动移植自正点原子,理论可用它支持的所有屏幕。
(//2.4寸/2.8寸/3.5寸/4.3寸/7寸 TFT液晶驱动
//支持驱动IC型号包括:ILI9341/ILI9325/RM68042/RM68021/ILI9320/ILI9328/LGDP4531/LGDP4535/
// SPFD5408/1505/B505/C505/NT35310/NT35510/SSD19)
编译下载查看: