多路生理信号数据采集模块设计_第1页
多路生理信号数据采集模块设计_第2页
多路生理信号数据采集模块设计_第3页
多路生理信号数据采集模块设计_第4页
多路生理信号数据采集模块设计_第5页
已阅读5页,还剩140页未读 继续免费阅读

下载本文档

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

文档简介

③RTL电路图图3.2.6系统原理图设计及引脚分配顶层模块硬件连线及引脚配置:《可编程逻辑设计课程设计》:三眼电图形刺激器设计(棋盘格)系统原理图设计及引脚分配图3.3.1RTL图图3.3.2仿真结果:图3.3.3硬件连线图图3.3.4《可编程逻辑设计课程设计》:三眼电图形刺激器设计(棋盘格)结果分析及心得体会硬件显示结果(部分)结果分析及心得体会由硬件实验结果可知,本次设计的眼电刺激图形满足实验要求,即每隔5S循环显示一种图形,颜色有黑白、红绿、蓝绿,图形形式有横竖条纹和方格,显示方式有全屏和半屏,共18种状态。本次实验做了很多前期准备,包括认真阅读相关文献、与同学进行讨论和交流等。并且在编写程序后多次修改优化,反复调试。在最初硬件显示调试时没有屏幕输出显示,检查程序并没有错,检查硬件时发现是由于硬件VGA端口有RGB各两个,而本设计实际使用为其中三个,引脚分配与硬件不相符导致结果无法正常显示,调换跳线帽位置后显示结果正确。总体来说本次课程设计过程曲折,但最终还是圆满地完成了任务,实现了了8x6的棋盘显示。通过此次课程设计,我收获颇丰。对于自己负责的课题,VGA的时序关系以及颜色成像的原理。同时,对于本次设计过程中帮助确定方案思路及硬件调试的组员王孜同学表示感谢。参考文献[1]《EDA技术与VHDL》第3版潘松,黄继业清华大学出版社2006.6[2]《EDA技术基础》实验指导书赵晓明[3]《基于FPGA的VGA显示模块设计》张亚平,贺占庄《可编程逻辑设计课程设计》:病房温度测控系统的设计病房温度测控系统的设计王孜重庆大学生物医学工程联合学院生物医学工程2班20106836设计要求(1)FPGA控制温度传感器对病房温度进行监控;(2)将检测的温度值实时显示在数码管上(十进制显示);(3)当温度值高于28度时,点亮FPGA主板LED1指示灯(模拟通知空调室降温),当温度值高于30度时,通过蜂鸣器发出间隔时间为1S的报警声,连续5声,点亮FPGA主板LED2。当温度值低于22度时,鸣器发出间隔时间为500MS的报警声,连续3声后点亮FPGA主板LED3指示灯(模拟通知空调室升温)。其余状态,LED4亮。(4)不同温度情况,用不同占空比PWM信号模拟电机调速。设计思路 为满足设计要求作出以下针对性设计:采用I2C接口的LM75A温度传感器采集温度;采用四位数码管将LM75A采集并由FPGA转换格式后的数据显示出来;将0~50度分为4个温度区间,分情况执行“要求”中的操作。为了便于实验,温度区间划分为:0~32,33~37,38~40,41~50。这样的话可以通过使用电烙铁加热芯片快速的观察实验效果。《可编程逻辑设计课程设计》:病房温度测控系统的设计所用硬件所用的硬件CycloneIV开发板1块红色LED5个LM75A1片按键1个数码管4位蜂鸣器1个 CycloneIV开发板EP4CE10E22C8是ALTER的CYCLONEIV四代FPGA器件,采用优化后的60nm工艺,降低了内核电压,和前一代相比,总功耗降低了25%,器件含有1万多个寄存器资源Altera新的Cyclone®IV系列FPGA器件巩固了Cyclone系列在低成本、低功耗FPGA市场的领导地位,并且目前提供集成收发器功能的型号。CycloneIV器件旨在用于大批量,成本敏感的应用,使系统设计师在降低成本的同时又能够满足不断增长的带宽要求。CycloneIV器件系列是建立在一个优化的低功耗工艺基础之上,并提供E和GX两种型号。CycloneIVE—最低的功耗,通过最低的成本实现较高的功能性。右表显示了所用器件的资源。LM75ALM75A是一个使用了内置带隙温度传感器和Σ-△模数转换技术的温度-数字转换器。它也是一个温度检测器,可提供一个过热检测输出。LM75A包含许多数据寄存器:配置寄存器(Conf),用来存储器件的某些配置,如器件的工作模式、OS工作模式、OS极性和OS故障队列等;温度寄存器(Temp),用来存储读取的数字温度;设定点寄存器(Tos&Thyst),用来存储可编程的过热关断和滞后限制,器件通过2线的串行I2C总线接口与控制器通信。LM75A还包含一个开漏输出(OS),当温度超过编程限制的值时该输出有效。LM75A有3个可选的逻辑地址管脚,使得同一总线上可同时连接8个器件而不发生地址冲突。LM75A可配置成不同的工作条件。它可设置成在正常工作模式下周期性地对环境温度进行监控或进入关断模式来将器件功耗降至最低。OS输出有2种可选的工作模式:OS比较器模式和OS中断模式。OS输出可选择高电平或低电平有效。故障队列和设定点限制可编程,为了激活OS输出,故障队列定义了许多连续的故障。温度寄存器通常存放着一个11位的二进制数的补码,用来实现0.125℃的精度。这个高精度在需要精确地测量温度偏移或超出限制范围的应用中非常有用。正常工作模式下,当器件上电时,OS工作在比较器模式,温度阈值为80℃,滞后75℃,这时,LM75A就可用作一个具有以上预定义温度设定点的独立的温度控制器。特性1.器件可以完全取代工业标准的LM75,并提供了良好的温度精度(0.125℃),单个器件的电源可超出2.8V~5.5V的范围。2.小型8脚封装:SO8和TSSOP8。3.具有I2C总线接口,同一总线上可连接多达8个器件。4.电源电压范围:2.8V~5.5V。5.温度范围:-55℃~+125℃。6.提供0.125℃的精度的11位的ADC。7.温度精度:-25℃~+100℃时为±2℃-55℃~+125℃时为±3℃8.可编程温度阈值和滞后设定点。9.为了降低功耗,关断模式下消耗的电流仅为3.5uA。10.上电时器件可用作一个独立的温度控制器。11.ESD保护:JESD22-A114为2000VHBM,JESD22-A115为200V和JESD22-C101为1000VCDM。12.超过100mA的JESDEC标准JESD78要进行栓锁测试(Latch-uptesting)。系统功能描述 按下rst按键,使系统复位到预定的状态。此时数码管显示”000C“,一段时间后,显示当前温度的整数值。 温度在33~37度LED4亮,为预设的正常温度,PWM驱动的LED中等亮度;温度在38~40度LED3亮,PWM驱动的LED中等亮度;温度在从40度以下进入到41度以上时,蜂鸣器以1s为间隔鸣叫5次,之后LED2点亮。PWM控制的LED高亮度;温度在从32度以上进入到31度以上时,蜂鸣器以500ms为间隔鸣叫3次,之后LED3点亮。PWM控制的LED低亮度;《可编程逻辑设计课程设计》:病房温度测控系统的设计系统模块系统模块如图,把系统的实现分成5个模块。分别为:LM75A,数码管,数据转换与处理,蜂鸣器,PWM。其中LM75A模块负责与温度传感器的接口,通过I2C获得温度数据。数据转换与处理模块是系统中功能最复杂的模块,负责4种温度状态的判断与转换。数码管模块负责将温度传感器的数据动态扫描显示在数码管上。蜂鸣器和PWM模块的功能与其命名相同。其中最难得一点是正确的实现蜂鸣器鸣叫和随后的LED点亮。温度过高提示时,蜂鸣器间隔1s响5次,之后点亮LED。要求从38~40度到41~50度温度时进行一次,也就是说,只有在40到41度变化之后才使蜂鸣器鸣叫,温度反向变化,或是停在41~50区间都不会使蜂鸣器鸣叫。换言之,要判断温度从40度变化到41度,只有唯一的经历这一过程才会使蜂鸣器鸣叫。温度过低的蜂鸣器警报也是如此。所以,除了编写4个温度区间的状态机外,要单独考虑过冷和过热的蜂鸣器警报。将上述内容图形化:蜂鸣器模块采用了状态机控制蜂鸣器在特定的时间间隔鸣叫,并且鸣叫后点亮LED。《可编程逻辑设计课程设计》:病房温度测控系统的设计仿真代码(见附录)仿真 因为使用的是QuartusII11.064-bit版本,没有仿真功能,所以借助第三方仿真工具ModelSimSE10.0c64-bit。 Modelsim介绍Mentor公司的ModelSim是业界最优秀的HDL语言仿真软件,它能提供友好的仿真环境,是业界唯一的单内核支持VHDL和Verilog混合仿真的仿真器。它采用直接优化的编译技术、Tcl/Tk技术、和单一内核仿真技术,编译仿真速度快,编译的代码与平台无关,便于保护IP核,个性化的图形界面和用户接口,为用户加快调错提供强有力的手段,是FPGA/ASIC设计的首选仿真软件。主要特点:·RTL和门级优化,本地编译结构,编译仿真速度快,跨平台跨版本仿真;·单内核VHDL和Verilog混合仿真;·源代码模版和助手,项目管理;·集成了性能分析、波形比较、代码覆盖、数据流ChaseX、SignalSpy、虚拟对象VirtualObject、Memory窗口、Assertion窗口、源码窗口显示信号值、信号条件断点等众多调试功能;·C和Tcl/Tk接口,C调试;·对SystemC的直接支持,和HDL任意混合;·支持SystemVerilog的设计功能;·对系统级描述语言的最全面支持,SystemVerilog,SystemC,PSL;·ASICSignoff。·可以单独或同时进行行为(behavioral)、RTL级、和门级(gate-level)的代码。ModelSim分几种不同的版本:SE、PE、LE和OEM,其中SE是最高级的版本,而集成在Actel、Atmel、Altera、Xilinx以及Lattice等FPGA厂商设计工具中的均是其OEM版本。SE版和OEM版在功能和性能方面有较大差别,比如对于大家都关心的仿真速度问题,以Xilinx公司提供的OEM版本ModelSimXE为例,对于代码少于40000行的设计,ModelSimSE比ModelSimXE要快10倍;对于代码超过40000行的设计,ModelSimSE要比ModelSimXE快近40倍。ModelSimSE支持PC、UNIX和LINUX混合平台;提供全面完善以及高性能的验证功能;全面支持业界广泛的标准;MentorGraphics公司提供业界最好的技术支持与服务。 使用ModelSim时发现,这个软件功能很强大,甚至提供断点功能,还有很多高级功能,比如Dataflow。由于我们做的工程比较简单,所以没有用到这些功能。在熟练地掌握这些软件并养成良好的工作习惯之前,这些软件并不能有效的提供帮助。这个工程是我第一次做的功能比较综合的FPGA,完全没有仿真,只是按照自己的思路加上电路板上的实验效果调试出来的。以后在做更复杂的工程时,会尝试进行仿真,提高效率。整个工程中,大概有三种功能型结构:1.时钟产生,即为分频;2.由case语句产生的状态机;3.由if语句组成的判断。所以相同功能的模块就不进行仿真了。以下是时序仿真结果:数码管动态扫描模块仿真命令:forceclk11,02–repeat2 Run@1000000使用四位共阴数码管,输入x”0123”,可以观察到位选信号和段码的改变,即动态显示的原理。时钟产生模块仿真命令:forceclk11,02–repeat2 Run–all Break数据转换与控制模块仿真命令:forceclk11,02–repeat2 用force设定某时间段datain的值,模拟从LM75获取数据 Run-all break PWM模块仿真命令:forceclk11,02–repeat2 用force设定某时间段dy的值,模拟从convert获取数据 Run-all break 可以看出pwm占空比的变化。《可编程逻辑设计课程设计》:病房温度测控系统的设计SignalTapII蜂鸣器模块仿真命令:forceclk11,02–repeat2 用force设定某时间段datain的值,模拟从LM75获取数据 Run-all break 可以看出蜂鸣器正确的鸣叫,而且在之后点亮LED。各温度区间LED点亮情况也正确。SignalTapII 主要使用SignalTapII观察系统整个系统和单独观察LM75模块。27C时36C时39C时44C时过热时蜂鸣器情况过冷时蜂鸣器情况LM75时序数据通信主机和LM75A之间的通信必须严格遵循I2C总线管理定义的规则。LM75A寄存器读/写操作的协议通过下列描述之后的各个图来说明:1.通信开始之前,I2C总线必须空闲或者不忙。这就意味着总线上的所有器件都必须释放SCL和SDA线,SCL和SDA线被总线的上拉电阻拉高。2.由主机来提供通信所需的SCL时钟脉冲。在连续的9个SCL时钟脉冲作用下,数据(8位的数据字节以及紧跟其后的1个应答状态位)被传输。3.在数据传输过程中,除起始和停止信号外,SDA信号必须保持稳定,而SCL信号必须为高。这就表明SDA信号只能在SCL为低时改变。4.S:起始信号,主机启动一次通信的信号,SCL为高电平,SDA从高电平变成低电平。5.RS:重复起始信号,与起始信号相同,用来启动一个写命令后的读命令。6.P:停止信号,主机停止一次通信的信号,SCL为高电平,SDA从低电平变成高电平。然后总线变成空闲状态。7.W:写位,在写命令中写/读位=0。8.R:读位,在读命令中写/读位=1。9.A:器件应答位,由LM75A返回。当器件正确工作时该位为0,否则为1。为了使器件获得SDA的控制权,这段时间内主机必须释放SDA线。10.A’:主机应答位,不是由器件返回,而是在读2字节的数据时由主控器或主机设置的。在这个时钟周期内,为了告知器件的第一个字节已经读走并要求器件将第二个字节放到总线上,主机必须将SDA线设为低电平。11.NA:非应答位。在这个时钟周期内,数据传输结束时器件和主机都必须释放SDA线,然后由主机产生停止信号。12.在写操作协议中,数据从主机发送到器件,由主机控制SDA线,但在器件将应答信号发送到总线的时钟周期内除外。13.在读操作协议中,数据由器件发送到总线上,在器件正在将数据发送到总线和控制SDA线的这段时间内,主机必须释放SDA线,但在主器件将应答信号发送到总线的时间周期内除外。电路原理图set_location_assignmentPIN_91-toclkset_location_assignmentPIN_25-torstset_location_assignmentPIN_142-toSCLKset_location_assignmentPIN_141-toSDAset_location_assignmentPIN_128-toweima[0]set_location_assignmentPIN_127-toweima[1]set_location_assignmentPIN_132-toweima[2]set_location_assignmentPIN_129-toweima[3]set_location_assignmentPIN_114-toduanma[0]set_location_assignmentPIN_115-toduanma[1]set_location_assignmentPIN_119-toduanma[2]set_location_assignmentPIN_120-toduanma[3]set_location_assignmentPIN_121-toduanma[4]set_location_assignmentPIN_124-toduanma[5]set_location_assignmentPIN_125-toduanma[6]《可编程逻辑设计课程设计》:病房温度测控系统的设计电路原理图set_location_assignmentPIN_126-toduanma[7]《可编程逻辑设计课程设计》:病房温度测控系统的设计总结总结 这是我做的第一个较为复杂的FPGA工程,因为缺少经验所以调试了挺久的。但是完成了之后还是学了很多,比如语法格式、状态机的写法、ModleSim的使用等。 在动手编写程序之前,更重要的是读懂题目的要求,将具体的功能实现转化为状态机。在这一步骤中,理清思路特别重要,最好可以在纸上推演一下,尽可能简化状态。比如AD采集程序中的核心部分的状态机,想清楚后可以简化为3个状态,空想的话在实验室调试了一个下午都没有结果。所以思路清晰很重要。 总的来说,当初初识FPGA的兴奋还没有消退。感觉单片机是编软件,FPGA是编写硬件,有完全不同的思路和风格。《可编程逻辑设计课程设计》附件:多路生理信号采集模块设计程序清单附件材料多路生理信号采集模块设计程序清单键盘扫描模块程序LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;USEIEEE.STD_LOGIC_UNSIGNED.ALL;ENTITYMATRIKEYSCANISPORT( CLK :INSTD_LOGIC;--50MHZ时钟 CLKOUT:OUTSTD_LOGIC;--1KHZOUTPUTNEXT COL :INSTD_LOGIC_VECTOR(3DOWNTO0);--LIESIGNAL ROW :OUTSTD_LOGIC_VECTOR(3DOWNTO0);--HANGSIGNAL KEYOUT :OUTSTD_LOGIC_VECTOR(3DOWNTO0);--MARKTHENUMBER PUTDOWN:OUTSTD_LOGIC);--PUTDOWN=1表示键盘输出值有效ENDMATRIKEYSCAN;ARCHITECTUREBEHAVEOFMATRIKEYSCANIS SIGNALROWREG:STD_LOGIC_VECTOR(3DOWNTO0); SIGNALCOLREG,COLREG0,COLREG1,COLREG2:STD_LOGIC_VECTOR(3DOWNTO0); SIGNALCON:STD_LOGIC_VECTOR(7DOWNTO0); SIGNALCNT:INTEGERRANGE0TO50000; SIGNALCLKREG:STD_LOGIC;--1KHZ时钟BEGINPROCESS(CLK)--50MHZCLK分频输出1KHZCLKREGBEGIN IFCLK'EVENTANDCLK='1'THEN IFCNT=49999THEN--49999 CNT<=0; CLKREG<='0'; ELSIFCNT=24999THEN--24,999 CNT<=CNT+1; CLKREG<='1'; ELSE CNT<=CNT+1; ENDIF; ENDIF;ENDPROCESS;CLKOUT<=CLKREG;PROCESS(CLKREG)--输出列信号,扫描键盘BEGIN IFCLKREG'EVENTANDCLKREG='1'THEN CASEROWREGIS WHEN"0001"=>ROWREG<="0010"; WHEN"0010"=>ROWREG<="0100"; WHEN"0100"=>ROWREG<="1000"; WHEN"1000"=>ROWREG<="0001"; WHENOTHERS=>ROWREG<="0001"; ENDCASE; ENDIF;ENDPROCESS; ROW<=ROWREG;--列信号输出 CON<=ROWREG&COL;PROCESS(CLKREG)--MARKTHENUMBERBEGIN IFCLKREG'EVENTANDCLKREG='1'THEN CASECONIS WHEN"10001000"=>KEYOUT<="0000";PUTDOWN<='1';--1 WHEN"01001000"=>KEYOUT<="0001";PUTDOWN<='1';--2 WHEN"00101000"=>KEYOUT<="0010";PUTDOWN<='1';--3 WHEN"00011000"=>KEYOUT<="0011";PUTDOWN<='1';--4 WHEN"10000100"=>KEYOUT<="0100";PUTDOWN<='1';--5 WHEN"01000100"=>KEYOUT<="0101";PUTDOWN<='1';--6 WHEN"00100100"=>KEYOUT<="0110";PUTDOWN<='1';--7 WHEN"00010100"=>KEYOUT<="0111";PUTDOWN<='1';--8 WHEN"10000010"=>KEYOUT<="1000";PUTDOWN<='1';--9 WHEN"01000010"=>KEYOUT<="1001";PUTDOWN<='1';--10 WHEN"00100010"=>KEYOUT<="1010";PUTDOWN<='1';--11 WHEN"00010010"=>KEYOUT<="1011";PUTDOWN<='1';--12 WHEN"10000001"=>KEYOUT<="1100";PUTDOWN<='1';--13 WHEN"01000001"=>KEYOUT<="1101";PUTDOWN<='1';--14 WHEN"00100001"=>KEYOUT<="1110";PUTDOWN<='1';--15 WHEN"00010001"=>KEYOUT<="1111";PUTDOWN<='1';--16 WHEN"00010000"=>PUTDOWN<='0'; WHEN"00100000"=>PUTDOWN<='0'; WHEN"01000000"=>PUTDOWN<='0'; WHEN"10000000"=>PUTDOWN<='0'; WHENOTHERS=>NULL; ENDCASE; ENDIF;ENDPROCESS;ENDBEHAVE;数码管显示模块程序LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;USEIEEE.STD_LOGIC_UNSIGNED.ALL;ENTITYDISPLAY_LEDISPORT(CLOCK:INSTD_LOGIC;--1KHZINPUTNUMIN:INSTD_LOGIC_VECTOR(3DOWNTO0);--MARKEDNUMBERST:INSTD_LOGIC;--0OR1EN:OUTSTD_LOGIC_VECTOR(7DOWNTO0);--WEIXUAND_OUT:OUTSTD_LOGIC_VECTOR(7DOWNTO0)--DUANXUAN);END;ARCHITECTURERTLOFDISPLAY_LEDISSIGNALCOUNTER:INTEGERRANGE0TO7;SIGNALNUMA:STD_LOGIC_VECTOR(3DOWNTO0);BEGINPROCESS(ST)BEGINIFRISING_EDGE(ST)THENNUMA(3DOWNTO0)<=NUMIN;ENDIF;ENDPROCESS; PROCESS(CLOCK) VARIABLENUM:STD_LOGIC_VECTOR(3DOWNTO0); BEGIN IFRISING_EDGE(CLOCK)THEN EN<="00000001"; IFCOUNTER>=7THEN--WEIXUANJISHU COUNTER<=0; ELSE COUNTER<=COUNTER+1; ENDIF; CASECOUNTERIS WHEN7=> NUM:=NUMA(3DOWNTO0); WHENOTHERS=> NUM:="0000"; ENDCASE; CASENUMIS--DUANXUANDISPLAY WHEN"0000"=>D_OUT<="00111111";--0 WHEN"0001"=>D_OUT<="00000110";--1 WHEN"0010"=>D_OUT<="01011011";--2 WHEN"0011"=>D_OUT<="01001111";--3 WHEN"0100"=>D_OUT<="01100110";--4 WHEN"0101"=>D_OUT<="01101101";--5 WHEN"0110"=>D_OUT<="01111101";--6 WHEN"0111"=>D_OUT<="00000111";--7 WHEN"1000"=>D_OUT<="01111111";--8 WHEN"1001"=>D_OUT<="01101111";--9 WHEN"1010"=>D_OUT<=X"77";--A WHEN"1011"=>D_OUT<=X"7C";--B WHEN"1100"=>D_OUT<=X"39";--C WHEN"1101"=>D_OUT<=X"5E";--D WHEN"1110"=>D_OUT<=X"79";--E WHEN"1111"=>D_OUT<=X"71";--F WHENOTHERS=>D_OUT<="00000000"; ENDCASE; ENDIF; ENDPROCESS; END;时钟分频模块程序LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;USEIEEE.STD_LOGIC_UNSIGNED.ALL;USEIEEE.STD_LOGIC_ARITH.ALL;ENTITYCLK_DIVISPORT(CLKIN:INSTD_LOGIC;FSEL:INSTD_LOGIC_VECTOR(3DOWNTO0);CLK_OUT_1,CLK_OUT_2:OUTSTD_LOGIC);END;ARCHITECTUREBEHAVEOFCLK_DIVISSIGNALCOUNTER_1:INTEGERRANGE0TO400;SIGNALCOUNTER_2:INTEGERRANGE0TO2500;SIGNALCLK_1,CLK_2:STD_LOGIC:='0';SIGNALFNUM:INTEGERRANGE0TO20;SIGNALNUM:INTEGERRANGE0TO400;BEGINPROCESS(FSEL)BEGINFNUM<=CONV_INTEGER(FSEL);--CONVERTTOINTEGERENDPROCESS;PROCESS(FNUM)--FENPINBEISHUBEGINCASEFNUMIS WHEN0=>NUM<=1; WHEN1=>NUM<=2; WHEN2=>NUM<=4; WHEN3=>NUM<=8; WHEN4=>NUM<=16; WHEN5=>NUM<=32; WHENOTHERS=>NUM<=4;ENDCASE;ENDPROCESS; PROCESS(CLKIN) BEGIN IFRISING_EDGE(CLKIN)THEN IFCOUNTER_1>=(330/NUM-1)THEN--330 COUNTER_1<=0;CLK_1<=NOTCLK_1; ELSECOUNTER_1<=COUNTER_1+1; ENDIF; ENDIF; ENDPROCESS;CLK_OUT_1<=CLK_1;PROCESS(CLKIN)--10KDIV BEGIN IFRISING_EDGE(CLKIN)THEN IFCOUNTER_2>=2499THEN--2499 COUNTER_2<=0;CLK_2<=NOTCLK_2; ELSECOUNTER_2<=COUNTER_2+1; ENDIF; ENDIF; ENDPROCESS; CLK_OUT_2<=CLK_2;END;AD时序产生模块程序LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;USEIEEE.STD_LOGIC_ARITH.ALL;USEIEEE.STD_LOGIC_UNSIGNED.ALL;ENTITYADS7822_TIME_CONTROLISPORT( CLK:INSTD_LOGIC; ADS7822_CS,ADS7822_SCLK_OUT:OUTSTD_LOGIC);END;ARCHITECTURERTLOFADS7822_TIME_CONTROLISTYPESTATESIS(IDLE,SCLK_STATE_1,SCLK_STATE_0,SCLK_STATE_3,CS_STATE_0,CS_STATE_1,CS_STATE_2);--定义各子状态SIGNALSTATE:STATES:=IDLE;SIGNALCNT:INTEGER:=0;SIGNALCNT2:INTEGER:=0;SIGNALCS,AD_SCLK:STD_LOGIC;BEGINADS7822_CS<=CS;ADS7822_SCLK_OUT<=AD_SCLK;PROCESS(CLK)BEGINIFRISING_EDGE(CLK)THENCASESTATEISWHENIDLE=> CS<='1';AD_SCLK<='0';CNT<=0; IFCNT2>2THEN STATE<=CS_STATE_0;CNT2<=0; ELSE CNT2<=CNT2+1;STATE<=IDLE; ENDIF; WHENSCLK_STATE_1=> AD_SCLK<='1';STATE<=CS_STATE_0; WHENCS_STATE_0=> CS<='0'; IFCNT>14THEN STATE<=CS_STATE_1; ELSE STATE<=SCLK_STATE_0; ENDIF; WHENSCLK_STATE_0=> AD_SCLK<='0';CNT<=CNT+1;STATE<=SCLK_STATE_3; WHENSCLK_STATE_3=> AD_SCLK<='0';CNT<=CNT;STATE<=SCLK_STATE_1; WHENCS_STATE_1=> AD_SCLK<='0'; IFCNT2>5THEN STATE<=CS_STATE_2;CNT2<=0; ELSE CNT2<=CNT2+1;STATE<=CS_STATE_1; ENDIF; WHENCS_STATE_2=> CS<='1';STATE<=IDLE; ENDCASE; ENDIF;ENDPROCESS;ENDRTL;AD转换模块程序 LIBRARYIEEE; USEIEEE.STD_LOGIC_1164.ALL; USEIEEE.STD_LOGIC_UNSIGNED.ALL; ENTITYSHIFT_AD_DATAIS PORT( CLK,CLK_CAP,AD_IN,CS:INSTD_LOGIC; AD_DATA:OUTSTD_LOGIC_VECTOR(11DOWNTO0)); END; ARCHITECTUREBEHAVEOFSHIFT_AD_DATAIS SIGNALAD_SIG:STD_LOGIC_VECTOR(14DOWNTO0); SIGNALAD_DATA_S:STD_LOGIC_VECTOR(11DOWNTO0); BEGINAD_DATA<=AD_DATA_S; PROCESS(CLK,AD_IN) BEGIN IFCLK'EVENTANDCLK='1'THEN AD_SIG(14)<=AD_IN; FORIIN1TO14LOOP AD_SIG(14-I)<=AD_SIG(15-I); ENDLOOP; ENDIF; ENDPROCESS; PROCESS(CLK_CAP,CS) BEGIN IFCLK_CAP'EVENTANDCLK_CAP='1'THEN IFCS='1'THEN AD_DATA_S<=AD_SIG(14DOWNTO3); ELSE AD_DATA_S<=AD_DATA_S; ENDIF; ENDIF; ENDPROCESS; ENDBEHAVE;存储地址控制模块程序LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;USEIEEE.STD_LOGIC_UNSIGNED.ALL;ENTITYSELISPORT( CS,RST:INSTD_LOGIC; KEYIN:INSTD_LOGIC; ST:OUTSTD_LOGIC_VECTOR(1DOWNTO0);--CHANNELMARK EN,A,B,C:OUTSTD_LOGIC; ADDRESS:OUTSTD_LOGIC_VECTOR(9DOWNTO0); LED,WEN:OUTSTD_LOGIC );ENDENTITYSEL;ARCHITECTURERTLOFSELISSIGNALSTREG:STD_LOGIC_VECTOR(1DOWNTO0);SIGNALADDREG:STD_LOGIC_VECTOR(9DOWNTO0);SIGNALRD,FLAG:STD_LOGIC;SIGNALSTATE:STD_LOGIC_VECTOR(1DOWNTO0);BEGINADDRESS<=ADDREG;--DATAADDRESSWEN<=FLAG;--I/OENABLEST<=STREG;--CHANNELMARKPROCESS(ADDREG,RST)BEGIN IFRST='0'THEN STATE<="00"; ELSIF((ADDREG="0000011111")AND(FLAG='1')AND(STATE="00"))THEN--(ADDREG="1111111111") STATE<="01"; ELSIF(KEYIN='0'ANDSTATE="01")THEN STATE<="10"; ENDIF;ENDPROCESS;PROCESS(CS,STATE,RST)--CASE_SWITCHBEGINIFRST='0'THEN ADDREG<="0000000000"; STREG<="00"; LED<='1'; FLAG<='1';--WENELSIFRISING_EDGE(CS)THEN CASESTATEIS WHEN"00"=> STREG<=STREG+1; FLAG<='1'; LED<='1'; ADDREG<=ADDREG+1;--INPUT WHEN"01"=> ADDREG<="0000000000"; FLAG<='0'; LED<='0';--STOPTOWAIT WHEN"10"=> ADDREG<=ADDREG+1; FLAG<='0'; LED<='1';--OUTPUT WHENOTHERS=>NULL; ENDCASE;ENDIF;ENDPROCESS;PROCESS(STREG)--CHANNALMARKAUTORETURNBEGINCASESTREGIS WHEN"00"=>EN<='0';C<='0';B<='0';A<='0'; WHEN"01"=>EN<='0';C<='0';B<='0';A<='1'; WHEN"10"=>EN<='0';C<='0';B<='1';A<='0'; WHEN"11"=>EN<='0';C<='0';B<='1';A<='1'; WHENOTHERS=>NULL;ENDCASE;ENDPROCESS;ENDARCHITECTURERTL;数据合并模块程序LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;USEIEEE.STD_LOGIC_UNSIGNED.ALL;ENTITYCOMBIS--MERGETHEDATASIGNAL&STATEMARKPORT( CLK:INSTD_LOGIC; DATAH:INSTD_LOGIC_VECTOR(1DOWNTO0); DATAL:INSTD_LOGIC_VECTOR(11DOWNTO0); DATACOMB:OUTSTD_LOGIC_VECTOR(15DOWNTO0); DATARAW:OUTSTD_LOGIC_VECTOR(11DOWNTO0) );ENDENTITYCOMB;ARCHITECTURERTLOFCOMBISSIGNALDATAREG:STD_LOGIC_VECTOR(15DOWNTO0);SIGNALDATAHREG:STD_LOGIC_VECTOR(1DOWNTO0);SIGNALDATALREG:STD_LOGIC_VECTOR(11DOWNTO0);BEGINDATAHREG<=DATAH;DATALREG<=DATAL;DATARAW<=DATAL;--DIRECTLYPASSFOROBSERVATIONDATAREG<="00"&DATAHREG&DATALREG;DATACOMB<=DATAREG;ENDARCHITECTURERTL;数据分离模块程序LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;USEIEEE.STD_LOGIC_UNSIGNED.ALL;ENTITYCONVIS--SEPARATETHESIGNALPORT( CLK:INSTD_LOGIC; DATAIN:INSTD_LOGIC_VECTOR(15DOWNTO0);--RAMOUTPUT SEL:OUTSTD_LOGIC_VECTOR(1DOWNTO0);--SIGNALMARK CH1:OUTSTD_LOGIC_VECTOR(11DOWNTO0); CH2:OUTSTD_LOGIC_VECTOR(11DOWNTO0); CH3:OUTSTD_LOGIC_VECTOR(11DOWNTO0); CH4:OUTSTD_LOGIC_VECTOR(11DOWNTO0) );ENDENTITYCONV;ARCHITECTURERTLOFCONVISSIGNALST:STD_LOGIC_VECTOR(1DOWNTO0);SIGNALCHREG:STD_LOGIC_VECTOR(11DOWNTO0);BEGINST<=DATAIN(13DOWNTO12);SEL<=ST;CHREG<=DATAIN(11DOWNTO0);PROCESS(CLK,ST)BEGINIFRISING_EDGE(CLK)THEN CASESTIS WHEN"00"=>CH4<=CHREG; WHEN"01"=>CH1<=CHREG; WHEN"10"=>CH2<=CHREG; WHEN"11"=>CH3<=CHREG; WHENOTHERS=>NULL;ENDCASE;ENDIF;ENDPROCESS;ENDARCHITECTURERTL;《可编程逻辑设计课程设计》附件:多路生理信号采集模块设计系统顶层设计图系统顶层设计图《可编程逻辑设计课程设计》附件:多路生理信号采集模块设计原理电路图原理电路图《可编程逻辑设计课程设计》附件:多路生理信号采集模块设计RTL视图RTL视图键盘扫描模块RTL时钟分频模块RTL存储地址控制模块RTL数据合并模块RTL数据分离模块RTL《可编程逻辑设计课程设计》附件:异步串行接口电路及数据传输模块设计程序清单

