stm32学习总结 FMC 驱动LCD

news2024/12/28 6:03:04

1, 显示器分类(了解)

在这里插入图片描述
全彩显示,LCD具有更多的优势,适合在单片机上使用

2, LCD简介(了解)

Liquid Crystal Display,即液晶显示器,由:玻璃基板、背光、驱动IC等组成
全彩LCD,是一种全彩显示屏(RGB565、RGB888),可以显示各种颜色
1,低成本:低至几块钱的价格
2,高解析度 :可高达500ppi的解析度,显示细腻
PPI(Pixels Per Inch)[4],从字面意思理解就是每英寸像素,也可以理解为屏幕像素密度,因为像素并没有固定的大小,所以,PPI 越高,像素大小越小,也就越清晰。具体的计算公式如下:
3,高对比度: 可高达1000 : 1的对比度,色彩清晰艳丽
4,响应速度快:可高达1ms响应速度,显示效果好
对比度指的是一幅图像中明暗区域最亮的白和最暗的黑之间不同亮度层级的测量,差异范围越大代表对比越大,差异范围越小代表对比越小,

LCD基本组成
1,玻璃基板
2,背光
3,驱动IC

LCD接口分类
在这里插入图片描述
MCU屏接口由于自带SRAM,驱动简单,大部分单片机都能驱动!
MCU接口:
2.8寸电阻触摸屏
3.5寸电阻触摸屏
4.3寸电容触摸屏
7寸电容触摸屏V2
RGB接口:
4.3寸480272触摸屏
4.3寸800
480触摸屏
7寸800480触摸屏
7寸1024
600触摸屏
10.1寸1280*800触摸屏
ILI9341芯片
ILI9341芯片支持多种通信接口。
MCU接口(8/9/16/18位)
3/4 线SPI接口
RGB接口(6/16/18位)
在这里插入图片描述
三基色原理
无法通过其他颜色混合得到的颜色,称之为:基本色
通过三基色混合,可以得到自然界中绝大部分颜色!
电脑一般用32位来表示一个颜色(ARGB888):
在这里插入图片描述
单片机一般用16/24位表示一个颜色(RGB565/RGB888):
在这里插入图片描述
在这里插入图片描述

3, LCD驱动原理(熟悉)

LCD屏(MCU接口)驱动的核心是:驱动LCD驱动芯片
LCD驱动基本知识:
1,8080时序,LCD驱动芯片一般使用8080时序控制,实现数据写入/读取
2,初始化序列(数组),屏厂提供,用于初始化特定屏幕,不同屏幕厂家不完全相同!
3,画点函数、读点函数(非必需),基于这两个函数可以实现各种绘图功能!
LCD驱动的一般过程
在这里插入图片描述
8080时序简介
并口总线时序,常用于MCU屏驱动IC的访问,由Intel提出,也叫英特尔总线
LCD 8080时序信号说明
在这里插入图片描述
8080写时序
数据(RS=1)/命令(RS=0)在WR的上升沿,写入LCD驱动IC,RD保持高电平
在这里插入图片描述
8080读时序
数据(RS=1)/命令(RS=0)在RD的上升沿,读取到MCU,WR保持高电平
在这里插入图片描述
8080读写简化代码

void lcd_wr_data(uint16_t data)
{
    	LCD_RS(1);		/* 操作数据 */
    	LCD_CS(0);		/* 选中 */
    	LCD_DATA_OUT(data);	/* 数据 */
    	LCD_WR(0);		/* WR低电平 */
    	LCD_WR(1);		/* WR高电平 */
    	LCD_CS(1);		/* 释放片选 */
}
uint16_t  lcd_rd_data(void)
{
	uint16_t ram;  			/* 定义变量 */
 	LCD_RS(1);              		/* 操作数据 */
    	LCD_CS(0);			/* 选中 */
    	LCD_RD(0);			/* RD低电平 */
   	ram = LCD_DATA_IN;    	/* 读取数据 */
    	LCD_RD(1);			/* RD高电平 */
    	LCD_CS(1);			/* 释放片选 */
	return ram;			/* 返回读数 */
}

4,LCD驱动芯片简介(熟悉)

用于控制LCD的各种显示功能和效果,整体功能较复杂。常见型号:ILI9341/ST7789等
一般我们只需要:6条指令即可完成对LCD的基本使用(以9341为例)
在这里插入图片描述
读ID指令(0XD3)
读取LCD控制器型号,通过型号可以执行不同LCD初始化,以兼容不同LCD
在这里插入图片描述

