嵌入式系统行车记录仪方案Word文件下载.docx
《嵌入式系统行车记录仪方案Word文件下载.docx》由会员分享,可在线阅读,更多相关《嵌入式系统行车记录仪方案Word文件下载.docx(23页珍藏版)》请在冰豆网上搜索。
32
第一章前言
车辆行驶记录仪又称汽车黑匣子,它是将飞机黑匣子的设计思想应用于汽车,集机械、电子、微电脑于一体,用于预防事故、监查违章和科学管理,并为事故分析提出公正、准确、科学的依据。
早在1990年以前欧共体就通过了在汽车上安装黑匣子的立法,要求欧共体的15个成员国在10a内给使用中的约900万辆商用车安装这一装置。
美国、日本、香港及马来西亚等国家和地区也相继广泛使用汽车黑匣子。
统计资料表明,汽车黑匣子的使用,使交通事故率降低了37%~52%,减少了人员伤亡和财产损失,产生了显著的社会效益和经济效益。
我国也正朝这个方向发展,我国的汽车行驶记录仪的国家标准(汽车行驶记录仪>
已于2003年9月1日正式实施,因此,开发基于国家标准的新型智能汽车行驶记录仪系统的条件已经成熟。
新型智能汽车行驶记录仪系统不仅要求具有基本的记录功能,还应具备显示、语音报警提示等功能,有良好的人机交互界面,具有通用的计算机接口。
通过配套的上位机分析数据,能对驾驶员、车辆、行驶速度等各种信息进行有效的管理。
第二章国内外研究现状
我国从20世纪80年代后期开始,在少数地区曾试用过由国内一些科研机构和企业自主研制的数字式记录仪,这些记录仪的主要功能是集中存储一些数据,以便车辆发生意外后将数据取出,重现事故全过程。
但由于存储数据比较少,无法有效复现事故过程,不能很好地分析事故原因,而且记录仪的功能是事后方知,解决不了控制交通事故发生率的问题。
因此,汽车行驶记录仪终因其不能起到预防交通事故发生的作用而无法推广同.2001年底,公安部、交通部、国家安全生产监督管理局联合下达了《公安部、交通部、国家安全生产监督管理局关于加强公路客运交通安全管理的通告》。
通告要求:
长途客运车辆应当逐步安装、使用符合国家有关标准的行车记录仪。
到2003年4月15日,由公安部有关部门起草、国家标准化管理委员会、国家经贸委审定通过,国家质量监督检查检疫总局发布了汽车行驶记录仪的国家标准正式实施。
实施对象包括所有的在用车和新车,将逐步由点到面,分批分时的展开。
汽车行驶记录仪是一种法规性的产品,将在配套法规的支持下推广应用,据不完全统计,全国有广东、四川、吉林、湖南、上海、浙江等20多个省、自治区、直辖市汽车行驶记录的应用工作取得进展,已安装使用行驶记录仪的客运、货运企业约350多家,车辆约2万辆。
目能全国各地交通运输企业营运车辆安装使用行车记录仪的工作仍处于起步阶段,各地的工作进展不一。
推广使用汽车行驶记录仪是一项既定国策,是一项中长期持久的工作任务.
第三章整体方案设计
本设计选择具有高性能、低成本、低功耗的,为嵌入式应用专门设计的ARMCortex-M3内核的STM32F107VCT6作为行车记录仪系统的中央处理单元,其内置256K的闪存,时钟频率达到72MHz。
并应用具有执行效率高、占用空间小、实时性能优良和可扩展性强等特点,最小内核可编译至2KB的UCOSII嵌入式操作系统。
使用具有30万像素的OV7670图像传感器采集信息,运用USB传输到STM32中,将图像信息显示在TFT上并存储在外部SD卡中。
该系统主要由OV7670摄像头模块,TFT显示模块,SD卡存储模块及USB传输模块组成。
USB
传
输
第四章各部分功能实现
1.信息采集模块
OV7670,图像传感器,体积小,工作电压低,提供单片VGA摄像头和影像处理器的所有功能。
通过SCCB总线控制,可以输入整帧、子采样、取窗口等方式的各种分辨率8位影像数据。
该产品VGA图像最高达到30帧/秒。
用户可以完全控制图像质量、数据格式和传输方式。
所有图像处理功能过程包括伽玛曲线、白平衡、饱和度、色度等都可以通过SCCB接口编程。
OmmiVision图像传感器应用独有的传感器技术,通过减少或消除光学或电子缺陷如固定图案噪声、托尼、浮散等,提高图像质量,得到清晰的稳定的彩色图像。
OV7670的特点有:
高灵敏度、低电压适合嵌入式应用,标准的SCCB接口,兼容IIC接口,支持RawRGB、RGB(GBR4:
2:
2,RGB565/RGB555/RGB444>
,YUV(4:
2>
和YCbCr<
4:
2:
2)输出格式,支持VGA、CIF,和从CIF到40*30的各种尺寸输出,支持自动曝光控制、自动增益控制、自动白平衡、自动消除灯光条纹、自动黑电平校准等自动控制功能。
同时支持色饱和度、色相、伽马、锐度等设置。
,支持闪光灯,支持图像缩放。
OV7670功能框图
OV7670行输出时序
OV7670帧时序
2.信息传输模块
USB,是英文UniversalSerialBUS<
通用串行总线)的缩写,而其中文简称为“通串线,是一个外部总线标准,用于规范电脑与外部设备的连接和通讯。
是应用在PC领域的接口技术。
USB接口支持设备的即插即用和热插拔功能。
USB是在1994年底由英特尔、康柏、IBM、Microsoft等多家公司联合提出的。
SB发展到现在已经有USB1.0/1.1/2.0/3.0等多个版本。
目前用的最多的就是USB1.1和USB2.0,USB3.0目前已经开始普及。
STM32F107自带的USB符合USB2.0规范。
标准USB共四根线组成,除VCC/GND外,另外为D+,D-。
这两根数据线采用的是差分电压
的方式进行数据传输的。
在USB主机上,D-和D+都是接了15K的电阻到低的,所以在没有设备接入的时候,D+、D-均是低电平。
而在USB设备中,如果是高速设备,则会在D+上接一个1.5K的电阻到VCC,而如果是低速设备,则会在D-上接一个1.5K的电阻到VCC。
这样当设备接入主机的时候,主机就可以判断是否有设备接入,并能判断设备是高速设备还是低速设备。
STM32F107的MCU自带USB从控制器,符合USB规范的通信连接;
PC主机和微控制器之间的数据传输是通过共享一专用的数据缓冲区来完成的,该数据缓冲区能被USB外设直接访问。
这块专用数据缓冲区的大小由所使用的端点数目和每个端点最大的数据分组大小所决定,每个端点最大可使用512字节缓冲区<
专用的512字节,和CAN共用),最多可用于16个单向或8个双向端点。
USB模块同PC主机通信,根据USB规范实现令牌分组的检测,数据发送
/接收的处理,和握手分组的处理。
整个传输的格式由硬件完成,其中包括CRC的生成和校验。
每个端点都有一个缓冲区描述块,描述该端点使用的缓冲区地址、大小和需要传输的字节数。
当USB模块识别出一个有效的功能/端点的令牌分组时,(如果需要传输数据并且端点已配置>
随之发生相关的数据传输。
USB模块通过一个内部的16位寄存器实现端口与专用缓冲区的数据交换。
在所有的数据传输完成后,如果需要,则根据传输的方向,发送或接收适当的握手
分组。
在数据传输结束时,USB模块将触发与端点相关的中断,通过读状态寄存器和/或者利用不同的中断来处理。
USB的中断映射单元:
将可能产生中断的USB事件映射到三个不同的NVIC请求线上:
1、USB低优先级中断(通道20>
:
可由所有USB事件触发(正确传输,USB复位等>
。
固件
在处理中断前应当首先确定中断源。
2、USB高优先级中断(通道19>
仅能由同步和双缓冲批量传输的正确传输事件触发,目
的是保证最大的传输速率。
3、USB唤醒中断(通道42>
由USB挂起模式的唤醒事件触发。
USB设备框图如下图所示
3.显示模块
TFT-LCD即薄膜晶体管液晶显示器。
其英文全称为:
ThinFilmTransistor-LiquidCrystalDisplay。
TFT-LCD与无源TN-LCD、STN-LCD的简单矩阵不同,它在液晶显示屏的每一个象
素上都设置有一个薄膜晶体管<
TFT),可有效地克服非选通时的串扰,使显示液晶屏的静态特性与扫描线数无关,因此大大提高了图像质量。
TFT-LCD也被叫做真彩液晶显示器
1、TFTLCD控制器ili9325寄存器和指令
采用16位数据线。
80并口有如下一些信号线:
CS:
TFTLCD片选信号。
//为0时,片选成功
WR:
向TFTLCD写入数据。
//上升沿有效
RD:
从TFTLCD读取数据。
D[15:
0]:
16位双向数据线。
//可读可写
RST:
硬复位TFTLCD。
写1有效
RS:
命令/数据标志<
0,读写命令;
1,读写数据)。
2、模块的控制器为ILI9320,该控制器自带显存,其显存总大小为172820<
240*320*18/8),即18位模式<
26万色)下的显存量。
模块的16位数据线与显寸的对应关系为565方式,如下图所示:
最低5位代表蓝色,中间6位为绿色,最高5位为红色。
数值越大,表示该颜色越深。
接下来,我们介绍一下ILI9320的几个重要命令,因为ILI9320的命令很多,大家可以找到ILI9320的datasheet看看。
要介绍的命令列表如下:
R0,这个命令,有两个功能,如果对它写,则最低位为OSC,用于开启或关闭振荡器。
对它读操作,则返回的是控制器的型号。
这个命令最大的功能就是通过读它可以得到控制器的型号,而我们代码在知道了控制器的型号之后,可以针对不同型号的控制器,进行不同的初始化。
因为93xx系列的初始化都比较类似,我们完全可以用一个代码兼容好几个控制器。
R3,入口模式命令。
我们重点关注的是I/D0、I/D1、AM这3个位,因为这3个位控制了屏幕的显示方向。
AM:
控制GRAM更新方向。
当AM=0的时候,地址以行方向更新。
当AM=1的时候,地址以列方向更新。
I/D[1:
当更新了一个数据之后,根据这两个位的设置来控制地址计数器自动增加/减少1,其关系如下图:
R7,显示控制命令。
该命令CL位用来控制是8位彩色,还是26万色。
为0时26万色,为1时八位色。
D1、D0、BASEE这三个位用来控制显示开关与否的。
当全部设置为1的时候开启显示,全0是关闭。
我们一般通过该命令的设置来开启或关闭显示器,以降低功耗。
R32,R33,设置GRAM的行地址和列地址。
R32用于设置列地址<
X坐标,0-239),R33用于设置行地址<
Y坐标,0-319)。
当我们要在某个指定点写入一个颜色的时候,先通过这两个命令设置到改点,然后写入颜色值就可以了。
R34,写数据到GRAM命令,当写入了这个命令之后,地址计数器才会自动的增加和减少。
该命令是我们要介绍的这一组命令里面唯一的单个操作的命令,只需要写入该值就可以了,其他的都是要先写入命令编号,然后写入操作数。
R80~R83,行列GRAM地址位置设置。
这几个命令用于设定你显示区域的大小,我们整个屏的大小为240*320,但是有时候我们只需要在其中的一部分区域写入数据,如果用先写坐标,后写数据这样的方式来实现,则速度大打折扣。
此时我们就可以通过这几个命令,在其中开辟一个区域,然后不停的丢数据,地址计数器就会根据R3的设置自动增加/减少,这样就不需要频繁的写地址了,大大提高了刷新的速度
2、TFTLCD-字符显示
其实每一字符就是一幅图像,字符的大小对应于图像的大小,字符的笔画对应于图像的内容。
那么如何把字符转换为图像呢?
简单的方法是使用“字模提取”之类的软件,它能够把任意的字符转换为一个字节型的数组,数组元素中的每一位代表LCD上的一个像素点,当为1时,表示该位置为字符的一个笔画,需要上色,而为0时,表示不是笔画,不需要上色。
例如,一个字符想要在16×
16的面积上显示,即该字符的宽和高各为16个像素,因为每一个像素用一位来表示,因此用字模提取软件生成的字节型数组,一共有16×
16÷
8=32个字节。
在字模提取的过程中,还要注意取模的顺序,顺序不同,得到的数组就不同,一般来说是从字符的左上角开始,从左向右,从上到下取模,这样程序编写上会方便一些。
相同字体大小的中文字符和ASCII码字符的宽度还有所不同,一般ASCII码字符的宽度是中文字符宽度的一半,所以显示中文字符的程序和显示ASCII码字符的程序还略有不同。
当把一个字符取模变成一个数组后,只要对该数组中每个元素的每一位依次进行判断,对值为1的位和值为0的位进行不同的上色处理,即可完成一个字符的绘制。
如果要在程序中显示大量的中文字符,是不是要把这些字符都取模啊?
回答是肯定的,但前人已经为我们完成了这一步,做成了数据库,并且进行了编码,只要按照编码规则调用该库文件,就可以检索到相要的字符。
下面就来说说编码规则:
每个汉字是由两个字节表示的,前一个字节表示的区号,后一个字节表示的位号,那么汉字在汉字库中的位置为:
94×
<
区号-1)+<
位号-1)。
94表示的是每个区里一共有94个汉字,减1表示的是数组是从0开始,而区号和位号是从1开始的。
具体到汉字在某一数据库中的位置,还需要乘以一个汉字字模所占的字节数,即[94×
位号-1)]×
一个汉字字模所占字节数。
如一个字模大小为16×
16的宋体数据库,库里每个汉字所占的字节为16×
8=32,则每个汉字在该宋体数据库中的位置为:
[94×
32。
ASCII码的字符调用比汉字字符要简单,只要把它乘以字模所占字节数即可找到该字符所在字库的位置,如8×
16的ASCII字库,ASCII码在该字库的位置为ASCII×
16。
如果中文字符和ASCII码混合在一样,如何区分它们呢?
其实也很简单,ASCII码的最高位是0,而中文的最高位是1,因此当读取到的一个字节的最高位是0,则该字节为ASCII码,它的下一个字节与这个字节无关;
当取得到的字节的最高位是1,则表示的是中文字符,并且该字节与它的下一个字节组合在一起表示完整的一个汉字。
显示ASCⅡ码,字库来自程序内,是8*16的,而汉字的字库则有两种选择,一种是代码字库,即有限的字库在代码中保存.另外一种就是FLASH字库,整个汉字库在FLASH中。
暂时程序都是显示的16*16汉字.两种使用汉字库的使用方式都很有代表意义。
代码字库的原理相当简单,采用索引的形式搜索你所需要的汉字.例如你字的代码
字库为:
"
你"
0x90,0x00,0x90,0x01,0x88,0x20,0xC8,0x7F,0x44,0x20,0x2C,0x12,0x16,0x02,0x45,0x0A,0xC4,0x12,0x44,0x12,0x24,0x22,0x24,0x62,0x14,0x22,0x84,0x02,0x04,0x01,0x00,0x00,
每个字的字库,都以此汉字的字符串作为一个索引值,汉字显示中,通过先搜索要显示的汉字是否在索引中出现,如找到索引,则使用索引之后的字库代码显示汉字.FLASH字库的原理就是把字库按汉字的内码排列好并烧写进FLASH,需要的时候,根据要显示的汉字的内码,搜索其对应字库在FLASH中的首地址,并读出字库到缓冲,再进写屏。
使用FLASH字库,首先需要你的FLASH里面带有字库.
3、TFTLCD-图片显示
图片显示最重要的一点是图片取模的扫描顺序,我应用的图片扫描软件是Image2Lcd,这是一款相当实用的图片取模软件。
图片取模注意要点:
当AM=0时设置水平扫描左右扫描依图上下与图相反
当AM=1时设置垂直扫描上下扫描依图左右与图相反
另外还需注意在显示图片数组的语句中首八位字节是左移还是右移,以此判定是高位在前还是地位在前。
4.信息存储模块
SD卡<
SecureDigitalMemoryCard)中文翻译为安全数码卡,它是在MMC的基础上发展而来,是一种基于半导体快闪记忆器的新一代记忆设备,它被广泛地于便携式装置上使用,例如数码相机、个人数码助理(PDA>
和多媒体播放器等。
SD卡由日本松下、东芝及美国SanDisk公司于1999年8月共同开发研制。
大小犹如一张邮票的SD记忆卡,重量只有2克,但却拥有高记忆容量、快速数据传输率、极大的移动灵活性以及很好的安全性。
按容量分类,可以将SD卡分为3类:
SD卡、SDHC卡、SDXC卡。
SD卡和SDHC卡协议基本兼容,但是SDXC卡,同这两者区别就比较大了,本章我们讨论的主要是SD/SDHC卡<
简称SD卡)。
SD卡一般支持2种操作模式:
1,SD卡模式<
通过SDIO通信);
2,SPI模式;
主机可以选择以上任意一种模式同SD卡通信,SD卡模式允许4线的高速数据传输。
SPI模式允许简单的通过SPI接口来和SD卡通信,这种模式同SD卡模式相比就是丧失了速度。
SD卡的命令总共有12类,分为Class0~Class11,
第五章硬件电路设计
1、STM32最小系统
STM32的最小系统包括:
单片机、振荡电路、复位电路、电源电路等。
其中振荡电路才用8M晶振,电源电路采用TLV11173.3V稳压芯片。
2.液晶接口电路设计
3.OV7670摄像头模块
4.SD卡存储模块
5.USB传输模块
第六章部分程序
//初始化OV7670
//返回0:
成功
//返回其他值:
错误代码
u8OV7670_Init(void>
{
u8temp。
u16i=0。
GPIO_InitTypeDefGPIO_InitStructure。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC,ENABLE>
//使能相关端口时钟
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6。
//PA8输入上拉vsync
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU。
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz。
GPIO_Init(GPIOC,&
GPIO_InitStructure>
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_12|GPIO_Pin_11。
//端口配置WRRD
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP。
//推挽输出
GPIO_Init(GPIOB,&
GPIO_SetBits(GPIOB,GPIO_Pin_11|GPIO_Pin_12>
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8。
//端口配置rclk
GPIO_Init(GPIOA,&
GPIO_SetBits(GPIOA,GPIO_Pin_8>
GPIO_InitStructure.GPIO_Pin=0xff。
//PC0~7输入上拉
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1|GPIO_Pin_12。
//WRSTRRST
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP。
GPIO_SetBits(GPIOC,GPIO_Pin_1|GPIO_Pin_12>
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5。
GPIO_ResetBits(GPIOC,GPIO_Pin_5>
SCCB_Init(>
//初始化SCCB的IO口
if(SCCB_WR_Reg(0x12,0x80>
>
return1。
//复位SCCB
delay_ms(50>
//读取产品型号
temp=SCCB_RD_Reg(0x0b>
if(temp!
=0x73>
return2。
temp=SCCB_RD_Reg(0x0a>
=0x76>
//初始化序列
for(i=0。
i<
sizeof(ov7670_init_reg_tbl>
/sizeof(ov7670_init_reg_tbl[0]>
/2。
i++>
{
SCCB_WR_Reg(ov7670_init_reg_tbl[i][0],ov7670_init_reg_tbl[i][1]>
delay_ms(2>
}
return0x00。
//ok
}
///////////////////////////////////////////////////////////////