FMC驱动LCD

硬件简介

主控:STM32H750

LCD屏幕为16位并口屏幕

CubeMX配置

FMC配置

chip select: 选择起始地址块号,ADDR[27:26]

Memory type: 内存类型,选择LCD Interface

LCD Register Select: 根据选择计算映射地址, FSNC_A[25]

Data: 数据宽度

NOR/PSRAM timing: 调整时间,能够提升屏幕刷新的速率

代码

2.1 获取LCD屏幕驱动源码

获取到一份能够正常使用的屏幕驱动源码

2.2 计算地址

#define Bank1_LCD_DATA ((uint32_t)0x60080000) /* display data address */
#define Bank1_LCD_REG ((uint32_t)0X60000000)  /* display register addres
2.3.1 根据chip select计算 register addres

NE1 -NE4分别对应ADDR[27:26]对应00 - 11

对应的为映射起始地址

image-20231104135511377

2.3.2 根据Memory type和LCD Register Select计算data address

image-20231104140534952

对于8位数据宽度的地址为:

Bank1_LCD_DATA = Bank1_LCD_REG + 1 << 18(LCD Register Select + 0)

对于16位数据宽度的地址为:

Bank1_LCD_DATA = Bank1_LCD_REG + 1 << (18 + 1)(LCD Register Select + 1)

所以

#define Bank1_LCD_DATA ((uint32_t)0x60080000) /* display data address */

驱动代码

lcd.h

#ifndef __LCD_H
#define __LCD_H/* BEGIN Includes */
#include "main.h"
/* END Includes */void LCD_Fill(uint16_t xsta,uint16_t ysta,uint16_t xend,uint16_t yend,uint16_t color);
void LCD_Fill_1(uint16_t xsta,uint16_t ysta,uint16_t xend,uint16_t yend,uint8_t color);
void LCD_DrawPoint(uint16_t x,uint16_t y,uint16_t color);
void LCD_DrawRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2,uint16_t color);
//void LCD_ShowPicture(uint16_t x,uint16_t y,uint16_t length,uint16_t width,const uint8_t pic[]);
void LCD_ShowPicture(uint16_t x,uint16_t y,uint16_t length,uint16_t width,const uint16_t pic[]);#endif /* __LCD_H */

lcd.c