访问控制指令(0X36)
实现GRAM读写方向控制,即:控制GRAM自增方向,从而控制显示方向
在这里插入图片描述
MX,MY,MV:共同控制GRAM自增方向(扫描方向)
BGR位:可以控制RGB、BGR顺序
MX、MY、MV扫描方向控制关系
在这里插入图片描述
在这里插入图片描述
从左到右,从上到下
X坐标设置指令(0X2A)
在这里插入图片描述
SC:起始坐标
EC:结束坐标
设置关系:0≤SC≤EC≤239(LCD像素宽度)

Y坐标设置指令(0X2B)
页地址设置指令,一般用于设置Y坐标
在这里插入图片描述
SP:起始坐标
EP:结束坐标
设置关系:0≤SP≤EP≤319(LCD像素高度)
写GRAM指令(0X2C)
发送该指令后,数据线变成16位,可以开始写入GRAM数据,支持地址自增
在这里插入图片描述
每次写入1个像素点的颜色值(RGB565),地址自增方向由MX/MY/MV控制无需重新设置坐标,可实现连续写入,大大提高写入速度
读GRAM指令(0X2E)
发送该指令后,数据线变成16位,可以开始读取GRAM数据,支持地址自增
在这里插入图片描述
读1个点的颜色,要读3次
1,dummy
2,R1G1
3,B1R2
uint16_t r, g, b;
r = lcd_rd_data();
g = lcd_rd_data();
b = lcd_rd_data();
g = r & 0XFF;
return (((r >> 11) << 11) | ((g >> 2) << 5) | (b >> 11));

读点函数代码(精简)

uint16_t  lcd_rd_data(void)
{
	uint16_t ram;  		/* 定义变量 */
	DATA_IN_MODE();	/* 设置数据输入 */
 	LCD_RS(1);              	/* 操作数据 */
    	LCD_CS(0);			/* 选中 */
    	LCD_RD(0);		/* RD低电平 */
   	ram = LCD_DATA_IN;    	/* 读取数据 */
    	LCD_RD(1);		/* RD高电平 */
    	LCD_CS(1);			/* 释放片选 */
	DATA_OUT_MODE();	/* 设置数据输出 */
	return ram;		/* 返回读数 */
}
uint16_t  lcd_read_point (uint16_t x, uint16_t y)
{
	uint16_t r = 0, g = 0, b = 0;	/* 定义变量 */
	lcd_set_cursor(x, y);		/* 设置坐标 */
 	lcd_wr_regno(0X2E);		/* 发读点命令 */
 	r = lcd_rd_data();  		/* 假读 */
	r = lcd_rd_data();  		/* 读rg */
	b = lcd_rd_data(); 		/* 读b */
    	g = r & 0XFF;       			/* 得到g值 */
	return (((r >> 11) << 11) | ((g >> 2) << 5) | (b >> 11));
}

5,LCD基本驱动实现(掌握)

目标:用最简单代码,点亮开发板LCD屏,实现任意位置画点和读点
1,确定IO连接关系 LCD模块原理图、开发板液晶接口原理图
2,初始化IO口 初始化连接LCD的各个IO口
3、初始化FSMC外设 可选,某些芯片是没有FSMC外设,MINI板是没有的
3,编写读写接口函数 lcd_wr_data、lcd_wr_regno、lcd_write_reg、lcd_rd_data
4,编写LCD初始化函数 编写lcd_init函数,完成初始化序列配置,点亮背光等
5,编写LCD画和读点函数
编写lcd_draw_point函数,实现LCD任意位置画点
在这里插入图片描述

6, 编程实战1(掌握)

1,使用8080时序在LCD上实现任意位置画点和读点
2,在LCD屏幕上能支持1212、1616、2424、3232大小的ASCII字符显示
任意字符显示的关键是要制作字库,有了字库就能实现任意字符显示
1,字库制作 根据字体大小(12/16/24/32),制作对应的字库
2,编写任意字符显示函数 根据字库生成方式,编写对应的字符显示函数

ASCII字库制作(16*16)
第1步,设置字体大小
在这里插入图片描述
第2步,设置字模选项
在这里插入图片描述
第3步,输入ASCII字符集(95个)
第4步,生成字模在这里插入图片描述

7.1,FMC简介

