毕业设计(论文)-基于STM32的照相机系统的实现.docx_第1页
毕业设计(论文)-基于STM32的照相机系统的实现.docx_第2页
毕业设计(论文)-基于STM32的照相机系统的实现.docx_第3页
毕业设计(论文)-基于STM32的照相机系统的实现.docx_第4页
毕业设计(论文)-基于STM32的照相机系统的实现.docx_第5页
已阅读5页,还剩34页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

目 录第1章 绪论11.1 研究背景与意义21.2 研究内容4第2章 系统方案设计42.1 整体框架设计42.2 主控模块52.3 液晶显示模块122.4 存储器模块162.5 图像采集模块21第3章 系统软件设计293.1 顶层程序设计293.2 系统初始化程序设计293.3 拍照处理程序设计32第4章 系统功能测试分析34总结36参考文献37第1章 绪论一幅图像可以描述为“一个平面上与位置成函数关系的光强或反射率的变化”。相机是一台捕捉并记录图像的设备,其中“捕捉”是指将一幅图像中包含的信息转换成相应的以可以重现的方式存储的信号1。在传统卤化银的相机中,图像信息被转换成胶片中的化学信号,并存储在胶片中对应的点上。而现代的电子相机是通过图像传感器将捕捉到的图像信号转换成了电子信号,并将图像信息存储在内存中。电子相机又根据存储的方式不同,分为模拟相机和数码相机。图1.1数字系统图像捕捉原理物镜:聚焦图像,折射来自物体的光线,使光线汇聚成为一幅清晰的图像;光圈:决定进入镜头的光量,通过光圈数值计量。光圈数值越大则光圈开口越小;快门:快门速度决定曝光时间长短,通常以一秒的十分之一计量。快门速度越快则曝光时间越短;ccd:光耦合组件。1.1 研究背景与意义自1991 年第一款商用数码相机面市以来, 数码相机的性能有了极大的提高2。作为数码相机的核心部件感光元件ccd 像素数已从初期的10 几万发展到目前的2 千万以上, 另一种感光元件cmos在图像质量方面已经基本上与ccd 不相上下, 因而在专业级数码相机方面得到广泛应用。变焦倍率已从2 3 倍增加到10 倍以上2。至于存储器, 不仅品种多, 且存储量已达8gb,数码相机的功能也从单拍照发展到十机一体的多媒体拍照手机3。1.1.1 电子相机的早期发展电子照相的设想由来已久,最早于1973年出现在著名的半导体制造商德州仪器公司(texas instruments incorporated)提出的一项专利申请。在实施方案中,半导体图像传感器位于可伸缩镜头后方,其捕捉的图像信号被传输到电磁记录头,并存储到一个可移动的环形磁鼓中。然而由于1973年传感器技术与磁记录技术还在起步阶段,该想法并没有付诸在真正的产品之中。直到1981年,这一年对于相机制造商而言是极其重要的一年,索尼公司发布了一款电子相机的原型,被称为“mavica”。这种原型相机将半导体图像传感器捕获到的图像信号记录在磁性软盘上,包含有单镜头反光式取景器、ccd图像传感器、信号处理电路和软盘驱动器。但是记录到软盘上的图像信号是一种改良的视频信号,属于模拟信号,故它并非是一款完整意义上的数码相机。在索尼mavica发布后,数家相机制造商和电子设备制造商组成了联盟来推进索尼的构想。他们建立了一套电子照相系统的标准,名为“静态视频系统”。但由于此系统基于ntsc的视频格式,图像的画质不是太好,镜头相机的使用只被局限在无须纸质打印的小应用之中。图1.2 索尼mavica(原型)1.1.2 数码相机的出现随着数字技术的进步,模拟电子相机向数字化过渡,在1988年的世界影像贸易博览会上,第一台数码相机(富士ds-1p)发布。该相机将数字图像信号记录在一块容量为2mb的静态ram卡上。虽然这款富士原型机没有上市销售,但随着对其概念的不断改进和完善,有几款数码相机陆续上市。1995年,卡西欧qv-10上市销售,由于其不仅是一台相机,更是一个便携式图像浏览器,即在用户拍完照后能即刻共享和欣赏图片,受到年轻一代的热烈欢迎。1.1.3 像素数量之战随着市场的日益增长,数码相机的前景变得愈发明朗,许多厂家开始了数码相机的开发。半导体制造商也认识到其中蕴含的重大商机,开始研发专用于数码相机上的图像传感器。1996年奥林巴斯发布了c-800l型数码相机,其ccd图像传感器约含80万像素。随后,富士和奥林巴斯与次年分别发布130万像素的ds300和140万像素的c-1400l。1999年,多家厂商发布了200万像素的机型,而在2000年发布300万像素的机型时情形再次发生。直到2004年,出现了高达800万像素的傻瓜相机和1670万像素的单反相机。 图1.3 卡西欧ov-10 图1.4 单反照相机1.1.4 本课题研究的意义市场上的照相机大多都是像素很高,体验也非常不错的照相机,但这些数码照相机太过于独立,而且价格也不低。在有些场合,需要把照相功能嵌入到某个系统中,完成一些简单的摄像和保存图片的功能,本次课设实现的stm32照相机的系统正好满足要求。stm32照相机的程序还可以以板级支持包的方式根据需求对功能进行裁剪,功耗低,成本也很低。1.2 研究内容本文主要研究stm32照相机的程序设计流程,从硬件的参考手册入手。根据芯片手册或模块资料,配置相关寄存器,并对信号的时序做出分析,搭建出每个器件操作的完整的编程模型。再选择出合适的算法,使各个模块之间协调工作,最终设计出较低成本、可移植性较好的stm32照相机系统。第2章 系统方案设计2.1 整体框架设计整个照相系统根据功能划分,可分为:主控模块、液晶显示模块、存储器模块、图像采集模块。另外,在实际拍照中,还需要加入按键作为拍照的按钮、led灯作为操作指示灯。在器件选型上,在综合了相机像素、存储容量、成本,以及功耗各方面的考虑后,决定选用stm32最小系统作为主控模块,ov7725摄像头作为图像采集模块,ili9341作为液晶驱动,容量为128mb的sd卡作为存储模块,见图2.1。图2.1 stm32照相机系统框图2.2 主控模块2.2.1 stm32f103zet6芯片功能介绍(1)内核:arm 32位的crotex-m3的cpu,最高72mhz工作频率;可进行单周期的乘法和硬件除法。(2)存储器:256kb/512kb的flash;高达64kb的sram;带4个片选控制的静态存储器控制器:sram、psram、nor和nand;并行lcd接口,兼容8080/6800模式。(3)时钟、复位与电源管理:2.03.6v供电和i/o引脚;上电、断电复位(por/pdr),可编程电压监测器(pvd);416mhz晶体振荡器;内嵌经出厂调校的8mhz的rc振荡器;带校准功能的32khz rtc振荡器。(4)低功耗:睡眠、停机和待机模式;vbat为rtc和后备寄存器供电。(5)3个12位模数转换器,1s转换时间(多达21个输入通道)。(6)dma:12通道dma控制器,支持的外设:定时器,adc,spi,i2c和usart。(7)多达112个快速i/o端口:51 /80/112个i/o口,所有i/o可以映像到16个外部中断。(8)调试模式:串行单线调试(swd)和jtag接口;cortex-m3内嵌跟踪模块(etm)。(9)多达11个定时器:4个16位定时器,每个定时器有多达4个用于输入捕获/输出比较/pwm/脉冲计数的通道和增量编码输入;2个16位带死区控制和紧急刹车,用于电机控制和pwm高级控制定时器;2个看门狗定时器;系统时间定时器;2个16位基本定时器用于驱动dac。(10)多达13个通信接口:多达2个i2c接口(支持smbus/psmbus);多达5个usart(支持iso7816接口,lin,irda接口和调制解调器接口);多达3个spi接口(18m bit/s);can接口;usb2.0全速接口;sdio接口。(11) crc计算单元,96位的芯片唯一代码。(12) ecopack封装。2.2.2 时钟树为了满足系统时钟和不同外设时钟的需求,stm32芯片内部对系统时钟和多种总线时钟进行了管理,形成了时钟树。为了低功耗的需要,系统时钟、中断、gpio以及外设时钟都设置了开关。所以,要求在系统启动前设置内部或外部时钟晶振频率和分/倍频数,在使用gpio管脚时要打开gpio挂接在总线上的时钟开关,在使能中断和使用外设时都要打开对应的时钟开关。下面介绍stm32的时钟源和时钟系统框图:在stm32的内部共有五个时钟源,分别为hsi、hse、lsi、lse、pll4。(1)hsi(高速内部时钟)为rc振荡器,其频率为8mhz。(2)hse(高速外部时钟)可接石英或陶瓷谐振器,还可以接外部时钟源,频率范围为4mhz16mhz。(3)lsi(低速内部时钟)为rc振荡器,其频率为40khz。(4)lse(低速外部时钟),可接频率为32.768khz的石英晶振。(5)pll(锁相环),其时钟输入源可选择为高速内部时钟的二分频、高速外部时钟或其二分频。倍频可选择为216倍,但是其输出频率最大不得超过72mhz。图2.2 stm32时钟树2.2.3 gpio及功能复用在使用stm32上的gpio时,都要对其寄存器进行配置。包含2个32bit数据寄存器(gpiox_idr和gpiox_odr),1个32bit置位/复位寄存器(gpiox_bsrr),2个32bit配置寄存器(gpiox_crl和gpiox_crh),以及1个16bit复位寄存器(gpiox_brr)和1个32bit锁定寄存器(gpiox_lckr)。为方便用户使用,gpio的寄存器在gpiox结构体中实现:typedef struct _io uint32_t crl; _io uint32_t crh; _io uint32_t idr; _io uint32_t odr; _io uint32_t bsrr; _io uint32_t brr; _io uint32_t lckr; gpio_typedef; 另外,gpio端口上的每一位可以由软件分别配置成多种模式(在gpio_initstruct体中实现),即每一位都可以自由编程。typedef struct uint16_t gpio_pin; gpiospeed_typedef gpio_speed; gpiomode_typedef gpio_mode; gpio_inittypedef;但要注意的是,i/0端口寄存器必须按4个字节(即32bit)被访问,不支持只访问某一位或某几个字节。若要只进行位操作,可以将寄存器的值与某一32位数值进行按位与/或/同或/异或等操作实现。(1)gpio基本设置图2.3 gpio内部结构框图gpio类型gpio_mode共8种:gpio_mode_ain模拟输入:应用adc模拟输入,或者低功耗下省电;gpio_mode_in_floating浮空输入:可以做按键识别,串口接受端rx;gpio_mode_ipd下拉输入:内部下拉电阻输入;gpio_mode_ipu上拉输入:内部上拉电阻输入;gpio_mode_out_od开漏输出:当输出为0时,io内部硬件接地,当输出为1时,引脚是悬空的,需要外接上拉电阻,才能实现输出高电平。要想实现双向通信,外接上拉电阻后,可先向io口写入1,此时的io的电平会随着外部电路的电压值变化,从而完成输入功能;gpio_mode_out_pp推挽输出:输出0时,内部接低,输出1时,接的是电源电压vcc,但读输入的值是未知的;gpio_mode_af_od复用开漏输出:主要针对一些片内外设功能(如:串口tx1,spi通信);gpio_mode_af_pp复用推挽输出:片内外设功能(如:i2c的scl,sda)。对于输出引脚除设置引脚的输出模式外,还需设置gpio引脚速率gpio_speedgpio引脚速率是指i/o口驱动电路的响应速度(不是信号的输出速率),对于stm32上的输出引脚需要选择速度:2mhz、10mhz和50mhz。根据不同的外设,合理地选择不同的输出驱动模块,以达到最佳的性噪比和最低的系统功耗。比如,对于高频的驱动电路,噪声较高,所以不需要高的输出频率时,选用低频驱动电路,这样非常有利于提高系统的抗电磁干扰性能。(2)gpio功能复用复用功能是指内置外设与i/o口共用了引出管脚,也可能出现不同的功能对应同一管脚。若将gpio配置成复用输出功能,则i/o将不能使用输出寄存器,并在内部结构中与片上外设的输出信号连接。如果通过编程将某个gpio引脚配置成复用输出功能,但是外设没有启动,其输出将不确定。使用默认复用功能前必须对端口位配置寄存器编程。对于复用的输入功能,端口必须配置成输入模式(浮空、上拉或下拉)且输入引脚必须由外部驱动;对于复用输出功能,端口必须配置成复用功能输出模式(推挽或开漏);对于双向复用功能,端口位必须配置复用功能输出模式(推挽或开漏),此时的输入驱动器被配置成浮空输入模式。2.2.4 中断(1)中断基本概念中断是指当软件或硬件出现需要时,cpu暂时停止当前程序的执行,转去处理应对突发情况的程序的执行请求,在处理事件后完后又返回到源程序继续执行的过程。触发中断的事件称为中断源,而中断源向内核申请中断的入口就称为中断通道。也就是说,中断通道给中断源提供一个向内核申请中断的入口,中断源通过中断通道向内核提出中断申请。一个中断通道可以对应一个中断源,也可以对应多个;有的外设只对应一个,而有的外设可以对应多个中断通道。中断优先级是针对中断通道的。图2.4 中断通道、中断源与外设的关系(2)中断优先级stm32的中断优先级可分为响应式优先级或抢占式优先级。其中,抢占式优先级的中断会打断当前的主程序或者中断程序运行,是实现中断嵌套的一种手段。对于每一个中断通道,cortex-m3内核的头文件“core_m3.h”中都提供了一个8位的寄存器ip,来确定该中断通道的抢占式优先级或响应式优先级。(3)中断相关寄存器 nvic结构体(core_m3.h)内核中的寄存器与中断控制 scb结构体(core_m3.h)相关寄存器 外设相关寄存器外设中的寄存器(如:tim2的tim2_dier中断使能寄存器)在配置中断时主要使用中断控制(nvic)寄存器组中的寄存器,可以通过nvic的结构体来实现:typedef struct vu32 iser2; u32 reserved030; vu32 icer2; u32 rserved130; vu32 ispr2; u32 reserved230; vu32 icpr2; u32 reserved330; vu32 iabr2; u32 reserved462; vu32 ipr11; nvic_typedef;配置这些内核寄存器时(以按键中断为例)stm32的库函数中提供了中断初始化结构体:typedefstructuint8_tnvic_irqchanneluint8_tnvic_irqchannelpreemptionpriority;uint8_tnvic_irqchannelsubpriority;functionalstatenvic_irqchannelcmd; nvic_inittypedef;在按键中断初始化时,需进行如下操作:第一步:设置抢占优先级的分组;第二步:选择外部中断输入引脚,设置抢占优先级和响应优先级;第三步:使能中断通道,中断设置成功。(4)总中断的开和关stm32/cortex-m3是通过改变cpu当前优先级来实现允许/禁止中断的。在stm32固件库中(stm32f10x_nvic.h和stm32f10x_nvic.c)定义了四个函数操作primask位和faultmask位,改变cpu当前优先级,从而达到控制所有中断的目的。/*关闭总中断的两个函数*/voidnvic_setprimask(void);voidnvic_setfaultmask(void); /*使能总中断的两个函数*/voidnvic_resetprimask(void);voidnvic_resetfaultmask(void);2.3 液晶显示模块2.3.1 ili9341驱动器介绍ili9341是一个用于tft液晶显示的单芯片控制驱动器,具有26万色的240rgb x320像素显示解决方案,它的组成包括一个720通道的源极驱动器,一个320通道的栅极驱动器,172800字节用于图形显示的gram,以及供电电路5。ili9341支持8/9/16/18位数据总线的mcu接口,6/16/18位数据总线的rgb接口,以及3/4线的spi接口,移动图像区域可以通过窗口地址功能在内部gram来指定,指定的窗口区域可以选择性地更新,因此,可以在图像区域同时独立地显示移动图像6。ili9341可以使用1.653.3v的i/o接口电压和一个对应的电压跟随电路来产生驱动lcd的电压。ili9341有精确的电压控制(软件控制),来支持全色,8色显示模式和睡眠模式,是理想的中小型手提产品的lcd驱动器。2.3.2 fsmc总线fsmc(flexible static memory controller,可变静态存储控制器)是stm32系列中内部集成256 kb以上flash,后缀为xc、xd和xe的高存储密度微控制器特有的存储控制机制7。之所以称为“可变”,是由于通过对特殊功能寄存器的设置,fsmc能够根据不同的外部存储器类型,发出相应的数据/地址/控制信号类型以匹配信号的速度,从而使得stm32系列微控制器不仅能够应用各种不同类型、不同速度的外部静态存储器,而且能够在不增加外部器件的情况下同时扩展多种不同类型的静态存储器,满足系统设计对存储容量、产品体积以及成本的综合要求8。(1)fsmc框图及配置:图2.5 fsmc框图fsmc总线配置流程:第一步:选择合适的存储块映射nor flash存储器,共有4个独立的存储块可以用于与nor flash、sram和psram存储器接口,每个存储块都有一个专用的片选管脚。第二步:使用或禁用地址/数据总线的复用功能;第三步:选择所用的存储器类型:nor flash、sram或psram(其中nor flash memory和sram都支持同步或异步读写时序的存储器);第四步:定义外部的存储器的数据总线:8bit/16bit;第五步:使用或关闭nor flash memory的突发访问模式;第六步:配置等待信号的使用:开启或关闭,极性设置,时序配置;第七步:使用或关闭扩展模式:扩展模式用于访问具有不同读写操作时序的存储器。(2)时序参数及计算异步读写时序的参数及时序:addset: address setup time;addhold: address hold time;datast: data setup time图2.6 异步读时序图2.7 异步写时序读/写访问时间为:(addset+1)+(datast+1)hclk;写使能信号由低到高的时间为:twp= datasthclk;考虑最大的读/写访问时间,fsmc和存储器的内部延时,数据建立时间应满足:datast=(tavqv+tsu(data_ne)+tv(a_ne)/hclkaddset4。本次毕设lcd驱动的存储器接口是挂接在fsmc总线上(fsmc总线上的lcd连接见图2.8),选用nor flash存储器的bank1的第4块区域,并且禁用地址/数据总线的复用功能和存储器的突发访问模式,设置数据总线宽度为16位,读写时序为异步时序,并关闭扩展模式。其实只需对下面的三个寄存器做如下操作:fsmc_bank1-btcr6=0x5011;fsmc_bank1-btcr7=0x0809;fsmc_bank1e-bwtr6=0x0301。图2.8 lcd与fsmc总线连接2.3.3 lcd初始化表2.1 lcd寄存器操作部分指令集指令描述指令描述指令描述edh电源序列控制f7h泵比控制c5hvcom控制1e8h驱动时序控制ab1h帧速率控制c7hvcom控制2eah驱动时序控制bb6h显示功能控制f2h使能3gcbh功耗控制ac0h功耗控制126h伽马设置cfh功耗控制bc1h功耗控制2e0h正极伽马校准2ah列地址设置3ah像素格式设置e1h负极伽马校准2bh页地址设置11h退出睡眠模式2ch存储器写36h存储器访问控制29h开显示2eh读存储器fsmc总线(stm32引脚复用fsmc的硬件接口)配置完成后,就能通过stm32来对lcd内的寄存器进行读写操作了。本章节中所有关于时钟的设置,gpio的配置,引脚的复用功能,中断函数将在下一个章节集中讲解,lcd内部的寄存器比较多,可以对照lcd ili9341的数据手册通过命令来指定配置寄存器,并输入相应的参数。lcd ili9341的操作指令可分为:一级、二级、三级指令。lcd初始化和显示图片时需要用到的指令如表2.1。关于lcd的初始化代码,不同的液晶驱动程序是不一样的,在购买液晶屏时厂家会提供源代码,所以这里不再展开。2.4 存储器模块2.4.1 sd卡2.0协议sd存储卡兼容mmc卡的接口规范,采用9针的接口(clk为时钟线,cmd为命令响应线,data0data3为双向数据传输线,vdd、vss1和vss2为电源和地),最大的工作频率是25mhz。sd卡系统支持sd卡模式和spi模式(如表2.2和表2.3),两种通信协议9。sd卡在结构上使用一主多从星型拓扑结构。虽然spi的初始化流程比sdio简单得多,但sdio用4根数据线传输,而spi只是串行传输,sdio的传输速度明显高于spi。在传输图像时对传输速度要求较高,故本次毕设选用sd模式的接口(sdio)。表2.2 sd卡模式下的接口定义管脚类型描述备注data0data2输入/输出/推挽类型数据总线cm输入/输出/推挽类型卡监测数据位data3clk输入时钟引脚cmd推挽命令/响应 串行(1)sdio初始化sd_error sd_init(void);初始化函数包括gpio设置,寄存器的复位,上电操作,sd卡的信息获取。若初始化成功返回值为0。表2.3 spi模式下的接口定义管脚类型描述备注cs输入片选低电平有效di输入数据输入端串行do输出数据输出端串行clk输入时钟引脚在进行初始化之前先了解几个命令和sd卡内部寄存器(见图2.9和表2.4):图2.9 sd卡内部结构及寄存器cmd0:将所有的卡复位到理想状态;cmd8:发送主机的提供的电压范围,并响应sd卡支持的电压范围;cmd55:指定下一条命令是应用命名;acmd41:发送主机支持的卡的容量,并响应sd卡的ocr中的内容;cmd2:获取sd卡的id; cmd3:获取sd卡的相对地址。sdio模式下的初始化流程:当host上电后,使所有的卡设备处于卡识别模式,完成设置有效操作电压范围,卡识别和请求卡相对地址等操作。第一步:发送指令cmd0使卡设备处于空闲状态,进入第二步。第二步:发送指令cmd8,若卡设备有响应,说明此卡为sd2.0以上,此时会响应sd卡支持的电压范围,进入第三步;若没有响应,则为sd2.0以下的sd卡,执行第四步。第三步:若主机支持大容量的sd卡,将hcs置1,否则置0。发送指令cmd55+acmd41,若响应ccs为1,则sd卡为大容量的存储器,进入第四步;否则为标准容量的sd卡,进入第五步。第四步:hcs置0,并发送cmd55+acmd41,若有响应,则为标准容量的sd卡,进入第五步;若无响应,则返回没有找到可用的sd卡。第五步:发送指令cmd2获取cid。第六步:发送指令cmd3获取rca(relative card address),初始化完成。表2.4 sd卡内部寄存器寄存器位宽(bit)描述cid128卡标识号rca16相对卡地址:本地系统中卡的地址,是动态变化的,需要在主机初始化时确定;在spi模式中没有csd128卡描述数据:卡操作条件的信息数据scr64sd卡配置寄存器:sd卡特定信息数据ocr32操作条件寄存器dsr16驱动级寄存器,用于提高总线的性能;可选可不选(2)sd卡的基本操作sd卡的读操作:sd_error sd_readblock(uint8_t *readbuff, uint32_t readaddr, uint16_t blocksize);函数功能:读单个块的数据,并采用dma传输方式;readbuff:指向数据接受缓存器;readaddr:读取区域的首地址;blocksize:块的大小(512b);读取成功后返回sd_error = 0。(下同)sd_error sd_readmultiblocks(uint8_t *readbuff, uint32_t readaddr, uint16_t blocksize, uint32_t numberofblocks);函数功能:可以读取连续几个块的内容,块的个数由numberofblocks确定。读写都是以block为单位,一个block为512个字节(发送cmd16命令可以设置块的大小),小于512b时,以block的边界对齐。每个块传输的后面都跟着一个crc校验。cmd17(read_single_block)用于传输单个块,传输完之后,卡进入传输状态;cmd18(read_multiple_block)用于多个块的传输,直到收到一个cmd12命令。sd卡的写操作:sd_error sd_writeblock(uint8_t * writebuff, uint32_t writeaddr, uint16_t blocksize);函数功能:写入一个块的内容,dma传输;写入成功后返回sd_error = 0。(下同)sd_error sd_writemultiblocks(uint8_t *writebuff, uint32_t writeaddr, uint16_t blocksize, uint32_t numberofblocks);函数功能:连续写入几个块的内容,块的个数由numbersize确定。块写操作与块读操作类似,每个块传输的后面都跟着一个crc校验。卡写数据时会进行crc校验,多块写比重复的单块写更能提高效率。如果csd中的write_blk_misalign没设置,并且发送的数据不是块对齐的,卡会设置状态寄存器中的address_error位,并且进入receive-data状态等待停止命令。此时写操作也会停止,并且卡会设置其的wp_violation位。如果写缓冲满的话,卡会停止接受write_block命令。此时主机应发送send_status(cmd13)命令,卡返回数据的ready_for_data位标志卡是否准备好接受新的数据。在多块写操作中通过事先发送acmd23命令可提高写速度。acmd23用于定义接下来要写数据的块的数目10。每次多块写操作后,这个值又被设为默认值1,acmd22会使卡返回写成功的块数目。sd卡的擦除操作:sd_error sd_erase(uint32_t startaddr, uint32_t endaddr);函数功能:擦除sd卡中指定的内容,擦除成功时返回0;startaddr是擦除内容的起始地址;endaddr是擦除内容的终止地址。擦除命令的顺序是:erase_wr_blk_start(cmd32)、erase_wr_blk_end(cmd33)、erase(cmd38)10。如果(cmd38或(cmd32,33)接收到出错信息,卡会设置状态寄存器中的erase_seq_error位并且重新等待新的命令时序;如果接收到时序错误命令,卡会设置其erase_reset位并且重新等待新的命令时序。2.4.2 sd卡的文件系统fatfs上一节的sd 卡驱动只完成了向物理地址写入数据的工作,而根据文件系统格式的逻辑转换部分则需要额外的代码来完成。实质上,这个逻辑转换部分可以理解为当需要写入一段数据时,由它来求解向什么物理地址写入数据、以什么格式写入及写入一些原始数据以外的信息(如目录)。这个逻辑转换部分代码也称之为文件系统。fatfs 是面向小型嵌入式系统的一种通用的fat 文件系统。它完全是由aisi c 语言编写并且完全独立于底层的i/o 介质,因此它可以很容易地不加修改地移植到其他的处理器当中,如8051、pic、avr、sh、z80、h8、arm 等。fatfs 支持fat12、fat16、fat32 等格式11。所以利用前面写好的sdio 驱动,把fatfs 文件系统代码移植到工程之中,就可以利用文件系统的各种函数,对已格式化的sd 卡的文件进行读写了。(1)fatfs r0.09本次毕设采用fatfs文件系统的r0.09的版本,提供有两类接口函数:底层函数(device control interface)和上层函数(application interface)。图2.10 fatfs文件系统模型 file access: f_open(),f_close(),f_read(),f_write(),f_gets(),f_puts(),f_printf()directory access: f_opendir(),f_closedir(),f_readdir()api file/directory management: f_stat(),f_unlink(),f_rename(),f_mkdir(),f_getcwd()volume management: f_mount(),f_mkfs(),f_fdisk()dci:disk_status()获取扇区状态;disk_initialize()初始化扇区;disk_read()读扇区;disk_write()写入扇区;disk_ioctl()控制设备相关函数;get_fattime()获取当前时间。上一节讲到的sd卡的初始化,sd卡的读写操作,以及擦除等操作的实现全部封装到dci函数中使用,即使用fatfs提供的api和dci就能实现对sd卡的读写及管理文件系统的所有操作。(2)常用的api函数fresult f_mount ( byte vol ,fatfs *fs );函数功能:注册逻辑存储设备(打开一个工作区),成功后返回fr_ok;vol为盘符号;fs指向新建的文件系统。fresult f_open (fil*fp, const tchar* path, byte mode);函数功能:新建或打开一个文件,成功后返回fr_ok;fp指向创建的文件;path指向文件路径名;mode文件访问方式。fresult f_close (fil*fp);函数功能:关闭fp指向的文件。fresult f_read (fil *fp, void *buff,uint btr,uint *br);函数功能:读取文件,成功后返回fr_ok;fp指向要读取的文件;buff指向指向读取到的数据;btr读取的字节数;br指向读取的字节数。fresult f_write (fil *fp, const void *buff,uint btw,uint *bw);函数功能:写入文件,成功后返回fr_ok;fp指向要写入的文件;buff指向待写入的数据;btw指向写入的字节数。fatfs文件系统除了提供上述的库函数,还提供其他一些头文件,可根据需要进行手动添加:cc932.h,cc936.h,cc949.h,cc950.h,ccsbcs.h,syscall.h2.5 图像采集模块ov7725 是一个能够提供单片vga 摄像头和影像处理器的所有功能的图像传感器,它可以输出整帧,子采样,取窗口等方式的各种分辨率8/10 位图像数据,支持的数据格式有很多种,包括raw rgb ,rgb (grb 4:2:2,rgb 565/555/444) 以及ycbcr (4:2:2) 等格式12。它的体积小,工作电压低,具有单片vga 摄像头影像处理器的功能,可以对图像进行伽玛曲线、白平衡、饱和度、色度等处理13。2.5.1 摄像头输出时序ov7725 芯片的输出采用了vga 时序(是一种640*480像素显示器的显示模式),而ili9341液晶屏为3.2寸屏只能显示320*240像素的图像,故将其时序改为qvga(即原vga的四分之一,可配置ov7725的com7寄存器选择)。一个像素用16位的数据(rgb565)表示,而ov7725的数据总线宽度最多可设置为10位,故采用了8位的数据宽度(d2d9)输出图像信息。对ov7725内寄存器的配置接口是采用了sccb总线(后面会详细讲解),见图2.11。图2.11 ov7725一幅图像就是一帧的数据,ov7725在采集完一幅图像后,都会产生一个场/帧同步信号vsync,其时序为:一个脉冲为一帧的开始,低电平时开始传输,另一个脉冲为一帧结束,见图2.13。当捕捉到vsync的上跳沿(或下跳沿)时,产生中断,将数据写入到fifo中。vsync保持低电平表明正在传送图像。当再次捕捉到vsync的上跳沿(或下调沿)时,产生中断,一帧图像传输完毕,禁止向fifo的写入,并开始读fifo中的数据。一幅图由240行,320列个像素点组成,因此在vsync信号保持低电平阶段(即开始传输图像时)需要行同步信号href(输出行起始和行结束信号)换行,使数据一行行地被读出。行同步的时序为:href由低电平变为高电平时开始传输一行像素数据,高电平表示正在传输,由高变低时表示一行传输完毕。实际上,信号hsync(和href 共用一个管脚,可以通过软件来配置)也可以用于行同步,但与href 有一点区别。从图2.12中可以看到,href 为高电平时,摄像头输出的数据都是有效的,而hsync 高电平期间,在后面有一段时间是无意义的,即图中灰色部分。再结合fifo 的特性,选用了href 作为行同步,见图2.13。图2.12 帧时序图图2.13 行时序图前面讲到每一行都有320个像素点,在输出一行的像素点时,需要一个像素时钟pclk,确保像素点是一个个地被读出。在href保持高电平时,像素时钟信号pclk每出现一次上跳沿,就能输出一个字节数。而每个像素点采用rgb565的格式,共16位(2个字节数),故需要分两次输出。前一个字节从高位到低位依次是r4r0、g5g3,后一个字节是依次是g2g0、b4b0,见图2.14。图2.14像素输出时序2.5.2 fifo存储器由于摄像头采集图片信息的传输速率比较快(可达60fps),而stm32最快能每秒处理24帧的图像信息(每秒显示24张以上的图时,人眼会感觉出是连续的画面)。为了防止丢帧和解决stm32与ov7725间的速率匹配,在stm32和摄像头之间加入一个fifo存储器,见图2.15。fifo读时序主要用到4个管脚:re(读使能:低电平有效,已硬件接地)、oe(输出使能:低电平有效,高电平关闭输出)、rclk(读时钟)、rrst(读指针复位操作:低电平时,读指针复位到0地址开始读取数据)。re端硬件接地,则stm32随时可以读取里面的数据,但只有当oe为低电平时,读到的数据才是有效的,否则d0d7呈现高组态。oe为低电平时,随着rclk的运转,输出管脚d7d0按地址递增的方式(每读出一个字节,指针就会加一)输出数据,见图2.16。在数据全部读出后,要操作rrst将读指针复位,方便下次读取。图2.15 fifo与ov7725、stm32连接图2.16 fifo读时序fifo的写时序主要用到3个管脚:we(写使能:低电平有效)、wclk(写时钟)、wrst(写指针复位操作:当wrst为低电平时,写指针就复位到0地址开始写入)。we为低电平时,随着wclk的运转,输入管脚d17d10的数据就会按地址自增的方式写入到fifo中,见图2.17。在数据全部写入后,要操作wrst将写指针复位,方便下次写入。完整驱动程序流程:将摄像头的帧同步信号送入stm32,当stm32捕捉到场中断信号时,拉高wen 管脚电平,之后整幅图像的数据就会存入fifo。当再次捕捉到场中断时,表明一幅图像已经送入fifo,此时,关闭场中断,拉低wen 电平,防止摄像头数据再次写入fifo。并开始读取fifo 数据到内存缓冲区,交由stm32处理后显示到液晶屏上。再使能场中断,采集下一幅图像,如此循环。图2.17 fifo写时序2.5.3 sccb总线sccb(omnivision serial camera control bus),即串行摄像机控制总线,是一种已经由omnivision 公司定义和采纳的sccb总线是一种三线结构的串行总线,用于完成对绝大多数omnivision 系列图像传芯片功能的控制14。在简化的引脚封装中,sccb总线可以工作在改进的两线工作方式下15。两线sccb接口有两条通迅连接线,即sio_d(数据线)和 sio_c(时钟线)15。sccb接口协议是一种简化的i2c协议,两者通信的时序基本一致,但是在应答信号ack和总线停止信号等方面上存在差异。stm32上没有sccb的硬件接口,故采用gpio模拟i2c(sccb的双总线,将sccb_e硬件接地)的方式实现,下面是双总线功能原理图:图2.18 sccb的双总线接法(1)管脚定义sccb_e 信号低电平有效,一个高到低的转换表明数据传输开始;一个低到高的转换表明数据传输结束;数据传输过程保持为低电平;高电平表明总线处于空闲状态。在sccb_e表明数据传输开始之前主机必须将数据线sio_d置为1,这样可以避免总线数据传输开始之前的总线不确定状态的出现。sio_c 信号高电平有效,当处于空闲状态时必须被拉高;当启动传输后,sio_c被拉低表明数据传输的开始,传输过程中高电平表明一位数据正在传输,所以sio_d的数据变化只能在sio_c为低时发生,一位传输时间定义为tcyc,最小为10us。表2.5 主控器件管脚描述管脚类型描述sccb_e输出串行片选输出,当总线处于空闲状态时主机把sccb_e拉高为1,启动传输或处在悬浮状态时主机把sccb_e拉低。sio_c输出串行i/o信号1输出,空闲状态时主机把sio_c拉高;当sccb_e拉低时,在高低电平之间变化;当系统处于悬浮状态时,被拉低。sio_di/o串行信号0输入和输出,当总线处于空闲保持悬浮;系统处于悬浮状态时被拉低。pwdn输出掉电输出。注:当sccb_e没有出现在摄像头芯片引脚上时,默认使能,被拉高。表2.6 从控器件管脚描述管脚类型描述sccb_e输入串行片选输入,当系统处于挂起模式时,输入点可以被关闭。 sio_c输入串行i/o信号1输出,当系统处于挂起模式时,输入点可以被关闭。sio_di/o串行i/o信号0输入和输出,当系统处于挂起模式时,输入点可以被关闭。pwdn输入掉电输入。(2)sccb总线传输sccb与i2c总线的协议基本一致,读写时序相同,故对sccb的通信时序不再展开讨论。sccb的读操作:int sccb_readbyte(uint8_t* pbuffer, uint16_t length, uint8_t readaddress);入口参数: pbuffer存放待读出的数据;length:待读出的长度; readaddress:待读出的地址。第一步:判断起始信号,若初始化成功,进入第二步,否则返回失败;第二步:发送器件地址dev_adr,并等待应答,若有应答,进入第三步,否则返回失败;第三步:设置器件内部待读出的寄存器的低起始地址,并等待应答,释放总线;第四步:再次启用总线,并发送器件地址(dev_adr+1),并等待应答,进入第五步,否则返回失败;第五步:将数据读到pbuffer中,共读取length个字节,全部读出后,释放总线,返回成功。sccb写操作:int sccb_writebyte( uint16_t writeaddress , uint8_t sendbyte );入口参数:writeaddress 待写入的地址;sendbyte待写入的数据。第一步:判断起始信号,若初始化成功,进入第二步,否则返回失败;第二步:

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论