/* BEGIN Includes */#include "lcd.h"
#include "Lcd_init.h"
#include <string.h>
#include "dma.h"
/* END Includes *//******************************************************************************函数说明:在指定区域填充颜色入口数据:   xsta,ysta   起始坐标xend,yend   终止坐标color       要填充的颜色返回值:  无
******************************************************************************/
void LCD_Fill(uint16_t xsta,uint16_t ysta,uint16_t xend,uint16_t yend,uint16_t color)
{uint16_t i,j;LCD_Address_Set(xsta,ysta,xend-1,yend-1);for(i=ysta;i<yend;i++){for(j=xsta;j<xend;j++){LCD_WR_DATA(color);}}
}static uint8_t buf[240*10*2] __attribute__((section(".ARM.__at_0x38000400")));
void LCD_Fill_1(uint16_t xsta,uint16_t ysta,uint16_t xend,uint16_t yend,uint8_t color)
{memset(buf, color, sizeof(buf));LCD_Address_Set(xsta,ysta,xend-1,yend-1);HAL_DMA_Start_IT(&hdma_memtomem_dma1_stream0, (uint32_t)0x38000400, Bank1_LCD_DATA, ((yend + 1) - ysta) * ((xend + 1) - xsta) * 2);}
/******************************************************************************函数说明:在指定位置画点入口数据:x,y 画点坐标color 点的颜色返回值:  无
******************************************************************************/
void LCD_DrawPoint(uint16_t x,uint16_t y,uint16_t color)
{LCD_Address_Set(x,y,x,y);//LCD_WR_DATA(color);
}
/******************************************************************************函数说明:画线入口数据:x1,y1   起始坐标x2,y2   终止坐标color   线的颜色返回值:  无
******************************************************************************/
void LCD_DrawLine(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2,uint16_t color)
{uint16_t t;int xerr=0,yerr=0,delta_x,delta_y,distance;int incx,incy,uRow,uCol;delta_x=x2-x1; //delta_y=y2-y1;uRow=x1;//uCol=y1;if(delta_x>0)incx=1; //else if (delta_x==0)incx=0;//else {incx=-1;delta_x=-delta_x;}if(delta_y>0)incy=1;else if (delta_y==0)incy=0;//else {incy=-1;delta_y=-delta_y;}if(delta_x>delta_y)distance=delta_x; //else distance=delta_y;for(t=0;t<distance+1;t++){LCD_DrawPoint(uRow,uCol,color);//xerr+=delta_x;yerr+=delta_y;if(xerr>distance){xerr-=distance;uRow+=incx;}if(yerr>distance){yerr-=distance;uCol+=incy;}}
}
/******************************************************************************函数说明:画矩形入口数据:x1,y1   起始坐标x2,y2   终止坐标color   矩形的颜色返回值:  无
******************************************************************************/
void LCD_DrawRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2,uint16_t color)
{LCD_DrawLine(x1,y1,x2,y1,color);LCD_DrawLine(x1,y1,x1,y2,color);LCD_DrawLine(x1,y2,x2,y2,color);LCD_DrawLine(x2,y1,x2,y2,color);
}
/******************************************************************************函数说明:画圆入口数据:x0,y0   圆心坐标r       半径color   圆的颜色返回值:  无
******************************************************************************/
void Draw_Circle(uint16_t x0,uint16_t y0,uint8_t r,uint16_t color)
{int a,b;a=0;b=r;while(a<=b){LCD_DrawPoint(x0-b,y0-a,color);             //3LCD_DrawPoint(x0+b,y0-a,color);             //0LCD_DrawPoint(x0-a,y0+b,color);             //1LCD_DrawPoint(x0-a,y0-b,color);             //2LCD_DrawPoint(x0+b,y0+a,color);             //4LCD_DrawPoint(x0+a,y0-b,color);             //5LCD_DrawPoint(x0+a,y0+b,color);             //6LCD_DrawPoint(x0-b,y0+a,color);             //7a++;if((a*a+b*b)>(r*r))//{b--;}}
}/******************************************************************************函数说明:显示图片入口数据:x,y起点坐标length 图片长度width  图片宽度pic[]  图片数组    返回值:  无
******************************************************************************/void LCD_ShowPicture(uint16_t x,uint16_t y,uint16_t length,uint16_t width,const uint16_t pic[])
{uint16_t i,j;  uint32_t k=0;LCD_Address_Set(x,y,x+length-1,y+width-1);for(i=0;i<length;i++){for(j=0;j<width;j++){LCD_WR_DATA(pic[k]);k++;}}}

Lcd_init.h

#ifndef __LCD_INIT_H
#define __LCD_INIT_H/* BEGIN Includes */
#include "main.h"
/* END Includes */#define USE_HORIZONTAL 1  //设置横屏或者竖屏显示 0或1为竖屏 2或3为横屏#if USE_HORIZONTAL==0||USE_HORIZONTAL==1#define LCD_W 320
#define LCD_H 240#else
#define LCD_W 320
#define LCD_H 240
#endif//#define Bank1_LCD_DATA ((uint32_t)0x60108CA0) /* display data address */
#define Bank1_LCD_DATA ((uint32_t)0x6010fff0) /* display data address */
#define Bank1_LCD_REG ((uint32_t)0X60000000)  /* display register address */#define LCD_FMC_DATA(value) ((*(__IO uint8_t  *)(Bank1_LCD_DATA)) = ((uint8_t )(value))) // 写数据寄存器
#define LCD_FMC_REG(index) ((*(__IO uint8_t  *)(Bank1_LCD_REG)) = ((uint8_t )index))#define LCD_SCLK_Clr 	//HAL_GPIO_WritePin(GPIOE,GPIO_PIN_7,0)//SCL=SCLK
#define LCD_SCLK_Set 	//HAL_GPIO_WritePin(GPIOE,GPIO_PIN_7,1)#define LCD_MOSI_Clr	//HAL_GPIO_WritePin(GPIOE,GPIO_PIN_9,0)//SDA=MOSI
#define LCD_MOSI_Set	//HAL_GPIO_WritePin(GPIOE,GPIO_PIN_9,1)#define LCD_RES_Clr		HAL_GPIO_WritePin(GPIOE,GPIO_PIN_1,0)//RES
#define LCD_RES_Set		HAL_GPIO_WritePin(GPIOE,GPIO_PIN_1,1)#define LCD_DC_Clr		HAL_GPIO_WritePin(GPIOE,GPIO_PIN_4,0)//DC
#define LCD_DC_Set		HAL_GPIO_WritePin(GPIOE,GPIO_PIN_4,1)#define LCD_CS_Clr		HAL_GPIO_WritePin(GPIOC,GPIO_PIN_7,0)//CS
#define LCD_CS_Set		HAL_GPIO_WritePin(GPIOC,GPIO_PIN_7,1)#define LCD_BLK_Clr() //HAL_GPIO_WritePin(GPIOE,GPIO_PIN_9,0)//BLK
#define LCD_BLK_Set() //HAL_GPIO_WritePin(GPIOE,GPIO_PIN_7,1)void LCD_Writ_Bus(uint8_t dat);//
void LCD_WR_DATA8(uint8_t dat);//
void LCD_WR_DATA(uint16_t dat);//
void LCD_WR_REG(uint8_t dat);//
void LCD_Address_Set(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2);//
void LCD_Init(void);//#endif /* __LCD_INIT_H */

Lcd_init_.c

/* BEGIN Includes */#include "Lcd_init.h"
#include "lcd.h"/* END Includes */void LCD_Writ_Bus(uint8_t dat) 
{LCD_FMC_DATA(dat);
}
void LCD_WR_DATA8(uint8_t dat)
{LCD_FMC_DATA(dat);
}void LCD_WR_DATA(uint16_t dat)
{LCD_FMC_DATA(dat >> 8);LCD_FMC_DATA(dat);
}void LCD_WR_REG(uint8_t dat)
{LCD_FMC_REG(dat);
}
void LCD_Address_Set(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2)
{LCD_WR_REG(0x2a);//LCD_Writ_Bus(x1>>8);LCD_Writ_Bus(x1);LCD_Writ_Bus(x2>>8);LCD_Writ_Bus(x2);LCD_WR_REG(0x2b);//LCD_Writ_Bus(y1>>8);LCD_Writ_Bus(y1);LCD_Writ_Bus(y2>>8);LCD_Writ_Bus(y2);LCD_WR_REG(0x2c);//
}
void LCD_Init(void)
{LCD_RES_Clr;//HAL_Delay(100);LCD_RES_Set;HAL_Delay(100);LCD_BLK_Set();//HAL_Delay(100);//************* Start Initial Sequence **********//LCD_WR_REG(0x11);HAL_Delay(1000); //Delay 120msLCD_WR_REG(0X36);// Memory Access Controlif(USE_HORIZONTAL==0)LCD_WR_DATA8(0x00);else if(USE_HORIZONTAL==1)LCD_WR_DATA8(0xC0);else if(USE_HORIZONTAL==2)LCD_WR_DATA8(0x70);else LCD_WR_DATA8(0xA0);LCD_WR_REG(0X3A);LCD_WR_DATA8(0X05);//--------------------------------ST7789S Frame rate setting-------------------------LCD_WR_REG(0xb2);LCD_WR_DATA8(0x0c);LCD_WR_DATA8(0x0c);LCD_WR_DATA8(0x00);LCD_WR_DATA8(0x33);LCD_WR_DATA8(0x33);LCD_WR_REG(0xb7);LCD_WR_DATA8(0x35);//---------------------------------ST7789S Power setting-----------------------------LCD_WR_REG(0xbb);LCD_WR_DATA8(0x35);LCD_WR_REG(0xc0);LCD_WR_DATA8(0x2c);LCD_WR_REG(0xc2);LCD_WR_DATA8(0x01);LCD_WR_REG(0xc3);LCD_WR_DATA8(0x13);LCD_WR_REG(0xc4);LCD_WR_DATA8(0x20);LCD_WR_REG(0xc6);LCD_WR_DATA8(0x0f);LCD_WR_REG(0xca);LCD_WR_DATA8(0x0f);LCD_WR_REG(0xc8);LCD_WR_DATA8(0x08);LCD_WR_REG(0x55);LCD_WR_DATA8(0x90);LCD_WR_REG(0xd0);LCD_WR_DATA8(0xa4);LCD_WR_DATA8(0xa1);//--------------------------------ST7789S gamma setting------------------------------LCD_WR_REG(0xe0);LCD_WR_DATA8(0xd0);LCD_WR_DATA8(0x00);LCD_WR_DATA8(0x06);LCD_WR_DATA8(0x09);LCD_WR_DATA8(0x0b);LCD_WR_DATA8(0x2a);LCD_WR_DATA8(0x3c);LCD_WR_DATA8(0x55);LCD_WR_DATA8(0x4b);LCD_WR_DATA8(0x08);LCD_WR_DATA8(0x16);LCD_WR_DATA8(0x14);LCD_WR_DATA8(0x19);LCD_WR_DATA8(0x20);LCD_WR_REG(0xe1);LCD_WR_DATA8(0xd0);LCD_WR_DATA8(0x00);LCD_WR_DATA8(0x06);LCD_WR_DATA8(0x09);LCD_WR_DATA8(0x0b);LCD_WR_DATA8(0x29);LCD_WR_DATA8(0x36);LCD_WR_DATA8(0x54);LCD_WR_DATA8(0x4b);LCD_WR_DATA8(0x0d);LCD_WR_DATA8(0x16);LCD_WR_DATA8(0x14);LCD_WR_DATA8(0x21);LCD_WR_DATA8(0x20);LCD_WR_REG(0x29);//	LCD_WR_REG(0x21);			//´򿪑Չ«·´ת	
} 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分享一个抖音视频解析神器~

怎么样下载抖音视频&#xff1f;相信很多人都有过这样的困惑。作为一个资深短视频剪辑工作者&#xff0c;常常需要用到各种视频素材&#xff0c;其中不乏需要从抖音上下载的&#xff0c;因此我也尝试过许多下载工具&#xff0c;但是效果都不大满意&#xff0c;直到有一次朋友给…

el-table表格设置——动态修改表头

(1) 首先是form表单写表单设置按钮&#xff1a; &#xff08;1.1&#xff09;使用el-popover&#xff0c;你需要修改的是this.colOptions&#xff0c;colSelect: <el-popover id"popover" popper-class"planProver" placement"bottom" width&…

算法?认识一下啦

一、什么是算法&#xff1f; 算法 &#xff0c;是对特定问题求解方法和步骤的一种描述。它是有限指令的有限序列&#xff0c;其中每个指令表示一个或多个操作。 算法和程序的关系 算法​是解决问题的一种方法或一个过程&#xff0c;考虑如何将输入转换成输出&#xff0c;一个…

高防IP的原理

高防IP&#xff0c;把域名解析到高防IP上(web事务只要把域名指向高防IP 即可。非web事务&#xff0c;把事务IP换成高防IP即可)一起在高防IP上设置转发规矩;所有公网流量都会走高防IP&#xff0c;通过端口协议转发的方法将用户的拜访通过高防IP转发到源站IP&#xff0c;一起将歹…

《C/C++代码审计实践》一书出版了

我撰写了代码审计一书&#xff0c;包括了C、C、Java语言&#xff0c;加起来有600多页&#xff0c;书籍太厚&#xff0c;印刷成本比较高&#xff0c;出版社对于代码审计将来的销量也有所担心&#xff0c;他们更担心的在书中涉及到了对国家标准的解读&#xff0c;尤其是国家军用标…

XML External Entity-XXE-XML实体注入

XML 实体? XML 实体允许定义标签,在解析 XML 文档时这些标签将被内容替换。一般来说,实体分为三种类型: 内部实体 外部实体 参数实体。 必须在文档类型定义(DTD)中创建实体 一旦 XML 文档被解析器处理,它将js用定义的常量“Jo Smith”替换定义的实体。正如您所看到…

SystemC入门完整编写示例:全加器测试平台

导读: 本文将完整演示基于systemC编写一个全加器的测试平台。具体内容包括&#xff1a;激励平台&#xff0c;监控平台&#xff0c;待测单元的编写&#xff0c;波形文件读取。 1&#xff0c;main函数模块 搭建一个测试平台主要由&#xff1a;Driver, Monitor, DUT(design under …

【实验记录】为了混毕业·读读论文叭

PR曲线 1. Robust_Place_Recognition_using_an_Imaging_Lidar 在第三节方法中&#xff0c;提到了一些列处理步骤&#xff0c;分析来与vins相似&#xff0c;在vins中是关键帧检索、特征提取、DBoW查询、描述子匹配、PnP RANSAC求解。 第四节的实验部分&#xff0c;没有绘制pr…

Aop自定义注解生成日志

Aop自定义注解生成日志 1.编写自定义注解 //表示此注解可以标注在方法上 Target(ElementType.METHOD) //运行时生效 Retention(RetentionPolicy.RUNTIME) public interface OpetionLog {//定义一个变量&#xff0c;可以接收参数String value() default "";}2.Cont…

MVCC详解

什么是MVCC&#xff1f; MVCC&#xff0c;即Multi-Version Concurrency Control &#xff08;多版本并发控制&#xff09;。它是一种并发控制的方法&#xff0c;一般在数据库管理系统中&#xff0c;实现对数据库的并发访问&#xff0c;在编程语言中实现事务内存。 通俗的讲&am…

【完美世界】石昊拒绝云曦相认,爱而不得,云曦悲伤无助

Hello,小伙伴们&#xff0c;我是小郑继续为大家深度解析国漫资讯。 深度爆料《完美世界云曦篇》最新一集&#xff0c;为了云曦&#xff0c;石昊不远十万里&#xff0c;亲自送她回家&#xff0c;这份感情之真挚&#xff0c;绝对毋庸置疑。然而&#xff0c;令人感到不解的是&…

二维码智慧门牌管理系统升级:引领政务服务、寄件、开锁、刻章新潮流

文章目录 前言一、政务服务二、寄件服务三、便民开锁和刻章服务四、应用范围 前言 在科技不断进步的时代&#xff0c;二维码智慧门牌管理系统升级版正在改变我们的生活&#xff0c;为政务服务、寄件、便民开锁、刻章等多种业务应用提供全新的解决方案&#xff0c;使我们的日常…

Zotero 超好用插件的下载链接及配置方法(PDF-translate/ZotFile/茉莉花/Zotero Scihub)

目录 前言插件安装方法插件一&#xff1a;文献翻译插件&#xff08;pdf-translate&#xff09;插件二&#xff1a;文献附件管理&#xff08;ZotFile&#xff09;插件三&#xff1a;中文文献插件&#xff08;茉莉花&#xff09;插件四&#xff1a;Sci-Hub 自动下载文献&#xff…

3D模型格式转换工具HOOPS Exchange对工业级3D产品HOOPS的支持与应用

一、概述 HOOPS Exchange是一套高性能模型转换软件库&#xff0c;可以给软件提供强大的模型的导入和导出功能&#xff0c;我们可以将其单独作为转换工具使用&#xff0c;也可以将其集成到自己的软件中。 同样&#xff0c;HOOPS 的其它产品&#xff0c;也离不开HOOPS Exchange…

Docker学习——②

文章目录 1、Docker是什么1.1 Docker本质1.2 Docker的引擎迭代1.3 Docker和虚拟机的区别1.4 Docker 为什么比虚拟机资源利用率高&#xff0c;启动快&#xff1f;1.5 Docker 和 JVM 虚拟化的区别&#xff1f; 2、Docker架构3、Docker生态3.1 新时代软件诉求3.2 Docker 解决方案 …

蓝桥杯 (C++ 求和 等差数列 顺子日期 灌溉)

目录 1、求和 题目&#xff1a; 思路&#xff1a; 代码&#xff1a; 2、等差数列 题目&#xff1a; 思路&#xff1a; 代码&#xff1a; 3、顺子日期 题目&#xff1a; 思路&#xff1a; 代码&#xff1a; 4、灌溉 题目&#xff1a; 代码&#xff1a; 1、求和…

误删的文件恢复了成乱码 误删的文件恢复了成乱码怎么调整

电脑系统&#xff1a;Windows11 电脑型号&#xff1a;惠普 软件版本&#xff1a;EasyRcovery14 关于电脑&#xff0c;我们可以说是非常熟悉&#xff0c;并熟练掌握了对电脑的最基本操作&#xff0c;比如复制、粘贴、新建、删除文件。但我们真的很懂它吗&#xff1f;比如误删…

Azure 机器学习 - 设置 AutoML 训练时序预测模型

目录 一、环境准备二、训练和验证数据三、配置试验支持的模型配置设置特征化步骤自定义特征化 四、可选配置频率和目标数据聚合启用深度学习目标滚动窗口聚合短时序处理非稳定时序检测和处理 五、运行试验六、用最佳模型进行预测用滚动预测评估模型精度预测未来 七、大规模预测…

计算虚拟化3——I/O设备虚拟化

目录 I/O基本概念 I/O设备与CPU连接图 CPU与I/O设备的交互 访问I/O设备&#xff08;IO Access&#xff09; 数据传输&#xff08;Data Tronhsfer&#xff09; I/O设备虚拟化技术 软件辅助全虚拟化 半虚拟化 Virtio协议基本概念 Virtqueue讲解 硬件辅助全虚拟化 I/O…

C语言编译过程总结

开发C程序有四个步骤&#xff1a;预处理、编译、汇编和链接。任何一个体系结构处理器上都可以使用C语言程序&#xff0c;只要该体系结构处理器有相应的C语言编译器和库&#xff0c;那么C源代码就可以编译并连接到目标二进制文件上运行。 我们创建一个test.c为例来讲解程序编译的…