FMC,Flexible Memory Controller,灵活的存储控制器。
用途:用于驱动NOR/PSRAM,NAND/PC卡,同步DRAM(SDRAM/Mobile LPSDR SDRAM)等。
配置好FMC,存储器当成普通外设使用。定义一个指向这些地址的指针,通过对指针操作就可以直接修改存储单元的内容,FMC自动完成读写命令和数据访问操作,不需要程序去实现时序。
FMC外设配置好就可以模拟出时序
FMC模拟8080时序控制LCD
我认为所谓的映射就是将0-25FMC地址线所接的外设,通过这26条地址总线将外接的存储器映射到stm32内部内存地址中,其中某一个总线可以映射为一个地址,可以操作这个地址进行读写

7.2,FMC框图介绍

在这里插入图片描述
知识补充stm32时钟
SYSCLK:系统时钟,由外/内部晶振/时钟源经过PLL(或不经过PLL)倍频得到的
HCLK:AHB总线,高速外设时钟 经过SYSCLK分频得到,其中H代表高速
PCLK1:外设时钟:总线APB1 经过HCLK分频得到
PCLK2:外设时钟:总线APB2 经过HCLK分频得到
① 时钟控制逻辑
FMC挂载在AHB总线上
时钟信号来自HCLK
② STM32内部的FMC控制单元
FMC配置寄存器
NOR和PSRAM控制器
NAND和PC卡控制器
SDRAM控制器
③ 通信引脚
不同类型存储器用到的信号引脚
公共信号引脚
FMC通信引脚介绍
用于连接硬件设备的引脚,控制不同类型的存储器会用不同的引脚。
在这里插入图片描述
LCD使用的是类似异步、地址与数据线独立的SRAM控制方式
使用FMC驱动LCD
在这里插入图片描述

7.3,FMC时序介绍

FMC是Flexible灵活的,可以产生多种时序来控制外部存储器。
NOR/PSRAM控制器产生的异步时序就有5种,总体分为两类:一类是模式1,其他为拓展模式。
拓展模式相对模式1来说读写时序时间参数设置可以不同,满足存储器读写时序不一样需求。

在这里插入图片描述
这里模拟8080时序驱动LCD选择模式A
写时序
引脚类比
NEx ——>>CS 片选
NOE ——>>RD 读
NWE ——>>WR 写
RS读写命令用地址线中的一根
数据总线用到其中一部分数据总线
ADDSET
DATAST+1 根据寄存器进行设置
写时序
在这里插入图片描述
9341写时序
在这里插入图片描述
读SRAM时序
在这里插入图片描述
读9341时序在这里插入图片描述
重点时序:
读ID低电平脉宽(trdl)
读ID高电平脉宽(trdh)
读FM低电平脉宽(trdlfm)
读FM高电平脉宽(trdhfm)
写控制低电平脉宽(twrl)
写控制高电平脉宽(twrh)
ID:指LCD的ID号
FM指帧缓存即GRAM
RD/WR高电平持续时间即ADDSET
RD/WR低电平持续时间即DATAST
一个HCLK时钟周期:1/(系统主频Mhz)
注意:读和写时序存在不同,写时序中为DATAST+1
在这里插入图片描述
9341读写时钟
在这里插入图片描述
读写高低电平时间限制
写时钟周期最小66ns 高电平时间最小15ns 低电平时间最小15ns
读ID时钟周期最小160ns 高电平时间最小90ns 低电平时间最小45ns
读GRAM时钟周期最小450ns 高电平时间最小90ns 低电平时间最小355ns

我们进行读写时 以系统时钟168M也就是HCLK是168M,FSMC的时钟周期为1/168 = 6ns
写设置 地址建立时间ADDSET就是WR高电平时间 数据建立时间就是 WR地点评时间 这两个按照最低15ns 我们都设置为54ns
读设置 地址建立时间ADDSET就是OE高电平时间 数据建立时间就是 OE地点评时间 这两个按照最低90ns 我们都设置为355ns 这样既可以保证读ID也可以保证读FM 我们设置为90ns和360ns(经验值)
读写实际上就是对地址进行赋值和读取。

7.4,FMC地址映射

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

