这一个星期认真学习了硬件原理图的知识,做了一些笔记,方便以后查找。
硬件原理图分为三类
1.管脚类(gpio)和门电路类
输入输出引脚,上拉电阻,三极管
与门,或门,非门
上拉电阻:正向标志作用,给悬空的引脚一个确定的状态
三极管:反向三极管(gpio输出高电平,NP两端导通,被控制端导通,电压为0)->NPN
正向三极管(gpio输出低电平,PN两端导通,被控制端导通,电压为0)->PNP
2.协议类(1.双方约定一定的信号传输协议 2.双方满足一定的时序要求),硬件协议就是硬件的工作流程一般只能通过硬件的芯片手册看出来,比如nand flash只能通过具体的nand芯片的手册如K9F2G08U0C手册。看它的工作时序图看一看出部分硬件协议;
uart: (原理图接线+硬件协议+软件启动流程)
波特率:一秒钟可以传输多少位数据
原理图:一般是cpu接出两根线TXD0,RXD0分别为发线,收线,但一般还要接一根地线作为上面两根数据线的电平参考值0; cpu接出来的两根数据线的高电平1用3.3v的电压表示,0用0v表示,但是因为串口线一般有一段距离从开发板到PC,所以3.3v的驱动力是不够的,一般TXD0,RXD0都要经过一个电平转换芯片增强电压的驱动力,数据0用(-9v~-12v表示),数据1用(9v~12v表示)经过电平转换之后TXD0,RXD0才分别与PC机的两根数据线相连。
硬件协议:比如2440想要发0x41(0100 0001)这个数据给PC机,那么就要通过TXD0这根数据线发出去。协议过程如下:
在发送之前2440的TXD0线一直是高电平的,想要发出数据(0100 0001)到数据线上了,先要发出一个启始位(相当于i2c的start信号),这个启始位就是拉低数据线为0v并且这个低电平要维持一段时间T(这就是时序),PC机发现自己的RXD0被拉低了T时间段,知道这是对方发出的start信号了,这个启始位就是双方约定的协议内容。起始位一般都是一个bit,起始位信号发出去之后,就要将数据01000001一位一位地发送到数据线上,8bit都发送完毕之后,发出停止位(类似于i2c的stop信号,这个停止位一般是1个bit,将数据线的电平拉高并且维持T时间段就行了)具体的协议流程可以观看图片:串口协议图示.png
奇偶检验位是指在发完数据位之后在发停止位之前在这两者之前发一个0或者1作奇偶检验
比如如果是奇检验,假如数据是0x41(01000001),则校验位就要发一个1,使得发送的数据的1的个数为奇数。但这个校验位的数据不会放进数据位里,不影响数据传输。一般也可以不用校验位。数据位一般都用8bit,停止位1bit,起始位和停止位的维持的时间t=1/115200,所以2440和PC机都要遵守一个协议
1.波特率一致,使得双方的起始位与停止位维持的时间t一致,双方可以分辨出起始信号和停止信号。
2.数据位一致,都是8bit数据一次传输。
3.奇偶检验一致。
4.起始位个数一致,一般都是1位,而且免设置。
5.停止位一致。都是1位就行
软件的启动流程:看2440的芯片手册有关uart的接口设置那一章,设置波特率为115200,数据位为8位,奇偶校验不用,停止位1位,PC段串口接收也同样这样设置。双方协议一致才可以互相认得对方是什么意思才可以通信。
i2c:(原理图接线+硬件协议+软件启动流程)
原理图:2根线接到i2c的控制器,分别是sclk(时钟线),sdat(数据线),cpu给i2c外设提供时钟,并且根据外设的slave id区别从机,8位地址的最多可以接128个从机(2的7次方),10位的地址要发两次slave id(byte0:11110A9A8)(byte1:A7~A0)
硬件协议(读):sda/scl两根线匹配发出start信号(硬件触发),通过data线将8位的slave id发出去,从机匹配产生ACK响应,重新发出start信号,通过data线将8位的片内地址发出去从机响应ACK,从机通过data线将8bit数据传回来到i2c控制器。
软件的启动流程:具体的驱动流程,要看cpu的i2c control手册以及i2c外设手册共同决定。
spi:
原理图:4根线接到cpu的spi控制器,分别是spimosi(主机输出从机输入,写线),spimiso(主机输入从机输出,读线),时钟线(clk,cpu给设备提供时钟),片选线(区别各个设备从机的根据,一般用gpio管脚作片选线)
硬件协议:片选,发出cmd/addr/data(每次8bit)到写线上,数据开始传输,取消片选。
软件启动流程:要看cpu的spi control手册以及spi外设手册共同决定。
nand: soc有专门的nand接口
一般存储芯片都是先发出地址信号再发出数据信号,数据信号有专门的数据线DATA0~DATA7,那地址信号是否有对应的ADDR0~ADDR7呢?
nand的芯片手册会告诉你怎么通过nand芯片的各个引脚来对nand进行访问(读写操作)
nand的操作其实就是访问一个存储设备,需要发出命令,发出片内地址,然后启动数据传输,这个原始的访问过程需要多条管脚相互配合来完成。
写nand的设备驱动,要先看nand的外设芯片手册了解了其硬件协议之后,再看主控芯片2440的nand控制器的手册,两者配合才可以写出nand的驱动程序。
假如现在要写nand的设备驱动,要遵循以下的步骤:
原理图:nand芯片的各个管脚是怎么接到主控芯片2440的nand控制器的?看原理图发现
nand芯片上有8根IO线(IO0~IO7)被接到主控芯片2440的LDATA0~LDATA7;
nand芯片上的管脚R/B被接到主控芯片2440的RnB接口;
nand芯片上的管脚CLE被接到主控芯片2440的CLE接口;
nand芯片上的管脚CE被接到主控芯片2440的nFCE接口;
nand芯片上的管脚ALE被接到主控芯片2440的ALE接口;
nand芯片上的管脚WE被接到主控芯片2440的nFWE接口;
nand芯片上的管脚RE被接到主控芯片2440的nFRE接口;
nand芯片上的管脚WP被接到3.3v电源上;
必须明白一点:硬件协议都是通过读外设的芯片手册得到的
那nand芯片的这些管脚有什么意义呢?看nand flash的外设芯片手册发现:
WP:如果这个管脚被拉低那么nand就被写保护了,现在原理图上是接死3.3v的电压,就是一直拉高,那么就是一直取消写保护;
I/O0 ~ I/O7:写操作的时候这8根数据线被用作输入命令,地址和数据,读操作的时候这8根数据线被用作输出数据;
CLE:当这个管脚为高电平的时候,主控芯片2440里command register里的数据就会通过I/O0 ~ I/O7发出去;
CE:当这个管脚被拉低的时候,这个设备被选中了,当假如设备正忙的时候强制拉低这个管脚,nand也是不可被访问的;
ALE:如果这个管脚被拉高,那么主控芯片2440里的addr register里的数据就会通过8根io线发出去;
R/B:这一个管脚表明nand这个设备的状态,假如这个管脚向2440输出低电平,那说明nand正忙;
WE:当这个管脚被拉低的时候,数据的运输的方向为2440->nand,即为写操作,每拉低一次传一个字节;
RE:当这个管脚被拉低的时候,数据的运输方向为2440<-nand,即为读操作,每拉低一次传一个字节;
但是明白了这些管脚的意义了好像也不知道怎么访问nand,比如我想读devID,我要怎么操作呢?
猜想为:1.管脚CE拉低 2.管脚CLE拉高 3.管脚RE拉低 4.去8根io线那里读取数据值就行了
硬件协议:有多少种工作模式就有多少种硬件协议。
但是标准的硬件协议还是从nand的芯片手册找答案:我们发现不同的操作有不同的协议:
如读ID的协议:
1.先片选(将CE线拉低)。
2.发出读ID命令信号0x90(将0x90放在IO线上,将CLE线拉高并持续时间段T同时将ALE线拉低并且维持时间t说明IO线上的数据是命令),然后将WE线拉低并且持续时间t(此时已经将0x90作为命令发送出去了);
3.发出地址0x00(将0x00放在IO线上,将ALE线拉高并持续时间段T同时将CLE线拉低并且维持时间t说明IO线上的数据是地址),然后将WE线拉低并且持续时间t(此时已经将0x00作为地址值发送出去)了;
4.从IO线上读回数据(将RE线拉低一次可以从IO线上读回一个字节的数据,反复拉低5次就可以读到5个字节的数据。
5.取消片选(将CE线拉高)。
随意写的硬件协议:比如2440想往nand的0x10地址写入数据0x88;其硬件协议是这样的:
1.片选(将CE线拉低)
2.发出写命令0x85(将0x85放在IO0~IO7上,将nand芯片的CLE线拉高并且维持一段时间t同时ALE线要拉低一段时间t(说明io线上的数据作为命令),将WE线拉低并且维持一段时间t->这个时候命令0x85已经发送出去了)
3.发出地址0x10(将0x10放在IO0~IO7上,将nand芯片的CLE线拉低并且同时将ALE线拉高(说明IO线上的数据是地址),将WE线拉低并且维持一段时间t->这个时候地址0x10已经发送出去了)
4.发出数据0x88(将数据0x88放在IO0~IO7上,将nand芯片的CLE,ALE两根线同时拉低并且维持一段时间(说明IO线上的数据就是纯数据),将WE线拉低并且维持一段时间t->这个时候数据0x88已经发送出去了)
5.取消片选(CE线拉高)
随意读的硬件协议:比如2440想读nand芯片的0x10地址的值;其硬件协议是这样的:
1.片选(将CE线拉低)
2.发出读命令0x05(将0x05放在IO0~IO7上,将nand芯片的CLE线拉高并且维持一段时间t同时ALE线要拉低一段时间t(说明io线上的数据作为命令),将WE线拉低并且维持一段时间t->这个时候命令0x05已经发送出去了)
3.发出读命令0xE0(将0xE0放在IO0~IO7上,将nand芯片的CLE线拉高并且维持一段时间t同时ALE线要拉低一段时间t(说明io线上的数据作为命令),将WE线拉低并且维持一段时间t->这个时候命令0xE0已经发送出去了)
4.发出地址0x10(将0x10放在IO0~IO7上,将nand芯片的CLE线拉低并且同时将ALE线拉高(说明IO线上的数据是地址),将WE线拉低并且维持一段时间t->这个时候地址0x10已经发送出去了)
5.读回数据0x88(将RE线拉低一次就从IO0~IO7上读到一个字节,这个数据就是之前写进去的0x88)
6.取消片选(CE线拉高)
软件驱动设计:就是通过2440的nand控制器去完成上面的各个步骤,比如我想去读flash的devID
首先看原理图nand芯片的ALE CLE RnB NCON nFCE nFRE nFWE这些管脚被连到的2440 GPA17,18,19,20,22,可能先要管脚初始化。
1.先片选(NFCONT的bit1置0)
2.发出读ID命令信号0x90(将0x90写入NFCMMD寄存器),自动将WE线拉低一段时间
3.发出地址0x00(将0x90写入NFADDR寄存器),自动将WE线拉低一段时间
4.从IO线上读回数据(读寄存器NFDATA),自动将RE线拉低一段时间
5.取消片选(NFCONT的bit1置1)
lcd:最关键的是看LCD的外设芯片手册,结合管脚分析各个管脚的作用,确定lcd芯片的电源,屏幕的背光电源的来源;
电路图:EN表示高电平有效,nEN或者/EN表示低电平有效,或者EN上面有一根横线也表示低电平有效;
lcd的原理图:管脚对接并且分析管脚,从lcd屏的插槽开始分析,因为插槽一边链接主控芯片2440,一边连接lcd芯片;
VCLK: 负责喷枪的移动,ic的内部设计原理是->每来一个时钟喷枪就会移动在下一个像素的位置;
VSYNC: 水平方向的同步信号,当像素的横坐标等于图像的水平像素数量时发出信号告诉喷枪去到下一行像素的起点;
HSYNC: 垂直方向的同步信号,当像素的纵坐标等于图像的垂直像素数量时发出信号告诉喷枪回到起点(0.0),准备开始下一张图像的开始描绘;
VD0~VD23: 24根管脚发送像素的RGB数据,每一根线对应一个bit;
DE: data enable数据使能引脚,当这个管脚使能(拉高或拉低),数据线(VD0~VD23)的24bit RGB数据才可以输出,否则即使时钟使能喷枪移动,没有RGB数据,屏幕也只是背光点亮,没有颜色;
VDD: LCD芯片的内部电源供电,分析原理图可以得知VDD的电源来自一个电压转换芯片,而这个电压转换芯片的启动电压来自2440的一个GPIO管脚,这个管脚输出高电压就会使得电压转换芯片输出电压供电给LCD芯片的VDD管脚。
LED+,LED-: LCD屏幕的背光电压,上面的VDD只是给LCD芯片供电,这个LED+,-是给屏幕供电,我们可以看到屏幕亮起来;分析原理图得知这两根LED+,-也接来源一个电压转换芯片,这个电压转换芯片的供电也是来自2440的一个GPIO管脚,2440要使能这个管脚让其输出对应的电压就可以启动电压转换芯片给LED+,-供电从而点亮屏幕背光;
lcd的协议:clk(数据输出时钟),vsync(水平同步信号),hsync(垂直同步信号),de(像素数据使能),VD0~VD23(像素RGB数据管脚);
LCD的协议就是这28根线互相配合工作。配置好主控芯片的LCD接口之后(包括各个信号的时序,时钟这些),lcd芯片的ic内部就会根据时钟一个时钟周期一个描绘一个像素的原理
去24根数据线那里取到数据去喷涂在屏幕上(前提是DE管脚使能,24根线的数据得以输出);clk线负责驱动喷枪并且逐个像素点移动至于是怎样的移动原理那是ic内部设计的问题
反正主控芯片给时钟就可以驱动喷枪了,vsync线负责让喷枪喷满水平像素之后自动跳到下一行,hsync线负责喷枪的纵坐标到达像素的屏幕的竖直最大像素之后自动回到(0.0)准备开始下一张图像;
DE线负责让24根数据线的数据得以输出到屏幕,如果DE线不使能RGB数据将无法随着喷枪到达像素点导致喷枪填进去的数据为0,屏幕一直为黑屏。
软件驱动设计: 电路供电部分:lcd芯片的电压要供电(可能是驱动某一个gpio管脚输出电压给某一个电压转换芯片,然后电压转换芯片的输出电压接到lcd芯片的VDD端)
lcd屏幕的电压要供电(可能是驱动某一个gpio管脚输出电压给某一个电压转换芯片,然后电压转换芯片的输出电压接到lcd芯片的背光屏正电压,如LED+,LED-)
lcd芯片的负电压DFF,可能是接到主控芯片的某一个gpio管脚,让这个管脚输出低电压就可以了;
协议部分:就是填写主控芯片的LCD接口的寄存器,设置时钟(clk线),设置vsync线的时序,设置hsync线的时序,使能DE,往24根数据线写像素值。
3.类似内存的接口,就是接到内存控制器的那类设备;
sdram,ddr,nand,nor,dm9000:这些设备共用数据线,地址线,靠片选线来区分这些设备;
接到内存控制器上的内存类设备每一个设备都有一根片选线,这根片选线要接到内存控制器对应bank的片选接口,这样当cpu发出对应bank的地址时内存控制器就会
自动将设备的片选管脚选中,不需要程序手工选中.例如sdram接到内存控制器的bank6(0x30000000~0x380000000),那sdram的片选管脚也要连到主控芯片的内存控制器的GCS6
不同位宽的接线,访问过程
怎么确定访问地址,设置内存控制器
cs#:井号也是表示低电平有效的意思;
4.从头到尾看几个开发板的原理图
1.如果原理图里看到nWAIT接口表示这个设备要使用nwait信号,在memory control的每一个bank都会有一个nwait接口,如果设备的nwait线接到了对应的
bank,那么在初始化memory control时就要enable对应的bank的nwait信号;
2.一款芯片的原理图一般由两部分组成:核心板,底板;核心板是指SOC(cpu+ddr+net+uart+nand,也包括soc里的片内外设)等cpu相关的,底板是指核心板的下一层(承载核心板的底板),主要是接纯外设比如spi设备,i2c设备等等;
3.usb分为host接口,slave接口
5.总结
写设备驱动的思路:先看原理图,弄清楚设备芯片的原理图的各个管脚是什么含义有什么作用分别接到哪里(要结合设备芯片的数据手册与原理图一起看才能弄懂);
然后弄明白各个管脚是怎么一起配合实现硬件协议的。(硬件协议可以通过外设芯片手册的时序后者简介看明白),反正就是要弄明白各个管脚是
怎样配合访问设备芯片的。最后根据外心芯片的时序要求等设置要求通过主控芯片的对应接口配置外设芯片,使其正常工作。