上海阔达网站建设公司,西安高风险调整,wordpress文档chm,网站如何布局1.1 TFTLCD简介 TFT-LCD#xff08;thin film transistor-liquid crystal display#xff09;即薄膜晶体管液晶显示器。液晶显示屏的每一个像素上都设置有一个薄膜晶体管#xff08;TFT#xff09;#xff0c;每个像素都可以通过点脉冲直接控制#xff0c;因而每个节点都…1.1 TFTLCD简介 TFT-LCDthin film transistor-liquid crystal display即薄膜晶体管液晶显示器。液晶显示屏的每一个像素上都设置有一个薄膜晶体管TFT每个像素都可以通过点脉冲直接控制因而每个节点都相对独立并可以连续控制不仅提高了显示屏的反应速度同时可以精确控制显示色阶所以TFT液晶的色彩更真因此TFT-LCD也被叫做真彩液晶显示器 常用的TFT液晶屏接口有8位、9位、16位、18位这里的位数表示的是彩屏数据线的数量。常用的通信模式有6800模式和8080模式本例程使用8080并口模式简称80并口8080接口有5条基本的控制线和多条数据线8/9/16/18位它们的功能如下表 8080接口模式的时序如下图所示 在WR跳变为低电平后液晶屏开始读取总线上面的数据在RD跳变为低电平后液晶屏开始放置数据到总线上面 本例程使用3.0寸的TFT-LCD模块驱动芯片为R61509VN分辨率240*400接口为16位的80并口自带触摸功能该模块原理图如下所示 该模块的80并口有如下信号线
信号线作用CSTFTLCD片选信号WR向TFTLCD写入数据RD从TFTLCD读取数据RS命令/数据选择0读写命令1读写数据DB[15:0]16位双向数据线RSTTFTLCD复位
任何LCD的使用流程都可以简单的用以下流程图来表示其中硬复位和初始化序列只需要执行一次即可。画点流程设置坐标 -- 写GRAM指令 -- 写入颜色数据然后在LCD上就可以看到对应的点显示写入的颜色了读点流程设置坐标 -- 读GRAM指令 -- 读取颜色数据这样就可以获取到对应点的颜色数据了 以上是最简单也是最常用的操作有了这些操作一般就可以正常使用TFTLCD了。设置TFT液晶显示通常需要以下几个步骤
- 设置STM32F1与TFTLCD模块箱连接的IO口将与TFTLCD模块相连的IO口进行初始化以便驱动LCD这里使用的是STM32F1的FSMC - 初始化TFTLCD模块写入一系列设置值本例程中LCD模块的复位引脚是接在STM32F1的复位上所以直接按下开发板复位键即可然后就是初始化序列即向LCD控制器写入一系列的设置值比如RGB格式、LCD显示方向、伽马校准等这部分代码一般LCD厂商会提供。初始化之后LCD才可以正常使用 - 通过函数将字符和数字显示到TFTLCD模块上画点流程只是一个点的处理因此需要设计一个函数来多次使用这个步骤以实现字符和数字的显示 1.2 FSMC简介 FSMCFlexible Static Memory Controller即灵活的静态存储控制器是STM32系列采用的一种新型存储器扩展技术能够连接同步、异步存储器和16位PC存储卡STM32通过FSMC可以与SRAM、ROM、PSRAM、NOR Flash和NAND Flash等存储器的引脚直接相连。STM32F1的FSMC内部框图如下图示 - 时钟输入FSMC的时钟来自时钟控制器HCLK - AHB接口CPU和其他AHB总线主设备可通过该AHB从设备接口访问外部静态存储器 - 外部设备FSMC将外部设备分为2类NOR/PSRAM设备和NAND/PC卡设备。它们共用地址数据总线等信号但具有不同的CS以区分不同的设备 本例程中使用的是FSMC的NOR/PSRAM存储器控制器部分即把TFTLCD当成SRAM设备使用。NOR/PSRAM存储器控制器的接口信号功能如下图示 从上图中可以看出外部SRAM的控制一般有A0 ~ A25、D0 ~ D15、NWE、NOE、NE[x]如果支持字节控制还有UB/LB信号。而TFTLCD的信号线包括RS、DB0 ~ DB15、WR、RD、CS、RST等。由此可见它们的操作接口信号完全类似唯一不同就是TFTLCD有RS信号没有地址信号 TFTLCD通过RS信号来决定传送的数据是数据还是命令可以理解为一个地址信号。比如我们把 RS 接在A0上面当FSMC控制器写地址0的时候会使得A0变为0对TFTLCD来说就是写命令而FSMC写地址1的时候A0将会变为1对TFTLCD来说就是写数据了。这样就把数据和命令区分开了其实就是对应SRAM操作的两个连续地址。 当然RS也可以接在其他地址线上本例程中RS是连接在 A10 上面的 下面介绍一下FSMC的外部设备地址映射从FSMC的角度外部存储器被划分为4个固定大小的存储区域Bank每个存储区域的大小为256MB共1GB空间详见下图 Bank1可连接多达4个NOR Flash或PSRAM存储器器件此存储区域被划分为4个NOR/PSRAM区域带4个专用片选信号Bank2和Bank3用于连接NAND Flash器件Bank4用于连接PC卡设备对于每个存储区域所要使用的存储器类型有用户在配置寄存器中定义。FSMC各Bank配置寄存器如下图示 这里使用的是Bank1Bank1又被分为4个区每个区管理64MB空间每个区都有独立的寄存器对所连接的存储器进行配置。Bank1的256MB空间由28根地址线HADDR[27:0]寻址HADDR是内部AHB地址总线其中HADDR[25:0]来自外部存储器地址FSMC_A[25:0]HADDR[27:26]用于对4个区寻址 本例程使用的是Bank1的第4区即起始地址为0x6C000000这里需要特别注意HADDR[25:0]HADDR[25:0]包含外部存储器地址由于HADDR为字节地址而存储器按字寻址所以根据存储器数据宽度不同实际向存储器发送的地址也有所不同如下图示 不论外部接8位/16位宽设备FSMC_A[0]始终接在外部设备地址A[0]。本例程中TFTLCD使用的是16位数据宽度所以HADDR[0]并没有用到只有HADDR[25:1]是有效的对应关系变为HADDR[25:1] -- FSMC_A[24:0]相当于右移了一位。比如地址0x7E对应的二进制是01111110此时FSMC_A6是0而不是1因为要右移一位。另外HADDR[27:26]是不需要我们干预的。 FSMC的NOR Flash控制器支持同步和异步突发两种访问方式选用不同的时序模型时需要设置不同的时序参数 同步突发访问方式需要设置CLKDIV分频系数、DATLAT获得第一个数据所需要的等待延迟异步突发访问方式需要设置DATAST数据建立时间、ADDSET地址建立时间、ADDHLD地址保持时间 在实际扩展时根据选用存储器的特征确定时序模型从而确定个时间参数与存储器读写周期参数指标之间的计算关系利用该计算关系和存储芯片数据手册中给定的参数指标可计算出FSMC所需要的各时间参数从而对时间参数寄存器进行合理的配置 这里使用异步模式AModeA方式来控制TFTLCD模式A的读操作时序图如下所示 模式A的写操作时序图如下所示 2. 硬件设计
LED2指示灯用来提示系统运行状态TFTLCD的ID通过串口1打印输出
LED2指示灯USART1FSMCTFTLCD模块 3、 STM32CubeMX设置
RCC设置外接HSE时钟设置为72MPE5设置为GPIO推挽输出模式、上拉、高速、默认输出电平为高电平USART1选择为异步通讯方式波特率设置为115200Bits/s传输数据长度为8Bit无奇偶校验1位停止位
FSMC参数配置
1、选择FSMC选中Bank1片选为NE4即Bank1的第4区存储器类型选为LCD InterfaceLCD寄存器选择RS设置为A10数据宽度设为16位 在 Connectivity 中选择 FSMC 设置并在 NOR Flash/PSRAM/SRAM/ROM/LCD 1 中选择 NE1 Chip Select 片选选择原理图中的片选引脚NE1【选择Bank1的第一区是根据原理图的映射管脚进行选择的这里选择不同区对应的引脚是不同的】 FSMC_NE 是用于控制存储器芯片的片选控制信号线STM32 具有 FSMC_NE1/2/3/4 号引脚不同的引脚对应 STM32 内部不同的地址区域。例如当 STM32 访问 0x68000000-0x6BFFFFFF 地址空间时FSMC_NE3 引脚会自动设置为低电平由于它一般连接到外部存储器的片选引脚且低电平有效所以外部存储器的片选被使能而访问 0x60000000- 0x63FFFFFF 地址时FSMC_NE1 会输出低电平。当使用不同的 FSMC_NE 引脚连接外部存储器时STM32 访问外部存储的地址不一样从而达到控制多个外部存储器芯片的目的。 Memory type设置要控制的存储器类型 选择 LCD Interface LCD接口LCD Register SelectRS引脚 选择 A16 RS脚也就是命令/数据选择位同样是根据原理图得知这里应该选择A10 Data设置要控制的存储器的数据宽度 选择 16 bits 很明显从原理图看出有16个数据引脚这里选择16bits就好 2、在配置菜单中使能存储器写根据LCD驱动芯片的数据参数设置地址建立时间、数据保存时间、总线周转阶段持续时间设置为0模式设置为A NOR/PSRAM control
Write operation设置是否写使能 选择 Enabled 禁止写使能的话 FSMC 只能从存储器中读取数据不能写入。Extended mode设置是否使用扩展模式 选择 Enabled 在非扩展模式下对存储器读写的时序都只使用 FSMC_BCR 寄存器中的配在扩展模式下对存储器的读写时序可以分开配置读时序使用 FSMC_BCR 寄存器写时序使用 FSMC_BWTR 寄存器的配置。
FSMC读时序配置
这里引入一个基本概念 HCLK周期 按STM32F103的默认配置HCLK的时钟频率为72MHz即一个 THCLK 为 1/72us0.0138us13.8us。 NOR/PSRAM timingFSMC读时序配置
Address setup time in HCLK clock cycles地址建立时间 填 0Data setup time in HCLK clock cycles数据建立时间 填 26 根据ILI9341时序配置FSMC读时序 NEx片选后NOE要保持一段时间的高电平这个时间就是ADDSET地址建立时间通过寄存器FMC_BTRx可配置。 之后NOE变为低电平读使能。低电平保持的时间由DATAST数据建立时间通过寄存器FMC_BTRx可配置决定。 tast tast 表示地址建立时间最小为0ns 由时序图可以知道FSMC在ADDSET周期之后进入DATAST周期之后将会进行数据采样。 所以我们设置(ADDSET)HCLK的时间要大于等于tast地址建立时间。 (ADDSET)HCLK 0ns(0)·13.8 0ns所以ADDSET可以设置为0就可保证满足最小tast地址建立时间 trdlfm trdlfm 表示读取数据低电平的时间最小为355ns ILI9341时序图没有给出ILI9341操作数据线传输被读取的数据时的相关信息我们最好做到满足其读取数据低电平的最小时间。 当然不做到也行影响不大只要在FSMC在DATAST的这个周期的数据采样中获取所有的要访问的数据就行。 (DATAST)HCLK 355ns(26) * 13.8 358.8ns355ns所以DATAST设置为26。 Bus turn around time in HCLK clock cycles总线转换周期 填 0 仅适用于总线复用模式的NOR Flash操作所以这里设0。Access mode存储器访问模式 选 A LCD控制器使用 Mode A ,该模式用来控制SRAM/PSRAM且OE会翻转。控制异步 NOR FLASH 时使用 B 模式。 FSMC写时序配置
NOR/PSRAM timing for write accessesFSMC写时序配置
Extended address setup time地址建立时间 填 0Extended data setup time数据建立时间 填 1 根据ILI9341时序配置FSMC写时序 NEx片选后NWE要保持一段时间的高电平这个时间就是ADDSET地址建立时间通过寄存器FMC_BTRx可配置。 之后NWE变为低电平写使能。低电平保持的时间由DATAST数据建立时间通过寄存器FMC_BTRx可配置决定。 tast tast 表示地址建立时间最小为0ns 由时序图可以知道FSMC在ADDSET周期之后进入DATAST周期之后将会进行数据采样。 所以我们设置(ADDSET)HCLK的时间要大于等于tast地址建立时间。 (ADDSET)HCLK 0ns(0)·13.8 0ns所以ADDSET可以设置为0就可保证满足最小tast地址建立时间。 tdst、tdht tdst数据设置时间最小是10ns在这个周期内WRX线处于低电平。 tdht数据保持时间,与 twrh写控制高电平的最小时间相同,是10ns,在这个周期内WRX线处于高电平。 观察时序图我们设置 tdst数据设置时间 为1HCLK13.810就能满足数据设置最小时间的要求,我们不需要考虑tdht数据保持时间(看上面模式B时序图,NWE变成高电平后,会持续1HCLK13.8ns,默认满足tdht了)。 故我们只需考虑数据建立周期 DATAST 要大于10ns就行。(DATAST)HCLK 10ns13.810 故DATAST 至少设置为1 Extended bus turn around time总线转换周期 填 0Extended access mode存储器访问模式 选 A
3、设置背光和复位引脚 根据原理图复位脚已经跟单片机的复位脚连接在一起了因此只需要设置背光引脚BL_EN就行了。 将PB0设置为GPIO推挽输出模式、上拉、高速、默认输出电平为低电平重命名为BL_EN。
4、输入工程名选择工程路径不要有中文选择MDK-ARM V5勾选Generated periphera initialization as a pair of ‘.c/.h’ files per IP 点击GENERATE CODE生成工程代码
4、 MDK-ARM编程
在fsmc.c文件下可以看到FSMC的初始化函数
void MX_FSMC_Init(void){FSMC_NORSRAM_TimingTypeDef Timing {0};FSMC_NORSRAM_TimingTypeDef ExtTiming {0};hsram1.Instance FSMC_NORSRAM_DEVICE;hsram1.Extended FSMC_NORSRAM_EXTENDED_DEVICE;/* hsram1.Init */hsram1.Init.NSBank FSMC_NORSRAM_BANK4;hsram1.Init.DataAddressMux FSMC_DATA_ADDRESS_MUX_DISABLE;hsram1.Init.MemoryType FSMC_MEMORY_TYPE_SRAM;hsram1.Init.MemoryDataWidth FSMC_NORSRAM_MEM_BUS_WIDTH_16;hsram1.Init.BurstAccessMode FSMC_BURST_ACCESS_MODE_DISABLE;hsram1.Init.WaitSignalPolarity FSMC_WAIT_SIGNAL_POLARITY_LOW;hsram1.Init.WrapMode FSMC_WRAP_MODE_DISABLE;hsram1.Init.WaitSignalActive FSMC_WAIT_TIMING_BEFORE_WS;hsram1.Init.WriteOperation FSMC_WRITE_OPERATION_ENABLE;hsram1.Init.WaitSignal FSMC_WAIT_SIGNAL_DISABLE;hsram1.Init.ExtendedMode FSMC_EXTENDED_MODE_ENABLE;hsram1.Init.AsynchronousWait FSMC_ASYNCHRONOUS_WAIT_DISABLE;hsram1.Init.WriteBurst FSMC_WRITE_BURST_DISABLE;/* Timing */Timing.AddressSetupTime 0x01; //地址建立时间ADDSET为2个HCLK即2/72M 27.8nsTiming.AddressHoldTime 15; //默认值地址保持时间ADDHLD模式A未用到Timing.DataSetupTime 0x0f; //数据建立时间DATST为16个HCLK即16/72M 222.2nsTiming.BusTurnAroundDuration 0x00; //总线恢复时间Timing.CLKDivision 16; //默认值时钟分频同步突发访问方式才需要设置此值Timing.DataLatency 17; //默认值数据保持时间同步突发访问方式才需要设置此值Timing.AccessMode FSMC_ACCESS_MODE_A;/* ExtTiming */ExtTiming.AddressSetupTime 0x0f;//地址建立时间ADDSET为16个HCLK即16/72M 222.2nsExtTiming.AddressHoldTime 15; //默认值地址保持时间ADDHLD模式A未用到ExtTiming.DataSetupTime 0x05; //数据建立时间DATST为6个HCLK即6/72M 83.3nsExtTiming.BusTurnAroundDuration 0x00; //总线恢复时间ExtTiming.CLKDivision 16; //默认值时钟分频同步突发访问方式才需要设置此值ExtTiming.DataLatency 17; //默认值数据保持时间同步突发访问方式才需要设置此值ExtTiming.AccessMode FSMC_ACCESS_MODE_A;if (HAL_SRAM_Init(hsram1, Timing, ExtTiming) ! HAL_OK){Error_Handler( );}__HAL_AFIO_FSMCNADV_DISCONNECTED();
}
创建TFTLCD驱动文件tftlcd.c 和相关头文件tftlcd.h 本例程使用FSMC存储器1的第4区驱动LCDTFTLCD的RS接在FSMC_A10上CS接在FSMC_NE4上并且是16位数据总线可以在tftlcd.h里定义如下LCD操作结构体
//TFTLCD操作结构体
typedef struct{uint16_t LCD_CMD;uint16_t LCD_DATA;
}TFTLCD_TypeDef;
//HADDR[27,26]11A10作为数据命令区分线
//设置时STM32内部会右移以为对齐
#define TFTLCD_BASE ((uint32_t)(0x6C000000 | 0x000007FE))
#define TFTLCD ((TFTLCD_TypeDef *) TFTLCD_BASE)
//0x6C000000是Bank1.sector4的起始地址0x000007FE是A10的偏移量
//0x7FE即11111111110,16位数据宽度时地址需要右移一位对齐
//因此实际对应到引脚时A10:A001111111111此时A10是0
//如果16位地址再加1,则A10:A010000000000此时A10是1
//有了以上定义LCD写命令/数据极为方便
TFTLCD-LCD_CMD CMD; //写命令
TFTLCD-LCD_DATA DATA; //写数据
//读的时候反过来操作即可
CMD TFTLCD-LCD_CMD //读LCD寄存器
DATA TFTLCD-LCD_DATA //读LCD数据
tftlcd.h中另一个重要结构体管理LCD重要参数 //LCD重要参数集
typedef struct{ uint16_t width; //LCD宽度uint16_t height; //LCD高度uint16_t id; //LCD IDuint8_t dir; //LCD显示方向
}_tftlcd_data;
extern _tftlcd_data tftlcd_data; //管理LCD重要参数
几个简单但是很重要的函数 #define TFTLCD_R61509VN //本例程的TFTLCD屏驱动类型为R61509VN
//写寄存器函数cmd寄存器地址
void LCD_WriteCmd(uint16_t cmd){TFTLCD-LCD_CMD(cmd8)1;TFTLCD-LCD_CMD(cmd0xff)1; //写入要写的寄存器序号
}
//写LCD数据data要写入的值
void LCD_WriteData(uint16_t data){TFTLCD-LCD_DATA(data8)1;TFTLCD-LCD_DATA(data0xff)1;
}
//写寄存器cmd寄存器地址data要写入的数据
void LCD_WriteCmdData(uint16_t cmd,uint16_t data){LCD_WriteCmd(cmd);LCD_WriteData(data);
}
//读LCD数据返回读到的值
uint16_t LCD_ReadData(void){ uint16_t ram; ram(TFTLCD-LCD_DATA)1;ramram8;ram|(TFTLCD-LCD_DATA)1; return ram;
}
链接 百度网盘 请输入提取码 提取码tvil 链接 https://pan.baidu.com/s/1Zb8qI-yZ795eyjGyXpgocQ?pwdfnro 提取码fnro void LCD_Display_Dir(uint8_t dir); //设置LCD显示方向
void LCD_Set_Window(uint16_t sx,uint16_t sy,uint16_t width,uint16_t height); //设置窗口
void LCD_Clear(uint16_t Color); //清屏
void LCD_Fill(uint16_t xState,uint16_t yState,uint16_t xEnd,uint16_t yEnd,uint16_t color); //在指定区域内填充颜色
void LCD_DrawPoint(uint16_t x,uint16_t y); //画点
void LCD_DrawFRONT_COLOR(uint16_t x,uint16_t y,uint16_t color); //指定颜色画点
uint16_t LCD_ReadPoint(uint16_t x,uint16_t y); //读取某点的颜色
void LCD_DrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2); //画线
void LCD_DrawLine_Color(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2,uint16_t color); //指定颜色画线
void LCD_DrowSign(uint16_t x, uint16_t y, uint16_t color); //画十字标记
void LCD_DrawRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2); //画矩形
void LCD_Draw_Circle(uint16_t x0,uint16_t y0,uint8_t r); //指定位置画指定大小的圆
void LCD_ShowChar(uint16_t x,uint16_t y,uint8_t num,uint8_t size,uint8_t mode); //在指定位置显示一个字符
void LCD_ShowNum(uint16_t x,uint16_t y,uint32_t num,uint8_t len,uint8_t size); //显示数字不显示高位的0
void LCD_ShowxNum(uint16_t x,uint16_t y,uint32_t num,uint8_t len,uint8_t size,uint8_t mode); //显示数字显示高位的0
void LCD_ShowString(uint16_t x,uint16_t y,uint16_t width,uint16_t height,uint8_t size,uint8_t *p); //显示字符串
void LCD_ShowFontHZ(uint16_t x, uint16_t y, uint8_t *cn); //显示汉字
void LCD_ShowPicture(uint16_t x, uint16_t y, uint16_t wide, uint16_t high,uint8_t *pic); //显示图片
在main.c文件下编写TFTLCD测试代码
int main(void){HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_FSMC_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 */TFTLCD_Init(); FRONT_COLORBLACK;LCD_ShowString(10,10,240,400,12,(uint8_t*)TFTLCD Testing...!);FRONT_COLORRED;LCD_ShowString(10,30,240,400,16,(uint8_t*)TFTLCD Testing...!);FRONT_COLORGREEN;LCD_ShowString(10,50,240,400,24,(uint8_t*)TFTLCD Testing...!); /* USER CODE END 2 */while (1){HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_5);HAL_Delay(200);}
}
5. 下载验证
STM32CubeMX生成的代码默认优化级别为Level 3在此优化级别下编译无误下载到开发板后可以看到D1指示灯不断闪烁但是LCD屏不能被点亮将优化级别调整到Level 0编译下载后LCD屏能够被点亮
KEIL5中C/C优化等级介绍 -O0最少的优化可以最大程度上配合产生代码调试信息可以在任何代码行打断点特别是死代码处。 -O1有限的优化去除无用的inline和无用的static函数、死代码消除等在影响到调试信息的地方均不进行优化。在适当的代码体积和充分的调试之间平衡代码编写阶段最常用的优化等级。 -O2高度优化调试信息不友好有可能会修改代码和函数调用执行流程自动对函数进行内联等。 -O3最大程度优化产生极少量的调试信息。会进行更多代码优化例如循环展开更激进的函数内联等。 编译无误下载到开发板后可以看到D1指示灯不断闪烁LCD屏显示相应的文字串口打印出LCD的ID信息 6、参考文献 STM32CubeMX学习笔记38——FSMC接口使用TFT-LCD屏显示_cubemx配置lcd时复位引脚-CSDN博客
STM32CubeMX系列 | TFTLCD显示 - 知乎 (zhihu.com)