地址0x6000 0000-0xDFFF FFFF
使用FMC外接存储器,其存储单元是映射到STM32的内部寻址空间的。
从FMC角度看,把外部存储器划分为固定大小为256M字节的6个存储块(1.5GB)。
FMC存储块1被分为4个区,每个区管理64M字节空间
在这里插入图片描述
在这里插入图片描述
HADDR与FMC_A关系
HADDR总线是转换到外部存储器的内部AHB地址线
简单来说,从CPU通过AHB总线到外部信号线之间的关系。
HADDR是字节地址,而存储器访问不都是按字节访问,接到存储器的地址线与其数据宽度相关。
LCD使用16位数据线
在这里插入图片描述
在这里插入图片描述
注意:数据宽度为16位时,地址存在偏移
在这里插入图片描述

LCD的RS信号线与地址线关系
8080接口中RS(数据/命令选择线),用FMC的某根A地址线进行替换。
FMC_A19接到RS线上
当FMC_A19为高电平时(即RS为高电平),FMC_D[15:0]被理解为数据。
当FMC_A19为低电平时(即RS为低电平),FMC_D[15:0]被理解为命令。
究竟发送什么地址代替?
1、确认FMC_NE1基地址
0x6000 0000 NEx(x=1…4):0x6000 0000 + (0x400 0000 * (x - 1))
2、确认FMC_A19对应地址值
219 x 2 = 0x100000 FMC_Ay(y=0…24): 2y x 2 这里是不是FMC_A19对应HADDR_20
3、确认两个地址
代表LCD命令的地址:0x6000 0000
代表LCD数据的地址:0x6010 0000
#define FMC_ADDR_CMD ((uint32_t) 0x6000 0000)
#define FMC_ADDR_DATA ((uint32_t) 0x6010 0000)

7.5,FMC相关寄存器介绍

对于NOR_FLASH/PSRAM控制器(存储块1)配置工作,通过FMC_BCRx、FMC_BTRx和FMC_BWTRx寄存器设置(其中x=1~4,对应4个区)。
在这里插入图片描述
LCD的读写时序存在比较大差异,所以FMC的读写时序也得分开配置

SRAM/NOR闪存片选控制寄存器(FMC_BCRx)
在这里插入图片描述
EXTMOD:扩展模式使能位,控制是否允许读写不同的时序。读和写用不同的时序,该位设置为1
WREN:写使能位。向TFTLCD写入数据,该位设置1
MWID[1:0]:存储器数据总线宽度。00,表示8位数据模式;01表示16位数据模式;10和11保留。我们使用16位数据模式设置01
MTYP[1:0]:存储器类型。00表示SRAM、ROM;01表示PSRAM;10表示NOR FLASH;11保留。设置为00表示SRAM
MBKEN:存储块使能位。设置为1
SRAM/NOR闪存片选时序寄存(FMC_BTRx)
在这里插入图片描述
ACCMOD[1:0]:访问模式。00:模式A;01:模式B;10:模式C;11:模式D。设置为00
DATAST[7:0]:数据保持时间,等于DATAST个HCLK时钟周期,DATAST最大为255。
对于ILI9341来说,其实就是RD低电平持续时间,最小为355ns。
对于F429,一个HCLK = 5ns(1/180M),设置为70
对于F767,一个HCLK = 4.6ns(1/216M),设置为80
对于H743/H750,一个HCLK = 4.5ns(1/220M) ,设置为78

ADDSET[3:0]:地址建立时间。表示ADDSET个HCLK时钟周期,ADDSET最大为15。
对于ILI9341来说,相当于RD高电平持续时间,为90ns。
F429/F767/H743/H750设置15

SRAM/NOR闪存写入时序寄存器(FMC_BWTRx)
在这里插入图片描述
ACCMOD[1:0]:访问模式。00:模式A;01:模式B;10:模式C;11:模式D。
DATAST[7:0]:数据保持时间,等于DATAST个HCLK时钟周期,DATAST最大为255。

对于ILI9341来说,其实就是WR低电平持续时间,最小为15ns。
对于F429,一个HCLK = 5ns(1/180M),设置为15
对于F767,一个HCLK = 4.6ns(1/216M),设置为15
对于H743/H750,一个HCLK = 4.5ns(1/220M) ,设置为15
ADDSET[3:0]:地址建立时间。表示ADDSET(+1)个HCLK时钟周期,ADDSET最大为15。
对于ILI9341来说,相当于WR高电平持续时间,为15ns。
F429/F767/H743/H750设置15

