新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > 2440裸机学习心得(下)

2440裸机学习心得(下)

作者: 时间:2016-11-29 来源:网络 收藏
摄像头驱动
一些概念:
摄像接口的主时钟信号由USB PLL产生,它的频率为96MHz,再经过分频处理后输出给摄像头,摄像头再根据该时钟信号产生三个同步时钟信号(像素时钟、帧同步时钟和行同步时钟),反过来再输入回s3c2440。
OV9650内部有大量的寄存器需要配置,这就需要另外的数据接口。
OV9650的数据接口称为SCCB(串行摄像控制总线),它由两条数据线组成:一个是用于传输时钟信号的SIO_C,另一个是用于传输数据信号的SIO_D。SCCB的传输协议与IIC的极其相似,只不过IIC在每传输完一个字节后,接收数据的一方要发送一位的确认数据,而SCCB一次要传输9位数据,前8位为有用数据,而第9位数据在写周期中是Don’t-Care位(即不必关心位),在读周期中是NA位。SCCB定义数据传输的基本单元为相(phase),即一个相传输一个字节数据。
SCCB只包括三种传输周期,即3相写传输周期(三个相依次为设备从地址,内存地址,所写数据),2相写传输周期(两个相依次为设备从地址,内存地址)和2相读传输周期(两个相依次为设备从地址,所读数据)。当需要写操作时,应用3相写传输周期,当需要读操作时,依次应用2相写传输周期和2相读传输周期。(这些读写和IIC一样~)
OV9650有两个只读寄存器——0x1C和0x1D,用于存放厂家ID,数据分别为0x7F和0xA2,我们可以通过读取它们来判断s3c2440是否连接了OV9650。当确认连接了OV9650后,我们就可以把VGA(640×480)模式下YUV彩色空间的配置数组写入OV9650内(二维数组:第一个表示寄存器地址,第二个表示要写入的数据)
注意比较三个变量的含义:
Width = 640 //源宽度
PrDstWidth =480 //目标宽度
SrcWidth =640-WinHorOffset*2; //偏移后宽度
驱动函数编写步骤:
外围基础准备硬件初始化
IIC初始化,LCD初始化,UPLL时钟初始化(96M,0V9650系统时钟),
GPIO初始化(GPJ),硬件和软件复位摄像头(GPJ12为CAMERARESET,rCIGCTRL)
0V9650寄存器配置
A、读取OV9650厂商ID,验证是否工作
B、复位所有OV9650寄存器
C、配置OV9650寄存器(用规定的二维数组直接配)
摄像头接口初始化
摄像头接口的一些寄存器初始化:rCIGCTRL,rCIWDOFSTrCISRCFMT
rCIPRTRGFMT,rCIPRTAREA
B、设置内存首地址为LCD缓存数组首地址:rCIPRCLRSA1~4
C、计算水平和垂直缩放比率和位移量,以及主水平、垂直比率
放入以下三个寄存器中rCIPRSCPRERATIO,rCIPRSCPREDSTrCIPRSCCTRL
中断函数开启和指向
控制台菜单的编写与实现
显示视频
rCIPRSCCTRL|=(1<<15); //预览缩放开启
rCIIMGCPT =(1<<31)|(1<<29); //预览缩放捕捉使能
截图,定格
rCIPRSCCTRL &=~(1<<15); //预览缩放关闭
rCIIMGCPT &=~((1<<31)|(1<<29)); //预览缩放捕捉不使能
视频定格后,LCD_BUFFER数组就是图像数据
放大,缩小
调节偏移量HOffset,VOffset,每次改变后重新初始化摄像头接口
四个额外写出需注意的函数:
1、计算主突发长度和剩余突发长度CalculateBurstSize
2、/计算预缩放比率及移位量CalculatePrescalerRatioShift
3、中断函数(只清中断,不干别的) camera_interrupt
4、SCCB总线函数的读写(像IIC)Rd_SCCB,Wr_SCCB
网卡驱动
DM9000的一些基本概念:
DM9000对外来说只有两个端口——地址口和数据口,地址口用于输入内部寄存器的地址,而数据口则完成对某一寄存器的读写。DM9000的CMD引脚用来区分这两个端口,当CMD引脚为0时,DM9000的数据线上传输的是寄存器地址,当CMD引脚为1时,传输的是读写数据。
我们把DM9000的A8和A9接为高电平,把A4~A7接为低电平,并且把DM9000的AEN接到s3c2440的nGCS4引脚上,则DM9000的端口基址为0x20000300,如果再把DM9000的CMD引脚接到s3c2440的ADDR2引脚上0x20000304(怎么计算?)
查了一下书,是和存储控制器有关系,每个nGCSx对应128M地址空间,8个nGCSx对应1G地址。
nGCS4刚好对应0x20000000开始的地址,但为什么是0x20000300?
再加上IObase:300
如果将DM9000的CMD引脚接到s3c2440的ADDR2,由于CMD引脚的高低电平决定地址口和数据口,那么,ADDR2为0时,访问的
就是地址口,所以地址口的起始地址为ARRD2为0的情况,即0x20000000;ADDR2为1时,(LADDR3~LADDR0 = 0100)访问的就是数
据口,所以数据口的地址即0x20000004。
如果要写入DM9000中的某个寄存器,则先把该寄存器的地址赋予DM_ADDR_PORT,然后再把要写入的数据赋予DM_DATA_PORT即可。读取DM9000中的某个寄存器也类似。
DM9000寄存器介绍在数据手册11页开始:
DM9000内部有0x3FF大小的SRAM用于接受和发送数据缓存。在发送或接收数据包之前,数据是暂存在这个SRAM中的。当需要连续发送或接收数据时,我们需要分别把DM9000寄存器MWCMD或MRCMD赋予数据端口,这样就指定了SRAM中的某个地址,并且在传输完一个数据后,指针会指向SRAM中的下一个地址,从而完成了连续访问数据的目的。
基于ARP协议的DM9000编写步骤:
初始化EINT7中断,设置中断函数入口
因为DM9000的数据中断引脚INT是连接到s3c2440的外部中断7引脚上的
编写好读和写DM9000寄存器函数,用其配置DM9000的寄存器
并使其用中断方式接收网卡数据,查询方式发送数据
(这步挺难的,很多寄存器要配置,对照着Datasheet和别人的程序)
注:DM9000内的寄存器的地址宏定义时,不用管基址,直接按OFFSET定义
编写好DM9000发送和接受函数(位宽为16)
分别把DM9000寄存器MWCMD或MRCMD赋予数据端口
接受数据时要注意,按照规定的格式来编写
定义一个符合ARP协议格式的数组,用于数据传输
将该数组作为发送函数形参发给PC机请求包
编写中断函数,清屏蔽
将接收函数中的数组内容,用串口打印出控制台
SD卡驱动
SD(全名为Secure Digital Memory Card,安全数码卡)
s3c2440集成了SD控制器,可以方便地读写SD、MMC和对SDIO进行操作。
可以用SDIO控制器来编,也可用SPI总线来编
SDIO的应用是未来嵌入式系统最重要的接口技术之一,会取代目前GPIO式的SPI接口
具体的CMD命令和协议内容自己看回资料了。
我使用的SD卡为手机的内存卡(不是MMC),型号为SDHC_V20_CARD,支持PLV2.0协议
主要讲编写简单的SD读写步骤:
准备工作,编写要使用到一堆东西:
检查SDIO命令发送,接收是否结束函数Chk_CMD_End(int cmd, int be_resp)
使用到的CMD和ACMD函数(这部分要配置寄存器,要查值,比较难,参考别人的吧)
编写一个要用的结构体SD_STRUCT,用于记录cCardType和iCardRCA等
SD卡识别模式:
初始化:时钟400K,Type B, clk enable,SD卡模式,FIFO reset
CMD 0——》reset指令
CMD 8——》工作电压范围,初始化SDHC卡,看是否支持PLV2.0,返回类型
CMD 55——》RCA为0x0,使用ACMD41前必须使用
ACMD 41——》识别卡能否在给定的VDD下工作
CMD 2——》查卡的CID信息
CMD 3——》要求系统给SD卡发送一个新相对地址RCA
改时钟频率:25M,准备进入transfer状态
CMD 7——》进入transfer状态
ACMD 6——》设置总线宽度为4bit
数据传输模式:
若需要擦除:
{
CMD 32——》start address
CMD 33——》end address
CMD 38——》erase
}注意:擦除后必须要进行复位,即重新初始化前面步骤,不然不能进行读写
单块写或多块写
CMD 7——》transfer模式
单块读或多块读
拓展:
将摄像头捕捉的图像,写进SD卡中,然后再还原显示出来
注意一个点:
就是要将LCD_BUFFER[480][272]的二维数组转化为LCD_BUFFER_SD[480*272]一维
一个疑问?好像只需51200就可将整幅图像都显示出来,而不需要480*272那么多
附加部分(有空研究):
文件系统的构建:

上一页 1 2 3 下一页

关键词: 2440v裸机学

评论


技术专区

关闭