小车运动控制的VHDL描述设计.docx
- 文档编号:28042493
- 上传时间:2023-07-07
- 格式:DOCX
- 页数:22
- 大小:706.32KB
小车运动控制的VHDL描述设计.docx
《小车运动控制的VHDL描述设计.docx》由会员分享,可在线阅读,更多相关《小车运动控制的VHDL描述设计.docx(22页珍藏版)》请在冰豆网上搜索。
小车运动控制的VHDL描述设计
Part1:
设计简介及背景知识
控制对象——由两台小型二相步进电机驱动的小车
控制目标——通过档位键盘(对应信号为dang[3..0])和控制键盘(对应信号kong[2..0])实现小车以两级速度前进、前左转、前右转、倒车、左倒车和右倒车。
本设计采用自顶向下的设计方法,分为三个模块(见下页图),队员分工设计。
各模块的相关说明
步进电机的转速和输入脉冲信号的频率成正比,所以可以通过第二模块产生不同的分频信号控制其转速。
本设计采用二相双四拍的电机工作模式,故须在第三模块实现相应的脉冲分配。
第三模块同时将脉冲导向不同的电机,实现方向控制。
步进电机启动时不能加太高的频率,否则会啸叫、震动、丢步,无法实现快速、稳定的启动,所以在第一模块对输入的时钟脉冲sr_clk进行处理,再输入下一级以实现控制信号启动部分的过渡。
步进电机的输入脉冲顺序相反时(相当于反接线时),会反转,因此可以通过在第三模块对输出反顺序赋值实现反转控制。
关于仿真的说明
步进电机的工作频率在KHZ级,此频率下可忽略芯片内部演示带来的影响,故一下的仿真大多为功能仿真。
参考资料
《基于VHDL语言与Quartus软件的可编程逻辑器件应用与开发》郑燕,赫建国,党剑华编著
《基于QuartusII的FPGA/CPLD设计》李洪伟,袁斯华编著
《VHDL语言设计技术》陈耀和著
《数字电子技术基础》(第二版)杨颂华冯毛官孙万蓉初秀琴胡力山编著
《步进电机综述》北京市自动化技术研究所,一机部电器科学研究
《新版机器人技术手册》(日)日本机器人学会编宗光华
Part2:
各模块代码及详解
第一模块:
脉冲分频
一、模块功能
对信号的起始部分的降频(因启动时需频率较低来过渡),输出最终的控制脉冲clk。
通过对脉冲计数分先后在同一输出clk上实现8、4、2、1(即原频)的输出,以达到缓慢启动。
二、原程序及相关说明
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityfenis
port(
sr_CLK:
INstd_logic;
kong:
instd_logic_vector(2downto0);
clk:
OUTstd_logic
);
endfen;
architecturedivoffenis
signalQ:
std_logic_vector(2downto0);--自定义变量用于计数分频转接输出等。
signalC:
std_logic;
signalD:
std_logic;
signalE:
std_logic;
signalR:
std_logic_vector(7downto0):
="00000000";
begin
process(sr_CLK)
begin
ifsr_CLK'EVENTANDsr_CLK='1'then
if(Q="111")then
Q<="000";
else
Q<=Q+1;
endif;
endif;
endprocess;
C<=Q
(2);--8分频
D<=Q
(1);--4分频
E<=Q(0);--2分频
PROCESS(sr_CLK,kong)--计数,在前96个脉冲使用某低速,在其后的脉冲使用某中速,在97个脉冲之后使用据横速度
BEGIN
ifsr_CLK'eventandsr_CLK='1'then
casekongis
when"011"|"101"|"110"=>
if(R<"10000000")then
R<=R+1;
else
R<=R;
endif;
whenothers=>
R<="00000000";
endcase;
endif;
endprocess;
process(R,C,D,E,sr_CLK)
begin
if(R="00000000")then
clk<='0';
elsif(R="00000001")then
clk<=C;
elsif((R<"00100001")and(R>"00000001"))then--第1脉冲上升沿开始八分频
clk<=C;
elsif(R="00100001")then
clk<=D;
elsif((R<"01000001")and(R>"00100001"))then--第33脉冲上升沿开始四分频
clk<=D;
elsif(R="01000001")then
clk<=E;
elsif((R<"01100001")and(R>"01000001"))then--第65脉冲上升沿开始二分频
clk<=E;
elsif(R>="01100001")then--第97脉冲上升沿开始原频
clk<=sr_CLK;
endif;
endprocess;
enddiv;
三、仿真波形
1、当控制键kong为011时仿真波形为
2、当控制键kong为101时仿真波形为
3、当控制键kong为110时仿真波形为
4、当控制键kong为111时仿真波形为
四、遇到的问题
(1)在仿真时遇到分频出现重叠使波形不是完整的8、4分频,为什么?
答:
主要原因在于设置时脉冲个数未控制好。
(2)在波形仿真时出现一个三分频,为什么?
答:
应为二分频和厡频输出的叠加。
(3)原程序编译通过,功能仿真(Functional) 和时序仿真(Timing)都能出现,但最优仿真却出不来,为什么?
(Error:
Can'tcontinuetimingsimulationusingfasttimingmodelbecausedelayannotationinformationfordesignismissing)
第二模块:
分频部分
一、功能描述:
1、输入有两个:
档位键盘输入的档位信号dang:
instd-logic-vector(3downto0),是个四位的位型矢量;时钟信号clk。
dang键盘按“空、前一、前二、倒”为顺序,当某个键被按下则由“1”变为“0”,
不按下时保持“1”;
2输出有一个:
clkc初级时钟;
3功能:
(1)当dang为“0111”时为空挡,输出的clkc全为“0——“空”
(2)当dang为“1011”时为前一档,输出的clkc为clk一半频率的时钟;——“前一”
(3)当dang为“1101”时为前二档,输出的clkc为clk,不做任何处理;——“前二”
(4)当dang为“1110”时为倒档,输出和前一档的完全一样;——“倒”
(5)其他所有情况都和空挡完全一样。
二、程序:
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entitydangweiis
port(dang:
instd_logic_vector(3downto0);
clk:
instd_logic;
clkc:
outstd_logic);
endentity;
architecturearc_dangweiofdangweiis
signalcount:
std_logic:
='0';(定义count的初始值为低电平)
begin
process(clk)
begin
if(dang="1101")then
clkc<=clk;
elsif(clk'eventandclk='1')then
if(dang="1011"ordang="1110")then
count<=notcount;
clkc<=notcount;
else
clkc<='0';
endif;
endif;
endprocess;
endarc_dangwei;
三、仿真波形:
(1)dang=“1101”时的输出波形:
(2)dang=“1011”和“1110”时的输出波形:
(3)dang输出为“0000”时:
(4)整体输出波形:
<1>功能仿真波形
<2>时序仿真波形
四、操作过程中出现的问题
(1)有没有可行的语句来控制waituntilclk'eventandclk='1'的作用范围,可以让其在我们设想的范围内起作用,而不是控制整个process?
——编写程序的初衷是用case语句实现,并用waituntilclk'eventandclk='1'实现边沿触发,来达到二分频和对clkc赋值的操作,但是受边沿触发的影响,导致赋值操作时实际输出波形如下图示:
(2)程序仿真出现在时钟下降沿时钟信号不能控制输出波形的情况该如何解决?
——如图所示:
第三模块:
脉冲分配器部分
1、设计基本要求
脉冲分配器部分要控制的步进电机为两相,其中有三个输入clkz、dang、kong信号,有八个输出z0~z3、y0~y3信号,且z0~z3对应左电机(小车左轮),y0~y3对应右电机(小车右轮)。
将clkz分配为四个相互错开的进程内部信号signalV,并在dang、kong信号的作用下完成对步进电机不同工作方式的控制,进而实现对二轮小车运动方式的控制。
2、设计流程
设计脉冲分配器部分流程如下:
实体名:
fenpei(“分配”)
输入有三个:
clkz:
时钟信号
dang:
instd-logic-vector(3downto0),是个四位的位型矢量
kong:
instd-logic-vector(2downto0),是个三位的位型矢量
dang键盘按“空档、前进档一、前进档二、倒档”为顺序排列,当某个键被按下则由“1”变为“0”,不按下时保持“1”
kong键盘按“两轮都工作、仅左轮工作、仅右轮工作”为顺序排列,当某个键被按下则由“1”变为“0”,不按下时保持“1”
输出有八个:
输出到左轮(z)的z0、z1、z2、z3
输出到右轮(y)的y0、y1、y2、y3
功能说明:
首先将输入的clkz分配成四个信号v0、v1、v2、v3,用于电机驱动的错开的四相脉冲。
然后,
1.当dang为“1110”(倒档)条件下:
当kong为“011”时,将v0~v3分别赋给z0~z3,以及y0~y3;“左右轮都工作”
当kong为“101”时,将v0~v3只赋给z0~z3,y0~y3全赋零;“仅左轮工作”
当kong为“110”时,将v0~v3只赋给y0~y3,z0~z3全赋零;“仅右轮工作”
当kong为其他时,zl和yl均赋全零;“左右轮都不工作”
2.当dang为“1011”或“1101”(前进档1,前进档2)条件下:
当kong为“011”时,将v3~v0分别赋给z0~z3,以及y0~y3;“左右轮都工作”
当kong为“101”时,将v3~v0只赋给z0~z3,y0~y3全赋零;“仅左轮工作”
当kong为“110”时,将v3~v0只赋给y0~y3,z0~z3全赋零;“仅右轮工作”
当kong为其他时,z0~z3和y0~y3均赋全零;“左右轮都不工作”
3.当dang为其他时,z0~z3和y0~y3均赋全零;“左右轮都不工作”
3、设计方法
利用VHDL语言描述脉冲分配器,代码如下:
libraryieee;--包含库
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityfenpeiis--实体(fenpei)说明
port(
clkz:
instd_logic;--时钟输入
dang:
instd_logic_vector(3downto0);--车轮工作方式第一选择信号(4位键盘输入)
kong:
instd_logic_vector(2downto0);--车轮工作方式第二选择信号(3位键盘输入)
w:
outstd_logic_vector(3downto0);--4位控制信号输出
z3,z2,z1,z0,y3,y2,y1,y0:
outstd_logic);--左(z)右(y)车轮控制信号输出
endfenpei;
architecturearc_fenpeioffenpeiis--结构体说明
signalA:
std_logic_vector(1downto0);--定义内部信号
signalV:
std_logic_vector(3downto0);
begin
process(clkz)
begin
ifclkz'eventandclkz='1'then--时钟上升沿有效
if(A="11")then
A<="00";
else
A<=A+1;
endif;
endif;
caseAis
when"00"=>V<="0110";--产生周期序列0011
when"01"=>V<="0011";
when"10"=>V<="1001";
when"11"=>V<="1100";
endcase;
endprocess;
process(dang,kong,V)
begin
casedangis
when"1110"=>--倒档
ifkong="011"then--(倒档)左右轮都工作
z3<=V(3);
z2<=V
(2);
z1<=V
(1);
z0<=V(0);
y3<=V(3);
y2<=V
(2);
y1<=V
(1);
y0<=V(0);
elsifkong="101"then--(倒档)仅左轮工作
z3<=V(3);
z2<=V
(2);
z1<=V
(1);
z0<=V(0);
y3<='0';
y2<='0';
y1<='0';
y0<='0';
elsifkong="110"then--(倒档)仅右轮工作
z3<='0';
z2<='0';
z1<='0';
z0<='0';
y3<=V(3);
y2<=V
(2);
y1<=V
(1);
y0<=V(0);
else--(倒档)左右轮都不工作
z3<='0';
z2<='0';
z1<='0';
z0<='0';
y3<='0';
y2<='0';
y1<='0';
y0<='0';
endif;
when"1011"|"1101"=>--前进档1或前进档2
ifkong="011"then--(前进档)左右轮都工作
z3<=V(0);
z2<=V
(1);
z1<=V
(2);
z0<=V(3);
y3<=V(0);
y2<=V
(1);
y1<=V
(2);
y0<=V(3);
elsifkong="101"then--(前进档)仅左轮工作
z3<=V(0);
z2<=V
(1);
z1<=V
(2);
z0<=V(3);
y3<='0';
y2<='0';
y1<='0';
y0<='0';
elsifkong="110"then--(前进档)仅右轮工作
z3<='0';
z2<='0';
z1<='0';
z0<='0';
y3<=V(0);
y2<=V
(1);
y1<=V
(2);
y0<=V(3);
else--(前进档)左右轮都不工作
z3<='0';
z2<='0';
z1<='0';
z0<='0';
y3<='0';
y2<='0';
y1<='0';
y0<='0';
endif;
whenothers=>--其余档,左右轮都不工作
z3<='0';
z2<='0';
z1<='0';
z0<='0';
y3<='0';
y2<='0';
y1<='0';
y0<='0';
endcase;
endprocess;
w<=V;
endarc_fenpei;
4、仿真结果
下面是脉冲分配器部分功能仿真和时序仿真结果,各部分的功能见图中标示:
五、问题讨论
在脉冲分配模块的源程序中,当把控制信号输出z3~z0,y3~y0:
outstd_logic改为Z,Y:
outstd_logic_vector(3downto0)时,输出结果出错。
为什么?
六、结论
脉冲分配器部分使用VHDL语言设计了一种步进电机控制器。
根据仿真波形的分析,基本达到了设计初期的要求,能够完成步进电机在不同控制档位下工作模式的选择,实现了步进电机正转、反转、停止的要求,进而实现了对两轮小车的运动方式的控制。
Part3:
顶层设计及仿真
一、过程
顶层设计采用原理图输入。
先将各模块代码转换成顶层文件中可以调用的元件,并将生成的.bsf文件及.vhd文件复制到工程文件夹中。
在创建的.bdf文件中调用各个元件并连线、设定输入输出端口。
最后,编译,仿真。
这种设计方法结构清晰,输入方便,也更容易修改各模块间的逻辑关系。
二、遇到的问题
开始时只将.bsf文件复制在了工程文件夹中,在编译过程中出现了Error:
Nodeinstance""instantiatesundefinedentity",搜索后得知没有将.vhd文件放在工程中,导致错误。
改正后,编译通过。
最大的问题出现在仿真过程。
由于设计中涉及多级分频,为使总体仿真的波形较好的反映功能,必须经过仔细的计算和规划。
最终由于情况复杂,还是用了两次仿真才完全反映出预想的功能。
上图分为两大块,三个方框内是“前一”档的情况,分别为“两轮前进”、“只左轮前转”和“只右轮前转”;三个横线上方是“前二”档的情况,分别为“两轮前进”、“只左轮前转”和“只右轮前转”。
由图中可清晰的看出“前二档”的频率是“前一档”的频率的二倍,表明比“前一档”时运动地快。
上图是“前二档”和“倒”档的情况。
从图中可清晰地看出两种情况时,输出的波形顺序相反,从而实现了“倒”档功能。
Part4:
工作分布
李子龙(04083032)
组长,完成了设计的提出、论证、模块划分、工作分配、顶层设计及仿真(part3)以及各模块设计的指导;
李建堂(04083056)
完成了模块一(实体名fen)的设计、仿真、并且提出了问题3.
徐冉冉(04083111)
完成了模块二(实体名dangwei的设计、仿真和相应模块的问题的提出
张金鑫(04083030)
完成了模块三(实体名fenpei)中除“倒档”外的“空”、“前”“前二”功能部分的设计、调试、仿真、提出相关模块问题及总结
李昕(04083044)
完成了模块三(实体名fenpei)中“倒档”功能部分的描述及仿真;以及模块一中的问题1问题2的回答,并完成ppt的制作。
小车运动控制的VHDL描述设计
Workedby
徐冉冉(04083111)李子龙(04083032)
张金鑫(04083030)李建堂(04083056)
李昕(04083044)
Part1:
设计简介及背景知识
Part2:
各模块代码及详解
第一模块:
脉冲分频
第二模块:
分频部分
第三模块:
脉冲分配器部分
Part3:
顶层设计及仿真
Part4:
工作分布
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 小车 运动 控制 VHDL 描述 设计