FMC寄存器组合说明
在ST官方提供的寄存器定义里面,并没有定义FMC_BCRx、FMC_BTRx、FMC_BWTRx等这个单独的寄存器,而是将他们进行了一些组合,规则如下:
FMC_BCRx和FMC_BTRx,组合成BTCR[8]寄存器组,他们的对应关系如下:
BTCR[0]对应FMC_BCR1,BTCR[1]对应FMC_BTR1
BTCR[2]对应FMC_BCR2,BTCR[3]对应FMC_BTR2
BTCR[4]对应FMC_BCR3,BTCR[5]对应FMC_BTR3
BTCR[6]对应FMC_BCR4,BTCR[7]对应FMC_BTR4
FMC_BWTRx则组合成BWTR[7]寄存器组,他们的对应关系如下:
BWTR[0]对应FMC_BWTR1,BWTR[2]对应FMC_BWTR2,
BWTR[4]对应FMC_BWTR3,BWTR[6]对应FMC_BWTR4,
BWTR[1]、BWTR[3]和BWTR[5]保留,没有用到

7.6,FMC相关HAL库函数简介

本例程涉及HAL库相关函数如下:
__HAL_RCC_FMC_CLK_ENABLE(); /* 使能FMC时钟 */
HAL_StatusTypeDef HAL_SRAM_Init ( SRAM_HandleTypeDef *hsram,
FMC_NORSRAM_TimingTypeDef *Timing,
FMC_NORSRAM_TimingTypeDef *ExtTiming )

在这里插入图片描述
调用
在这里插入图片描述
SRAM_HandleTypeDef

  typedef struct 
{ 
	FMC_NORSRAM_TypeDef *Instance;				/* 寄存器基地址 */ 	FMC_NORSRAM_EXTENDED_TypeDef *Extended; 	/* 扩展模式寄存器基地址 */ 
	FMC_NORSRAM_InitTypeDef Init;					/* SRAM初始化结构体*/ 
	HAL_LockTypeDef Lock; 						/* SRAM锁对象结构体 */ 
	__IO HAL_SRAM_StateTypeDef State; 				/* SRAM设备访问状态 */ 
	DMA_HandleTypeDef *hdma; 					/* DMA结构体 */ 
} SRAM_HandleTypeDef;
         

FSMC_NORSRAM_TimingTypeDef

 typedef struct 
{ 
	uint32_t AddressSetupTime; 			/* 地址建立时间 */ 
	uint32_t AddressHoldTime; 			/* 地址保持时间 */ 	
	uint32_t DataSetupTime; 			/* 数据建立时间 */ 	
	uint32_t BusTurnAroundDuration; 	/* 总线周转阶段的持续时间 */
	uint32_t CLKDivision;				/* CLK时钟输出信号的周期 */
	uint32_t DataLatency;				/* 同步突发NOR FLASH的数据延迟 */
	uint32_t AccessMode;				/* 异步模式配置 */
} FSMC_NORSRAM_InitTypeDef;
        

注意:1、引脚配置都配置成为复用FSMC
2、读写的时钟周期配置是经验值