异步串行接口电路及数据传输模块设计UART模块LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;USEIEEE.STD_LOGIC_ARITH.ALL;USEIEEE.STD_LOGIC_UNSIGNED.ALL;ENTITYUARTISPORT(CLK:INSTD_LOGIC;--系统时钟50MHZRST:INSTD_LOGIC;--系统复位RXD:INSTD_LOGIC;--串行数据接收端 ROMIN:INSTD_LOGIC_VECTOR(7DOWNTO0);--中间传送的并行数据TXD:OUTSTD_LOGIC;--串行数据发送端EN:OUTSTD_LOGIC_VECTOR(3DOWNTO0);--数码管使能SEG_DATA:OUTSTD_LOGIC_VECTOR(7DOWNTO0);--数码管7段码 ROMADD:OUTSTD_LOGIC_VECTOR(7DOWNTO0);KEY_INPUT:INSTD_LOGIC);--按键输入ENDUART;ARCHITECTUREARCHOFUARTIS--//////////////////INNERREG////////////////////SIGNALDIV_REG:STD_LOGIC_VECTOR(15DOWNTO0);--分频计数器,分频值由波特率决定。分频后得到频率为16倍波特率的时钟SIGNALDIV16_TRAS_REG:STD_LOGIC_VECTOR(3DOWNTO0);--该寄存器的计数值对应发送时当前位于的时隙数SIGNALDIV16_REC_REG:STD_LOGIC_VECTOR(3DOWNTO0);--寄存器的计数值对应接收时当前位于的时隙数SIGNALSTATE_TRAS:STD_LOGIC_VECTOR(3DOWNTO0);--发送状态寄存器SIGNALSTATE_REC:STD_LOGIC_VECTOR(3DOWNTO0);--接受状态寄存器SIGNALCLKBAUD_TRAS:STD_LOGIC;--以波特率为频率的发送使能信号SIGNALCLKBAUD_REC:STD_LOGIC;--以波特率为频率的接受使能信号SIGNALCLKBAUD16X:STD_LOGIC;--以16倍波特率为频率的时钟,它的作用是将发送或接受一个BIT的时钟周期分为16个时隙SIGNALRECSTART:STD_LOGIC;--开始发送标志SIGNALRECSTART_TMP:STD_LOGIC;--开始接受标志SIGNALTRASSTART:STD_LOGIC;--发送开始标志(开始发送一帧)SIGNALRXD_REG1:STD_LOGIC;--接收寄存器1SIGNALTXD_REG:STD_LOGIC;--发送寄存器SIGNALRXD_BUF:STD_LOGIC_VECTOR(7DOWNTO0);--接收数据缓存SIGNALTXD_BUF:STD_LOGIC_VECTOR(7DOWNTO0);--发送数据缓存SIGNALSEND_STATE:STD_LOGIC;--发送状态寄存器SIGNALCNT_DELAY:STD_LOGIC_VECTOR(19DOWNTO0);--延时去抖计数器SIGNALSTART_DELAYCNT:STD_LOGIC;--开始延时计数标志SIGNALKEY_ENTRY1:STD_LOGIC;--确定有键按下标志SIGNALKEY_ENTRY2:STD_LOGIC;--确定有键按下标志SIGNALKEY_UP:STD_LOGIC;SIGNALADDREG:STD_LOGIC_VECTOR(7DOWNTO0);--ROM存储地址SIGNALRXREG:STD_LOGIC_VECTOR(3DOWNTO0);CONSTANTDIV_PAR:STD_LOGIC_VECTOR(15DOWNTO0):="0000000010100011";--325--分频参数,其值由对应的波特率计算而得,按此参数分频的时钟频率是波特率的16倍,此处值对应9600的波特率,即分频出的时钟频率是9600*16 SIGNALTXD_XHDL3:STD_LOGIC;BEGINEN<="0001";--7段数码管使能信号赋值TXD<=TXD_XHDL3;TXD_XHDL3<=TXD_REG; ROMADD<=ADDREG;PROCESS(CLK,RST)--延时去抖16MSBEGINIF(NOTRST='1')THENCNT_DELAY<="00000000000000000000";--延时去抖计数器START_DELAYCNT<='0';--开始延时计数标志 KEY_UP<='1';ELSIF(CLK'EVENTANDCLK='1')THENIF(START_DELAYCNT='1')THENIF(CNT_DELAY/="11000011010100000000")THEN--800000CNT_DELAY<=CNT_DELAY+"00000000000000000001";ELSECNT_DELAY<="00000000000000000000";START_DELAYCNT<='0';ENDIF;ELSE--IF((NOTKEY_INPUT='1')AND(CNT_DELAY="00000000000000000000"))THEN--按键按下开始计时IF((KEY_UP='1')AND(NOTKEY_INPUT='1'))THEN KEY_UP<='0'; ELSIF((KEY_UP='0')AND(KEY_INPUT='1'))THEN START_DELAYCNT<='1'; KEY_UP<='1';ENDIF;ENDIF;ENDIF;ENDPROCESS;PROCESS(CLK,RST)--按键BEGINIF(NOTRST='1')THENKEY_ENTRY1<='0';ELSIF(CLK'EVENTANDCLK='1')THENIF(KEY_ENTRY2='1')THENKEY_ENTRY1<='0';ELSEIF(CNT_DELAY="11000011010100000000")THEN--IF(NOTKEY_INPUT='1')THEN--判断按键确实按下 IF(KEY_INPUT='1')THEN--判断按键确实弹起KEY_ENTRY1<='1';ENDIF;ENDIF;ENDIF;ENDIF;ENDPROCESS;PROCESS(CLK,RST)--计数值162则DIV_REG清零BEGINIF(NOTRST='1')THENDIV_REG<="0000000000000000";ELSIF(CLK'EVENTANDCLK='1')THENIF(DIV_REG=DIV_PAR-"0000000000000001")THENDIV_REG<="0000000000000000";ELSEDIV_REG<=DIV_REG+"0000000000000001";ENDIF;ENDIF;ENDPROCESS;PROCESS(CLK,RST)--分频得到16倍波特率的时钟=50M/(163*2)BEGINIF(NOTRST='1')THENCLKBAUD16X<='0';ELSIF(CLK'EVENTANDCLK='1')THENIF(DIV_REG=DIV_PAR-"0000000000000001")THENCLKBAUD16X<=NOTCLKBAUD16X;--DIV_REG计数值162则反转ENDIF;ENDIF;ENDPROCESS;PROCESS(CLKBAUD16X,RST,RECSTART)--判断接收条件,产生接收16位的频率BEGINIF(NOTRST='1')THENDIV16_REC_REG<="0000";ELSEIF(CLKBAUD16X'EVENTANDCLKBAUD16X='1')THENIF(RECSTART='1')THEN--接收开始标志DIV16_REC_REG<=DIV16_REC_REG+"0001";--接收开始后,时隙数在16倍波特率的时钟下加1循环ENDIF; ENDIF;ENDIF;ENDPROCESS;PROCESS(CLKBAUD16X,RST)--判断发送条件BEGINIF(NOTRST='1')THENDIV16_TRAS_REG<="0000";K,ELSEIF(CLKBAUD16X'EVENTANDCLKBAUD16X='1')THENIF(TRASSTART='1')THENDIV16_TRAS_REG<=DIV16_TRAS_REG+"0001";--发送开始后,时隙数在16倍波特率的时钟下加1循环ENDIF; ENDIF;ENDIF;ENDPROCESS;PROCESS(DIV16_REC_REG)--接收使能BEGINIF(DIV16_REC_REG="1111")THENCLKBAUD_REC<='1';在第16个时隙,接收使能信号有效,将数据打入ELSECLKBAUD_REC<='0';ENDIF;ENDPROCESS;PROCESS(DIV16_TRAS_REG)--发送使能BEGINIF(DIV16_TRAS_REG="1111")THENCLKBAUD_TRAS<='1';--在第16个时隙,发送使能信号有效,将数据发出ELSECLKBAUD_TRAS<='0';ENDIF;ENDPROCESS;PROCESS(CLKBAUD16X,RST)--发送BEGINIF(NOTRST='1')THENTXD_REG<='1';--发送寄存器TRASSTART<='0';--开始发送标志TXD_BUF<="00000000";--发送数据缓存STATE_TRAS<="0000";--发送状态寄存器SEND_STATE<='1';--发送状态寄存器KEY_ENTRY2<='0';--确定有键按下标志 ADDREG<="00000000"; ELSEIF(CLKBAUD16X'EVENTANDCLKBAUD16X='1')THENIF(NOTKEY_ENTRY2='1')THEN--KEY_ENTRY2=1开始发送IF(KEY_ENTRY1='1')THENKEY_ENTRY2<='1';--TXD_BUF<="00110010";--"2" TXD_BUF<=ROMIN;ADDREG<=ADDREG+1;ENDIF;ELSECASESTATE_TRASISWHEN"0000"=>--发送启动位IF((NOTTRASSTART='1')AND(SEND_STATE='1'))THENTRASSTART<='1';--开始发送状态ELSEIF(SEND_STATE='1')THENIF(CLKBAUD_TRAS='1')THEN--以波特率为频率的发送使能信号TXD_REG<='0';--起始位STATE_TRAS<=STATE_TRAS+"0001";ENDIF;ELSEKEY_ENTRY2<='0';STATE_TRAS<="0000"; SEND_STATE<='1'; ENDIF;ENDIF;WHEN"0001"=>--发送第1位IF(CLKBAUD_TRAS='1')THENTXD_REG<=TXD_BUF(0);TXD_BUF(6DOWNTO0)<=TXD_BUF(7DOWNTO1);STATE_TRAS<=STATE_TRAS+"0001";ENDIF;WHEN"0010"=>--发送第2位IF(CLKBAUD_TRAS='1')THENTXD_REG<=TXD_BUF(0);TXD_BUF(6DOWNTO0)<=TXD_BUF(7DOWNTO1);STATE_TRAS<=STATE_TRAS+"0001";ENDIF;WHEN"0011"=>--发送第3位IF(CLKBAUD_TRAS='1')THENTXD_REG<=TXD_BUF(0);TXD_BUF(6DOWNTO0)<=TXD_BUF(7DOWNTO1);STATE_TRAS<=STATE_TRAS+"0001";ENDIF;WHEN"0100"=>--发送第4位IF(CLKBAUD_TRAS='1')THENTXD_REG<=TXD_BUF(0);TXD_BUF(6DOWNTO0)<=TXD_BUF(7DOWNTO1);STATE_TRAS<=STATE_TRAS+"0001";

温馨提示

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

最新文档

评论

0/150

提交评论