车载GPS导航模拟系统
学号:61009133
姓名:孙文
1、申请题目:车载GPS导航模拟系统
n 车载GPS导航模拟系统实际上相当于一个独立的GPS终端,它基于真正的
GPS的原型,实现了在点阵板上实现GPS功能的构想。由于不涉及与其他外设的无线信号传输,因而实际上这里的GPS采用的是固定的预存在程序上的图形,不具有更新功能;而在这一张图形上,具体实现了道路搜索展示、行进、定位、视角切换等功能,最终达到了在点阵板顺利实现GPS运行展示的预期目的。
2、课题背景:
n GPS导航采用先进的定位与计算技术,给人们的生活带来了极大地便利,已
经逐渐成为现代交通的的眼睛;同时我国的北斗卫星导航系统发展的如火如荼,有望在不久的将来大范围运用。但GPS使用费用高,在我国并不普及。该项目模拟GPS终端系统,可为用户提供一定导航、测速等基本作用。使用户熟悉GPS操作;同时作为终端的一种模拟系统,如果有外在真实信息的输入,在原理上就相当接近真正的GPS了。
3、项目规划:
n 功能、指标、规模
功能 基础部分:
1. 用户需要输入密码,启动汽车(模拟GPS系统)
2. 用户输入当前位置和终点后,系统自动搜索可用的最佳道路,并在点阵板上予以显示;
3. 用户通过键盘控制行进方向和拐弯方向;
4. 进入道路后,以闪烁的点表示汽车的逐渐运动;
5. 用户通过键盘输入速度,数码管显示剩余道路长度、行驶速度和剩余时间。
6. 智能语音提醒,在应当拐弯时语音提示;
7 提供车祸自动求救功能。车辆遭遇车祸时自动发出求救警报
提高部分:
8. 随着汽车的运动,点阵显示的道路的观察视角可以随之发生变化
9. 道路记录功能,提供给司机作为回程时参考
10.路线修改功能,若驾驶员不小心偏离最佳航线,系统会自动寻找路线回到主道路。
指标:道路能分不同颜色正确显示;正确运行输入输出功能;正确完成道路的搜索过程;可以基本展示出车辆运行的整个过程,运行过程中起点和终点闪烁;数码管显示正确无误;转向灯、状态指示灯等正常运行;运行过程中道路修正、以前道路展示、视角转换等功能正确无误。
规模:该项目主体定位于16*16点阵来展示整个道路画面,整个操作在开发板上运行,依靠键盘作为输入的工具,数码管、LED灯、点阵板作为输出负载,属于属于较为复杂的小型化、实用型FPGA系统。
n 控制面板
实际图像:
操作规则:
1. 按START键系统运行
2. 输入当前位置横纵坐标,按确定。
3. 输入终点的横纵坐标,按确定;若输入错误,只需按下E即可重新进行输入。
4. 再按确定,即可显示可用道路
5. 运行中驾驶员通过方向键控制车辆运行;通过A、B键切换运行速度;按7键启动视角切换功能,3键关闭该功能;按下C键可以随时查看走过的道路。
6. 偏离主道路后按HELP键,显示回至主道路的路径。
7 返回时,按PAST即可调出最近运行道路,以供回程参考
8. RST由外在开关输入,使得系统可以随时回到初始状态。
注:START键为“F”,HELP、PAST键均为“E”;上下左右方向键分别为“1”、“9”、“4”、“6”。
n 输入、输出接口
输入信号:1. RST信号,由开关直接输入相应接口即可。
2. 键盘列状态信号,直接由键盘上的COL1、COL2、COL3、COL4输入即可
输出信号:1.点阵板行扫描信号,具体包括红色red[9..0]和绿色green[9..0]两种信号;
2. 点阵板列扫描信号,为周期性变化的rows[9..0];
3. 键盘行扫描信号,只需将COL[3..0]输出到ROW[3..0]即可;
4. 数码管显示信号,连接至六个数码管,分别为x1[7..0], y1[7..0], x2[7..0], y2[7..0], redlen[7..0] , timeleft[7..0],表示起点横纵坐标、终点横纵坐标,剩余道路长度,剩余时间等。
5. finish , rled , lled, wrong接至LED显示,分别是到达终点信号,右转向灯,左转向灯,输入错误提醒
6. state[3..0]接至LED显示,表示当前状态;rot[1..0]表示当前视角与原始视角之间的角度差,接至LED显示。
4、实现方案:
n 核心问题
1. 显然,要模拟GPS道路导航系统,必须显示道路(实际上是最佳路径),这涉及到一个最佳路径的探求问题;
2. 在控制下实时显示驾驶着当前位置并能随意改变(可能涉及到视角变换问题)是一个复杂的控制过程
n 解决方案
1. 路径的确认,有两种可操作方案:
方案一.利用已有的走迷宫的算法,最初的想法是基于递归调用,但是硬件描述语言明显不具有实用的、成熟的的描述方式,结合数据结构中堆栈的知识,可只要把递归算法改为非递归算法,需要使用一个栈存储试探过程中所走过的路径。具体的,当在道路中向前试探时,可能同时存在几个允许的前进方向。我们用三元数组记下当期那位置和上一步前进方向,然后选择一个前进方向进行试探,若不通,则将位于栈顶的活动记录退栈,以在前进方向上回退一步,再尝试其他的的允许方向。其C++代码框架如下:
While (栈非空) {
(i , j, dir )=从栈顶推出的坐标和方向;
While(还有移动) {
(g,h)=下一移动的坐标;
If (g==m&&h==p)迷宫搜索成功; //出口在Maze[m][p]
Mark[g][h]=1;
Dir=下一次将要移动的方向;
(I,j,dir)进栈;
I=g;j=h;dir=0;
//当前位置[i][j]移到[g][h]位置,方向置’N’
}
}
}
这里的栈可通过一个数组和一个位置参量来实现;
direc[stacktop]即可表示这种堆栈,实际上是程序中方向的存储堆栈;也就是说,stacktop指向当前栈顶。
方案二.由于显示路径有限,一个很自然的想法便是穷举法,即依据道路连接情况对道路分段和编号,并分别确定两不同道路间的最佳路径走法。判别时,只需确定起点和终点分别位于哪两段道路上,然后就可以调用已知路径。但这种方法有着很大的缺点——代码繁重复杂,可移植性很差,故而仅仅作为一个备选方案
我综合考虑了,成熟性、技巧性、可移植性等诸多因素,选择了方案一作为实现方法。
2. 关于运行过程的复杂的显示问题,我的想法是:设置两组变量,一组直接关联键盘输入,另一组直接关联点阵板显示,它们两者之间的联系决定于一旋转寄存器,即视角切换的角度的寄存器;其次,对道路的节点进行判断,当驾驶者位置到达节点时,可综合考虑其行进方向,判断其应该旋转的方向,并对旋转寄存器做相应加减处理,这样就可以借助它来实现视角的切换。
5、系统结构:
n 系统框图
简化框图:
实际总框图:
1. 主程序框图
2. 转向处理框图
3. 输出译码框图
n 模块功能描述
1. 分频电路模块主要用于对输入时钟信号进行分频,得到多种时钟信号,以满足不同模块对时钟的要求,输入晶振时钟2MHZ,输出1KHZ点阵显示扫描时钟和5HZ的闪烁时钟。
2. 键盘输入模块用于将键盘电信号转化为控制信号,具体包括输入消抖电路和电信号识别以及编码两个部分
3. 状态控制与显示控制模块:主要依据当前状态和输入信号控制状态转换方向和输出控制信号。具体实现整个系统状态机跳转、数组地图的定义,赋值,修改功能;道路搜索以及显示;修正道路、记录和显示走过道路、视角切换、随时切换速度、计算显示路程时间等主体功能。相当于许多模块的集成。
4. 扫描显示模块:主要产生行扫描和列扫描信号,用于将道路图像显示在16*16点阵上。
5. 其余部分显示模块:主要是数码管和二极管显示灯模块,用于显示车辆行驶速度、路程以及时间和起点终点等信息,此外还有当前状态信息、终点提示灯、转向提示灯等LED提示。
n 模块接口标注(参数、协议)
采用EP1C6Q240C8实验箱,其输入输出的实际连线与管脚表如下:
输入输出名称
|
芯片引脚号
|
实验箱标注
|
钉子线连接
|
Clk_maze
|
28
|
CLK
|
无
|
Col[0]
|
120
|
ROW1
|
无
|
Col[1]
|
121
|
ROW 2
|
无
|
Col[2]
|
122
|
ROW 3
|
无
|
Col[3]
|
123
|
ROW 4
|
无
|
Green[0]
|
177
|
绿行选1
|
有
|
Green[1]
|
178
|
绿行选2
|
有
|
Green[2]
|
179
|
绿行选3
|
有
|
Green[3]
|
180
|
绿行选4
|
有
|
Green[4]
|
181
|
绿行选5
|
有
|
Green[5]
|
182
|
绿行选6
|
有
|
Green[6]
|
184
|
绿行选7
|
有
|
Green[7]
|
48
|
绿行选8
|
有
|
Green[8]
|
234
|
绿行选9
|
有
|
Green[9]
|
235
|
绿行选10
|
有
|
Irow[0]
|
124
|
COL1
|
无
|
Irow[1]
|
125
|
COL2
|
无
|
Irow[2]
|
126
|
COL3
|
无
|
Irow[3]
|
131
|
COL4
|
无
|
lled
|
222
|
L8
|
无
|
rled
|
223
|
L7
|
无
|
Red[0]
|
23
|
红行选1
|
有
|
Red[1]
|
21
|
红行选2
|
有
|
Red[2]
|
20
|
红行选3
|
有
|
Red[3]
|
19
|
红行选4
|
有
|
Red[4]
|
18
|
红行选5
|
有
|
Red[5]
|
17
|
红行选6
|
有
|
Red[6]
|
16
|
红行选7
|
有
|
Red[7]
|
15
|
红行选8
|
有
|
Red[8]
|
14
|
红行选9
|
有
|
Red[9]
|
13
|
红行选10
|
有
|
Row[0]
|
12
|
列选1
|
有
|
Row[1]
|
11
|
列选2
|
有
|
Row[2]
|
8
|
列选3
|
有
|
Row[3]
|
7
|
列选4
|
有
|
Row[4]
|
6
|
列选5
|
有
|
Row[5]
|
5
|
列选6
|
有
|
Row[6]
|
4
|
列选7
|
有
|
Row[7]
|
45
|
列选8
|
有
|
Row[8]
|
46
|
列选9
|
有
|
Row[9]
|
47
|
列选10
|
有
|
Redlen[0]
|
159
|
数码管5 h段
|
有
|
Redlen[1]
|
160
|
数码管5 g段
|
有
|
Redlen[2]
|
161
|
数码管5 f段
|
有
|
Redlen[3]
|
162
|
数码管5 e段
|
有
|
Redlen[4]
|
163
|
数码管5 d段
|
有
|
Redlen[5]
|
164
|
数码管5 c段
|
有
|
Redlen[6]
|
165
|
数码管5 b段
|
有
|
Redlen[7]
|
166
|
数码管5 a段
|
有
|
Rst
|
158
|
K1
|
有
|
State[0]
|
228
|
L2
|
无
|
State[1]
|
227
|
L3
|
无
|
State[2]
|
226
|
L4
|
无
|
State[3]
|
225
|
L5
|
无
|
Timeleft[0]
|
167
|
数码管6 h段
|
有
|
Timeleft[1]
|
168
|
数码管6 g段
|
有
|
Timeleft[2]
|
169
|
数码管6 f段
|
有
|
Timeleft[3]
|
170
|
数码管6 e段
|
有
|
Timeleft[4]
|
173
|
数码管6 d段
|
有
|
Timeleft[5]
|
174
|
数码管6 c段
|
有
|
Timeleft[6]
|
175
|
数码管6 b段
|
有
|
Timeleft[7]
|
176
|
数码管6 a段
|
有
|
X1[0]
|
80
|
数码管4 h段
|
无
|
X1[1]
|
81
|
数码管4 g段
|
无
|
X1[2]
|
82
|
数码管4 f段
|
无
|
X1[3]
|
83
|
数码管4 e段
|
无
|
X1[4]
|
84
|
数码管4 d段
|
无
|
X1[5]
|
85
|
数码管4 c段
|
无
|
X1[6]
|
86
|
数码管4 b段
|
无
|
X1[7]
|
87
|
数码管4 a段
|
无
|
Y1[0]
|
88
|
数码管3 h段
|
无
|
Y1[1]
|
93
|
数码管3 g段
|
无
|
Y1[2]
|
94
|
数码管3 f段
|
无
|
Y1[3]
|
95
|
数码管3 e段
|
无
|
Y1[4]
|
96
|
数码管3 d段
|
无
|
Y1[5]
|
97
|
数码管3 c段
|
无
|
Y1[6]
|
98
|
数码管3 b段
|
无
|
Y1[7]
|
99
|
数码管3 a段
|
无
|
X2[0]
|
100
|
数码管2 h段
|
无
|
X2[1]
|
101
|
数码管2 g段
|
无
|
X2[2]
|
102
|
数码管2 f段
|
无
|
X2[3]
|
103
|
数码管2 e段
|
无
|
X2[4]
|
104
|
数码管2 d段
|
无
|
X2[5]
|
105
|
数码管2 c段
|
无
|
X2[6]
|
106
|
数码管2 b段
|
无
|
X2[7]
|
107
|
数码管2 a段
|
无
|
Y2[0]
|
108
|
数码管1 h段
|
无
|
Y2[1]
|
113
|
数码管1 g段
|
无
|
Y2[2]
|
114
|
数码管1 f段
|
无
|
Y2[3]
|
115
|
数码管1 e段
|
无
|
Y2[4]
|
116
|
数码管1 d段
|
无
|
Y2[5]
|
117
|
数码管1 c段
|
无
|
Y2[6]
|
118
|
数码管1 b段
|
无
|
Y2[7]
|
119
|
数码管1 a段
|
无
|
finish
|
221
|
L9
|
无
|
wrong
|
233
|
L1
|
无
|
Rot[0]
|
204
|
L17
|
无
|
Rot[1]
|
202
|
L18
|
无
|
6、状态流程图:
n 系统工作状态流程
7、各主要模块仿真结果波形
n 各模块的仿真波形,详细注释输入输出功能端口
主程序仿真图:
端口说明:
opeartion为键盘输入
x1、y1是当前坐标
x2、y2是终点坐标
searchflag是搜索寄存器
state是状态寄存器
initflag是初始化寄存器。
BCD码转八段码模块:
Shuru:BCD码输入
Clk:时钟;
Shuchu :八段码输出;
转向灯模块:
Clk: 时钟;
Iled:主程序输入转向信号
Oled:输出转向灯
Rst:清零信号
8、课程设计总结
n 预期的目标与当前实现功能的差异详细注释
预期实现的道路显示、道路搜索、人员运行、道路修正、视角切换、以往道路显示等功能得到了实现;但是车祸报警功能没有实现,因为涉及到外设,非常复杂;同时,原先设定的几张图级联的想法也没有实现,即只能在一张图上运行以上诸多操作,而不能形成“地图网”。而在完成的功能中,我增加了状态提示,转向角显示等功能,同时,分别完善和简化了一些功能,如:视角切换的初始方向只能是固定的,简化了要求;而输入错误时可以重新输入,则是扩展了原来的功能。
n 可以进一步发挥提高的部分
1. 在每步运行前,如果能够给出具体提示,则会更好;
2. 加上测醉驾的外设,利用酒精传感器与AD转换实现酒架报警,则功能更趋完善;
3. 可以增加多幅图,能够自由实现几幅图之间的切换,能够在不同地图上共同连接成一条道路,实现“地图网”。
n 课程设计体会
数字系统的设计实际上是一次自主学习的过程,这个过程中有过挣扎,有过失望,有时甚至想要放弃;但同时也有成就,快乐和自信,现在回想起来,学到了很多。
课程要求我们用硬件描述语言编写一个相对复杂的系统,而硬件描述语言我们从没接触过,老师上课也不讲述,所以这完全靠我们自学了。这样一个过程,虽然是痛苦的,却毫无疑问,极大地锻炼了我们自主学习、查找资料、发现分析解决问题等的能力,现在想来。如果不是有这门课,我恐怕始终不会相信自己可以靠自学完全掌握这样一门设计语言。
整个设计过程,我选择了Verilog语言,因为它与C语言即极为相似,容易掌握。而这个过程,却也有好多问题:比如Verilog语言中,我多采用了非阻塞赋值,需要在以时钟作用下同步运行;而C++则不是这样,它往往是顺序执行,前一行执行完了才执行下一行;这样两门语言就产生了差距,处理的办法是在Verilog中设计节拍,在节拍的作用下,每次只执行一小段,整体看来就相当于顺序执行。这实际上是自己思考的结果,很好的锻炼了自己独立思考的能力。
在整个设计过程中,我始终注意到了两点,一是多用状态寄存器,因为状态寄存器可以很好的传递信息,而代价却很小,因而用起来很方便,我在程序中设置了许多临时变量,使得整个程序看起来很复杂,实际上确是井然有序;而是避免任何隐患的产生,在程序中我考虑到了诸如输入错误如何处理、如何在闪烁的点亮的时候运行到下一个地方,如何保证正序旋转和反向旋转互不干扰,可以叠加,且每次只执行一次等等,这些考虑,使得系统抗风险能力大幅度提高,拥有着较高稳定性,因而也就能更好的展示出来。
调试程序是整个系统设计的大头,往往耗费的时间比编程还多。同时自己的实践,我总结出了以下几点:一是最好在调试前进行仿真,仿真无误后再进实验室进行调试;二是分模块检验,最好保证每一块都是对的,这样才能级联起来构成系统;三,要对自己的程序十分的熟悉,要经常看,搞清楚哪几个量会影响特定输出,调试时如果发现那个量不正确,只需注意查看其影响因素即可;最后一点,如果实在发现不了错误,而运行结果又不对,就可以了考虑以下是不是硬件的问题了,因为实验室的条件实在不敢恭维了,弄不好花了一天时间没调试出来,却最后发现是硬件不行,那就冤枉了。
整个数字系统的设计,占用了我们很多的时间,尤其是接近考试周的宝贵时间。但我们确实学到了很多东西,它将成为我们一个难忘的记忆,见证着我们不畏困难、勇往直前的学习精神,见证着我们的成功。以后的道路上,即便再有其他困难,有了这样一种历练,我们会更加从容不迫的应对。
9、参考文献
[1] 徐莹隽、常春等编著,数字逻辑电路设计实践.北京:高等教育出版社,2008.5
[2] 夏宇闻等编著,Verilog数字系统设计教程。北京:北京航空航天大学出版社,2003
[3] 姚远,李辰编著 ,FPGA开发入门与典型实例。北京:人民邮电出版社,2010