void lcd_init(void)
{
    GPIO_InitTypeDef gpio_init_struct;
    FSMC_NORSRAM_TimingTypeDef fsmc_read_handle;
    FSMC_NORSRAM_TimingTypeDef fsmc_write_handle;

    LCD_CS_GPIO_CLK_ENABLE();   /* LCD_CS脚时钟使能 */
    LCD_WR_GPIO_CLK_ENABLE();   /* LCD_WR脚时钟使能 */
    LCD_RD_GPIO_CLK_ENABLE();   /* LCD_RD脚时钟使能 */
    LCD_RS_GPIO_CLK_ENABLE();   /* LCD_RS脚时钟使能 */
    LCD_BL_GPIO_CLK_ENABLE();   /* LCD_BL脚时钟使能 */
    
    gpio_init_struct.Pin = LCD_CS_GPIO_PIN;
    gpio_init_struct.Mode = GPIO_MODE_AF_PP;                /* 推挽复用 */
    gpio_init_struct.Pull = GPIO_PULLUP;                    /* 上拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;          /* 高速 */
    gpio_init_struct.Alternate = GPIO_AF12_FSMC;            /* 复用为FSMC */
    HAL_GPIO_Init(LCD_CS_GPIO_PORT, &gpio_init_struct);     /* 初始化LCD_CS引脚 */

    gpio_init_struct.Pin = LCD_WR_GPIO_PIN;
    HAL_GPIO_Init(LCD_WR_GPIO_PORT, &gpio_init_struct);     /* 初始化LCD_WR引脚 */

    gpio_init_struct.Pin = LCD_RD_GPIO_PIN;
    HAL_GPIO_Init(LCD_RD_GPIO_PORT, &gpio_init_struct);     /* 初始化LCD_RD引脚 */

    gpio_init_struct.Pin = LCD_RS_GPIO_PIN;
    HAL_GPIO_Init(LCD_RS_GPIO_PORT, &gpio_init_struct);     /* 初始化LCD_RS引脚 */

    gpio_init_struct.Pin = LCD_BL_GPIO_PIN;
    gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;            /* 推挽输出 */
    HAL_GPIO_Init(LCD_BL_GPIO_PORT, &gpio_init_struct);     /* LCD_BL引脚模式设置(推挽输出) */

    g_sram_handle.Instance = FSMC_NORSRAM_DEVICE;
    g_sram_handle.Extended = FSMC_NORSRAM_EXTENDED_DEVICE;
    
    g_sram_handle.Init.NSBank = FSMC_NORSRAM_BANK4;                        /* 使用NE4 */
    g_sram_handle.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE;     /* 地址/数据线不复用 */
    g_sram_handle.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_16;    /* 16位数据宽度 */
    g_sram_handle.Init.BurstAccessMode = FSMC_BURST_ACCESS_MODE_DISABLE;   /* 是否使能突发访问,仅对同步突发存储器有效,此处未用到 */
    g_sram_handle.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW; /* 等待信号的极性,仅在突发模式访问下有用 */
    g_sram_handle.Init.WaitSignalActive = FSMC_WAIT_TIMING_BEFORE_WS;      /* 存储器是在等待周期之前的一个时钟周期还是等待周期期间使能NWAIT */
    g_sram_handle.Init.WriteOperation = FSMC_WRITE_OPERATION_ENABLE;       /* 存储器写使能 */
    g_sram_handle.Init.WaitSignal = FSMC_WAIT_SIGNAL_DISABLE;              /* 等待使能位,此处未用到 */
    g_sram_handle.Init.ExtendedMode = FSMC_EXTENDED_MODE_ENABLE;           /* 读写使用不同的时序 */
    g_sram_handle.Init.AsynchronousWait = FSMC_ASYNCHRONOUS_WAIT_DISABLE;  /* 是否使能同步传输模式下的等待信号,此处未用到 */
    g_sram_handle.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE;              /* 禁止突发写 */
    
    /* FSMC读时序控制寄存器 */
    fsmc_read_handle.AddressSetupTime = 0x0F;           /* 地址建立时间(ADDSET)为15个fsmc_ker_ck(1/168=6)即6*15=90ns */
    fsmc_read_handle.AddressHoldTime = 0x00;            /* 地址保持时间(ADDHLD) 模式A是没有用到 */
    fsmc_read_handle.DataSetupTime = 60;                /* 数据保存时间(DATAST)为60个fsmc_ker_ck=6*60=360ns */
                                                        /* 因为液晶驱动IC的读数据的时候,速度不能太快,尤其是个别奇葩芯片 */
    fsmc_read_handle.AccessMode = FSMC_ACCESS_MODE_A;   /* 模式A */
    
    /* FSMC写时序控制寄存器 */
    fsmc_write_handle.AddressSetupTime = 9;             /* 地址建立时间(ADDSET)为9个fsmc_ker_ck=6*9=54ns */
    fsmc_write_handle.AddressHoldTime = 0x00;           /* 地址保持时间(ADDHLD) 模式A是没有用到 */
    fsmc_write_handle.DataSetupTime = 9;                /* 数据保存时间(DATAST)为9个fsmc_ker_ck=6*9=54ns */
                                                        /* 注意:某些液晶驱动IC的写信号脉宽,最少也得50ns */
    fsmc_write_handle.AccessMode = FSMC_ACCESS_MODE_A;  /* 模式A */
    
    HAL_SRAM_Init(&g_sram_handle, &fsmc_read_handle, &fsmc_write_handle);
    delay_ms(50);

    /* 尝试9341 ID的读取 */
    lcd_wr_regno(0xD3);
    lcddev.id = lcd_rd_data();  /* dummy read */
    lcddev.id = lcd_rd_data();  /* 读到0x00 */
    lcddev.id = lcd_rd_data();  /* 读取93 */
    lcddev.id <<= 8;
    lcddev.id |= lcd_rd_data(); /* 读取41 */
    }

总结:

FSMC用作模拟8080时序使用,是将TFT模拟成SRAM使用,其中将RS(写命令/地址接在一根地址线上比如A0上),这时可以将TFT认为一个只有2个地址的SRAM。A0=0时地址对应0 A0=1时地址对应1。给地址0写时A0(RS)就被拉低了就是写命令,给地址1写时A0(RS)就被拉高了就是写数据。数据输出在数据总线上给到GRAM。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1461653.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

宝塔面板-安装与卸载

宝塔面板&#xff08;BT Panel&#xff09;是一款在互联网上广泛使用的服务器管理软件&#xff0c;它以其简洁的界面和强大的功能受到了许多站长的喜爱。通过宝塔面板&#xff0c;用户可以轻松地管理服务器上的网站、数据库、FTP、邮箱等服务。本文将详细介绍宝塔面板的安装与卸…

嵌入式产品开发流程全解析

&#xff08;本文为简单介绍&#xff0c;内容来源于网络&#xff09; 嵌入式产品开发是一个涵盖硬件和软件的综合系统工程,其开发流程可以概括为需求分析、系统设计、软硬件开发与调试、产品验证和批量生产几大阶段。 需求分析阶段是开发流程的基础,主要对产品的硬件资源、软…

【企业动态】复工啦,回顾2023,展望2024!东胜物联与您同启新程

这几天相信小伙伴们都已经陆陆续续回归工作岗位了吧&#xff0c;复工后在CSDN发布的第二篇文章带大家来回顾物联网硬件设备及解决方案商东胜物联的2023年总结以及2024年展望&#xff0c;分享给所有对Dusun感兴趣的新老朋友❤️ 2023年&#xff0c;东胜不仅面对了一些挑战&…

CVE-2024-24565 CrateDB数据库任意文件读取漏洞

目录 前言 简介 ​编辑 环境搭建 漏洞复现 前言 本次介绍的漏洞不同与以往&#xff0c; 本次洞更多是适用于利用数据库提权。 利用数据库的导入导出数据的功能&#xff0c;我们往往可以将内部的一些敏感文件如/etc/passwd导入到数据库进行查看。也可以将数据导入到一些特…

分组统计

目录 分组统计 根据部门编号分组&#xff0c;查询每个部门的编号、人数、平均工资 根据职位分组&#xff0c;统计出每个职位的人数、最低工资与最高工资 如果查询不使用 GROUP BY 子句&#xff0c;那么 SELECT 子句中只允许出现统计函数&#xff0c;其他任何字段不允许出现…

统计图雷达图绘制方法

统计图雷达图绘制方法 常用的统计图有条形图、柱形图、折线图、曲线图、饼图、环形图、扇形图。 前几类图比较容易绘制&#xff0c;饼图环形图绘制较难。 还有一种雷达图的绘制也较难&#xff0c;今提供雷达图的绘制方法供参考。 本方法采用C语言的最基本功能&#xff1a; &am…

Leetcode刷题笔记题解(C++):83. 删除排序链表中的重复元素

思路&#xff1a;链表相关的问题建议就是画图去解决&#xff0c;虽然理解起来很容易&#xff0c;但就是写代码写不出来有时候&#xff0c;依次去遍历第二节点如果与前一个节点相等则跳过&#xff0c;不相等则遍历第三个节点 /*** Definition for singly-linked list.* struct …

yolov5-tracking-xxxsort yolov5融合六种跟踪算法(二)--目标识别

本次开源计划主要针对大学生无人机相关竞赛的视觉算法开发。 开源代码仓库链接&#xff1a;https://github.com/zzhmx/yolov5-tracking-xxxsort.git 先按照之前的博客配置好环境&#xff1a; yolov5-tracking-xxxsort yolov5融合六种跟踪算法&#xff08;一&#xff09;–环境配…

Canvas绘制

Canvas绘制 一、介绍效果图 二、画圆1 写一个页面2 画一个圆&#xff08;点&#xff09;3 效果 三 画直线1 写一个页面2 画直线3 效果 四 用直线连接两个点1 写一个页面2 连线3 效果 五 画随机点1 写一个页面2 随机点3 效果 六 画随机点并连线1 写一个页面2 画点连线3 效果 七 …

GEE使用 Sentinel-1 SAR影像 和 Otsu 方法绘制洪水地图

