当前主流的显示器件
1.LED大屏幕
主要应用在大型的商场,也是由一块块的小型的屏幕拼接到一起的,背面会比较厚 在工作过程中会产生大量的热,有些LED后边会有一个空调 专门用来散热。
2.数码管
51单片机上使用七段或者是八段数码管的较多
3.点阵屏
OLED:自发光的二级管 可以弯曲
LCD:技术相对来说比较成熟 寿命远高于OLED,LCD 的构造是在两片平行的玻璃基板当中放置液晶盒,下基板玻璃上设置TFT(薄膜晶体管),上基板玻璃上设置彩色滤光片,通过TFT上的信号与电压改变来控制液晶分子的转动方向,从而达到控制每个像素点偏振光出射与否而达到显示目的。LCD屏又分为:电阻屏、电容屏;
电阻屏:全称为电阻式触摸屏,俗称“软屏”,结构上分为三层,里层是玻璃,外层是薄膜,在薄膜和玻璃相邻的一面都涂上ITO(铟锡金属氧化物)。通过点触产生通路,通过电压差来定位,需要进行校准(三点校准,五点校准)这个只要开机就要进行校准。(一点触控)
电容屏:全称为电容式触摸屏,俗称“硬屏”,是一块四层复合玻璃屏,第一层是ITO,用以保证工作环境,第二层是玻璃,第三层也为ITO涂层,做工作面使用;第四层则是矽土玻璃保护层。通过触碰改变电容,触摸芯片实时采集电容信号来实现定位(五点触摸和十点触摸校准)
4.水墨屏
没有任何发光 看起来就像看书本一样
原理,电子墨水屏其是由许多的电子墨水所组成,电子墨水我们可以把他们看成是一个个胶囊的样子,并且在每一个胶囊里面其都会有着液体电荷,其中正电荷染白色,负电荷染黑色,因此当我们在一侧给其给予正负电压时,带有电荷的液体就会被分别吸引和排斥。这样,每一个像素点就可以显示出白色又或者是黑色了。
5.显像管
在之前的老的电视机或者是“大头电脑”里,后端有一个阴极,他往外不停发射电子,经过偏转线圈调整 电子打到显示器上,这个时候我们看到的就是图像。
LCD常用的接口
接口类型分为:RGB 模式、SPI 模式、MDDI 模式、VSYNC 模式、DSI 模式、MCU 模式等
分类详解(引用)
8080并行接口
8080并行接口,又叫因特尔总线,是 MCU 模式中常用得一种总线,由数据总线和控制总线两部分组成。
引脚 | 说明 |
---|---|
CS | 片选信号 |
RD | MCU (MPU) 从LCD读数据控制线,上升沿有效,读数据时,WR拉高 |
WR | MCU(MPU) 向LCD写入数据控制线,上升沿有效,写数据时 RD拉高 |
DC (RS) | 数据/命令控制,L:低命令,H:高数据 |
RST | 硬件复位 LCD 信号 |
Data[0:x] | 数据总线,支持8/9/16/18/24bit,最常用的是8位 |
写数据:
- CS为低,选中
- RD为高, 禁止写
- DC/RS为高(写数据,写命令拉低)
- 在WR的上升沿,使数据写入到 驱动 IC 里面
- CS为高,结束一组数据读取
读数据:
- CS 拉低,选中
- DC/RS 为高(读数据)
- WR 为高,禁止写
- 在RD的上升沿,读线上的数据(D[0:7]),假设8位 8080并口
- CS 拉高,取消片选
8080时序通过io模拟太过复杂,采用FSMC模拟8080时序。
FSMC外设接口
由于 FSMC 外设可以用于控制扩展的外部存储器,而 MCU 对液晶屏的操作实际上就是把显示数据写入到显存中,与控制SRAM 存储器非常类似,且 8080 接口的通讯时序完全可以使用 FSMC 外设产生,因而非常适合使用 FSMC控制液晶屏。
统一编址:把外扩存储器地址统一编址到4G地址空间下,可以实现快速获取数据操作,内核对存储芯片操作 -- 直接操作内核地址=外部存储器地址。
独立编址:必须操作外部存储器地址,如:flash。
- 外扩的存储类型
— 静态随机访问存储器 (SRAM)
— 只读存储器 (ROM)
— NOR Flash/OneNAND Flash
— PSRAM(4 个存储区域) — PC 卡
接口介绍:
FSMC将1G的地址分成了四块:
LCD屏接口:使用NorFlash/PSRAM信号和共享信号,对应1G地址的Bank1
Bank1又分成了四个区:
将Bank1的四个区映射外部存储器地址:
以上是MCU阶段学习的,接下来是驱动内容。
本次采用的是tiny4412电容触摸屏
尺寸 | 七英寸 |
分辨率 | 800*480 |
像素位数 | 32位 |
屏幕刷新率 | 60FPS |
可以算出每秒钟所需的流量:
800*480*4 --1500k * 60 ---87.89M
这么大的数据使用SPI或者是IIC都不合适了 采用的接口是RGB接口。
开发板LCD屏驱动
lcd驱动生成的文件一般存放在/dev/fb0 这个fb0在Linux下一般表示这就是一个LCD屏,所谓的lcd的应用就是在学习 如何使用/dev/fb0这个文件。使用这个文件就要借助Linux提供的接口;
API
函数功能:将文件映射到进程中的内存空间
函数的头文件
#include<sys/mman.h>
函数原型
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
函数参数
void *addr :一般填写NULL 表示由系统指定一块内存空间供我们使用
size_t length :映射的空间的长度
int prot :PROT_READ | PROT_WRITE
int flags :MAP_SHARED 同步的变更
int fd :文件描述符
off_t offset:一般写0
函数返回值
返回的就是我们映射成功的地址空间,我们去操作这个地址,就相当于操作文件,同样的相当于操作我们的显示屏
映射空间的长度需要借助 ioctl 函数
int ioctl(int fd, ind cmd, …);
其中fd是用户程序打开设备时使用open函数返回的文件标示符,cmd是用户程序对设备的控制命令,至于后面的省略号,那是一些补充参数,一般最多一个,这个参数的有无和cmd的意义相关。
ioctl(fd,FBIOGET_VSCREENINFO,&fvs);
struct fb_var_screeninfo {__u32 xres; 横坐标的长 lcd的长__u32 yres; 纵坐标的长 lcd的宽__u32 xres_virtual; 虚拟坐标的长 __u32 yres_virtual; 虚拟的宽__u32 bits_per_pixel; :像素位 一个像素点占用多少位......................................};
在屏幕显示一张图片代码:
#include <stdio.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
//#include <stdint.h> //uint32_t 头文件extern unsigned char gImage_b[1152000];
u_int32_t *lcd_base=NULL;
struct fb_var_screeninfo fvs;void show_pic(u_int8_t *data,int w,int h)
{u_int32_t *p;int j,i;p=lcd_base;for(i=0;i<h;i++){for(j=0;j<w;j++){p[j]=data[j*3+i*3*w+2]<<16|data[j*3+i*3*w+1]<<8|data[j*3+i*3*w];}p+=fvs.xres_virtual;}
}int main()
{int fd;fd =open("/dev/fb0",O_RDWR);if(fd<0){perror("open");return -1;}ioctl(fd,FBIOGET_VSCREENINFO,&fvs);printf("真实的长度是:%d\n",fvs.xres);printf("真实的长度是:%d\n",fvs.yres);printf("真实的长度是:%d\n",fvs.xres_virtual);printf("真实的长度是:%d\n",fvs.yres_virtual);printf("像素位:%d\n",fvs.bits_per_pixel);lcd_base=mmap(NULL,fvs.xres_virtual*fvs.yres_virtual*fvs.bits_per_pixel/8,PROT_READ | PROT_WRITE,MAP_SHARED,fd,0);show_pic(gImage_b,800,480);return 0;
}