洪水是世界上最常见、破坏性最大的自然灾害之一,造成了巨大的生命和财产损失。此外,随着气候变化的影响,近年来,洪灾变得更加频繁和不可预测。为了最大限度地减少生命和财产损失,必须迅速发现洪水蔓延的情况,并及时采取必要的干预措施。洪水蔓延探测大多使用光学传感器或…

如何批量注册多个Google账号?

电子邮件地址对于在线帐户至关重要&#xff0c;但它们可能被滥用于发送垃圾邮件。因此Google使用先进的算法来检测可疑的注册和验证尝试&#xff0c;保护用户免受垃圾邮件和其他有害活动的侵害&#xff0c;所以如果需要批量注册多个Google帐户&#xff0c;需要做好账号防关联&a…

QT 文本编辑框textBrowser接收数据保持光标在底部的方法

目录 1.实现效果2.代码 1.实现效果 2.代码 右键textBrowser加入触发信号textChanged&#xff1a; 双击&#xff0c;跳转到槽函数&#xff1a;(文本更改时执行该函数) void Widget::updata_textBrowser() void Widget::on_textBrowser_textChanged() {//光标移动至底部ui->…

Py之pydantic:pydantic的简介、安装、使用方法之详细攻略

Py之pydantic&#xff1a;pydantic的简介、安装、使用方法之详细攻略 目录 pydantic的简介 1、Pydantic V1.10 vs. V2 pydantic的安装 pydantic的使用方法 1、简单的示例 pydantic的简介 pydantic是使用Python类型提示进行数据验证。快速且可扩展&#xff0c;Pydantic与您…

【云原生】Docker 安全与CA证书生成

目录 容器的安全行问题 Docker 容器与虚拟机的区别 Docker 存在的安全问题 1.Docker 自身漏洞 2.Docker 源码问题 Docker 架构缺陷与安全机制 1. 容器之间的局域网攻击 2. DDoS 攻击耗尽资源 3. 有漏洞的系统调用 4. 共享root用户权限 Docker 安全基线标准 1. 内…

【UI自动化】八大元素定位方式|xpath css id name...

目录 一、基础元素定位 二、cssSelector元素定位——通过元素属性定位 三、xpath元素定位——通过路径 1 、xpath绝对定位 &#xff08;用的不多&#xff09; 缺点&#xff1a;一旦页面结构发生变化&#xff08;比如重新设计时&#xff0c;路径少两节&#xff09;&#x…

HGAME 2024 WEEK 2

hgame2024官方题解-week2.pdf Misc ek1ng_want_girlfriend 打开流量包后点击“导出对象” 打开这张图片就是flag Web What the cow say?

粉丝2000 啦,选对赛道,做正确的事情,粉丝涨到2000说明大家对我做的事情还是非常的认可的,继续坚持中,将相关资料做了视频整理

1&#xff0c;见证历史成长&#xff0c;粉丝涨到 2000 啦 2&#xff0c;把视频进行分类&#xff0c;研究xinference相关视频 【xinference】&#xff08;1&#xff09;&#xff1a;在autodl上&#xff0c;使用xinference部署chatglm3大模型&#xff0c;支持函数调用&#xff0…

(一)全连接神经网络

参考资料&#xff1a;https://zhuanlan.zhihu.com/p/273595649 一、前向传播 1、第一层 &#xff08;1&#xff09;线性层 { z 1 ( 1 ) w 11 ( 1 ) ∗ x 1 w 12 ( 1 ) ∗ x 2 b 1 ( 1 ) z 2 ( 1 ) w 21 ( 1 ) ∗ x 1 w 22 ( 1 ) ∗ x 2 b 2 ( 1 ) z 3 ( 1 ) w 31 ( …

CCF-B类SGP‘24 4月10日截稿!速速行动!

会议之眼 快讯 第22届SGP(Eurographics Symposium on Geometry Processing)即欧洲图形学几何处理专题讨论会将于 2024 年 6月24 -日至26日在美国麻省理工学院举行&#xff01;SGP是传播几何处理新研究想法和尖端成果的首要学术会议。作为该领域的重要学术盛事&#xff0c;SGP会…

IO 作业 24/2/21

1、使用多线程完成两个文件的拷贝&#xff0c;第一个线程拷贝前一半&#xff0c;第二个线程拷贝后一半&#xff0c;主线程回收两个线程的资源 #include <myhead.h> //定义分支线程1 void *task1(void *arg) {int fdr-1;//只读打开被复制文件if((fdropen("./111.txt…