当前位置:首页 > 电源 > 数字电源
[导读]  时间等于金钱。随着科技的不断发展,人们越来越追求高效率,讨厌把时间花在一些排队的事情上。电子信息技术的发展,改变了原始呆板固化的排队等候方式,转变为基于FPGA

  时间等于金钱。随着科技的不断发展,人们越来越追求高效率,讨厌把时间花在一些排队的事情上。电子信息技术的发展,改变了原始呆板固化的排队等候方式,转变为基于FPGAGSM排号系统的舒适、休闲的等候方式,人们不仅可以自由安排等待时间,而且可以轻松的享受其他服务,这方式不仅提高了业务员的工作效率,也提高了其业务素质。以下详细介绍了我们这个系统的设计。

  一、设计目的与要求

  目的:建设了一套由FPGA、微机与GSM模块的通信系统,基于此种架设的系统来实现远程的排队叫号。在一定条件下由系统向指定号码发送请求,再由FPGA处理请求,在适宜时间协助服务提供者完成服务项目。在此过程中,FPGA为该系统的主要中心,GSM协助其实现功能。

  要求:

  1、患者向护士提交个人手机号码,护士给予患者相关排号的号码(例如号码是10号)。(扩展:患者不用去医院护士站利用网络也能提前提交申请服务,即提前叫号)。

  2、护士将登记的患者手机号码输入微机系统,完成排号登记。

  3、医生每完成一个患者的服务后,护士就点击相关按钮。系统自动完成以下任务:

  若下一个患者是第7号,则系统利用语音和LCD显示屏提示第7号患者前来服务。同时GSM发送相关信息给第10号患者,提醒其做好准备。(具体是否安排第10或第11号患者,可由系统设定)。

  二、系统方案与框图

  从电脑输入患者的手机号码,数据通过串口经电平转换,传给FPGA,然后由FPGA储存到存储器,FPGA返回患者一个排号给电脑;当医生接诊完一个病人后,按一下next按钮,FPGA控制LED点阵显示滚动消息,提示某某号病人前去就诊,同时控制语音模块和喇叭通知这位病人,并且读取储存器中的数据送到GSM短信模块,使其发短信通知后面正在等待的某位病人做好准备。系统框图如下:

 

  四、模块设计

  1、PC与FPGA通信

  PC方面,利用Visual C++ 6.0创建一个MFC应用程序,加入MSComm控件,在应用程序框架中添加要实现的功能的代码,设置合适的参数,即可实现串口通信。首先用MFC AppWizard(exe)建立一个基于对话框的应用程序界面,添加所需控件,设置控件ID,接着用“建立类导向”建立各个控件的函数。结果如下图所示:  

 

  在VC++生成的应用程序框架下添加串口初始化函数的代码:

  BOOL CPC_FPGADlg::OnInitDialog()

  {

  CDialog::OnInitDialog(); // Add "About..." menu item to system menu.

  // IDM_ABOUTBOX must be in the system command range.

  ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);

  ASSERT(IDM_ABOUTBOX < 0xF000);

  CMenu* pSysMenu = GetSystemMenu(FALSE);

  if (pSysMenu != NULL)

  {

  CString strAboutMenu;

  strAboutMenu.LoadString(IDS_ABOUTBOX);

  if (!strAboutMenu.IsEmpty())

  {

  pSysMenu->AppendMenu(MF_SEPARATOR); SysMenu->AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu);

  }

  }

  // Set the icon for this dialog. The framework does this automatically

  // when the application's main window is not a dialog

  SetIcon(m_hIcon, TRUE); // Set big icon

  SetIcon(m_hIcon, FALSE); // Set small icon

  // TODO: Add extra initialization here //以上是VC++自动生成的代码

  if(m_ctrlComm.GetPortOpen())//如果串口已经打开

  m_ctrlComm.SetPortOpen(FALSE);//不再重新打开

  m_ctrlComm.SetCommPort(1); //选择COM1口

  if( !m_ctrlComm.GetPortOpen())//如果串口没打开

  m_ctrlComm.SetPortOpen(TRUE);//打开串口

  else

  AfxMessageBox("无法打开串口!");//弹出提示消息

  m_ctrlComm.SetSettings("9600,n,8,1"); //波特率9600,无校验位,8个数据位,1个停止位

  m_ctrlComm.SetInputMode(1); //“1”表示以二进制方式接收数据

  m_ctrlComm.SetRThreshold(1); //“1”表示每当接收接收到一个字节时将引发一个接收数据的OnComm事件

  m_ctrlComm.SetInputLen(0); //“0”表示设置读取缓冲区全部数据

  m_ctrlComm.GetInput();//初始化时读缓冲区以清除数据

  return TRUE; // return TRUE unless you set the focus to a control

  }

  下面是产生OnComm事件后接收数据的代码:

  void CFC_FPGADlg::OnComm()

  {

  // TODO: Add your control notification handler code here

  m_strPaihao=" ";

  VARIANT variant_inp;//定义VARIANT型变量

  COleSafeArray safearray_inp;//定义COleSafeArray类实例

  LONG len,k;

  BYTE rxdata[2048]; //设置BYTE数组

  CString strtemp;//临时变量

  if(m_ctrlComm.GetCommEvent()==2) //事件值为2表示接收缓冲区内有字符

  {

  variant_inp=m_ctrlComm.GetInput(); //读缓冲区

  safearray_inp=variant_inp; //VARIANT型变量转换为ColeSafeArray型变量

  len=safearray_inp.GetOneDimSize(); //得到有效数据长度

  for(k=0;k

  safearray_inp.GetElement(&k,rxdata+k);//转换为BYTE型数组

  for(k=0;k

  {

  BYTE bt=*(char*)(rxdata+k); //字符型

  strtemp.Format("%c",bt); //将字符送入临时变量strtemp存放

  m_strPaihao=m_strPaihao+strtemp; //在编辑框显示排号

  }

  }

  UpdateData(FALSE); //更新编辑框内容

  }

  “确定” 按钮的实现代码:

  void CPC_FPGADlg::OnOK()

  {

  // TODO: Add your control notification handler code here

  m_strComm.SetOutput(COleVariant(m_strNum));//发送手机号

  }

 

  “清除”按钮的实现代码:

  void CPC_FPGADlg::OnClear()

  {

  // TODO: Add your control notification handler code here

  m_strNum = _T("");//清除手机号

  m_strPaihao = _T("");//清除排号

  }

  BEGIN_EVENTSINK_MAP(CPC_FPGADlg, CDialog)

  //{{AFX_EVENTSINK_MAP(CPC_FPGADlg)

  ON_EVENT(CPC_FPGADlg, IDC_MSCOMM1, 1 /* OnComm */, OnOnComm, VTS_NONE)

  //}}AFX_EVENTSINK_MAP

  END_EVENTSINK_MAP()

  程序的界面如下:

 

  FPGA方面的代码如下:

  LIBRARY IEEE;

  USE IEEE.STD_LOGIC_1164.ALL;

  USE IEEE.STD_LOGIC_UNSIGNED.ALL;

  ENTITY PC_FPGA IS

  PORT(CLK:IN STD_LOGIC;--波特率系数为16,采样时钟CLK=153600Hz

  RXD:IN STD_LOGIC;--模拟RXD

  TXD:OUT STD_LOGIC;--模拟TXD

  OE:OUT STD_LOGIC;--储存器输出使能

  CE:OUT STD_LOGIC;--储存器片选

  WE:OUT STD_LOGIC;--储存器写使能

  PH:OUT STD_LOGIC_VECTOR(7 DOWNTO 0); --排号数据

  PHH:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);--高位排号数据

  PHL:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);--低位排号数据

  A:OUT STD_LOGIC_VECTOR(12 DOWNTO 0);--储存器地址

  IO:INOUT STD_LOGIC_VECTOR(7 DOWNTO 0));--储存器数据线

  END PC_FPGA;

  ARCHITECTURE BHV OF PC_FPGA IS

  TYPE STS IS(S0,S1,S2,S3,S4,S5,S6,S7,S8,S9,S10,S11,S12,S13,S14,S15,S16,S17,S18);

  SIGNAL PST:STS;

  SIGNAL NUMH:STD_LOGIC_VECTOR(3 DOWNTO 0);--返回号码十位

  SIGNAL NUML:STD_LOGIC_VECTOR(3 DOWNTO 0);--返回号码个位

  SIGNAL CNTBR:INTEGER RANGE 0 TO 15;--波特率系数16

  SIGNAL CNTBYTE:INTEGER RANGE 0 TO 6;--计算收到的字节数

  SIGNAL T_T:STD_LOGIC;--发送寄存器

  SIGNAL TEMP:STD_LOGIC_VECTOR(7 DOWNTO 0);--接收数据暂存

  SIGNAL ADDR:STD_LOGIC_VECTOR(12 DOWNTO 0);--储存器地址

  BEGIN

  IO<=TEMP;A<=ADDR;TXD<=T_T;PHH<=NUMH; PHL<=NUML;PH<= NUMH& NUML;

  PROCESS(CLK,RXD) BEGIN

  IF CLK'EVENT AND CLK='1' THEN

  CASE PST IS

  WHEN S0=>OE<='1';CE<='1';WE<='1';T_T<='1';

  IF RXD='0' THEN --S0:空闲

  IF CNTBR=8 THEN

  CNTBR<=0;PST<=S1;--检测到起始位

  ELSE CNTBR<=CNTBR+1;

  END IF;

  ELSE PST<=S0;

  END IF;

  WHEN S1=>OE<='1';CE<='1';WE<='1';

  IF CNTBR=15 THEN TEMP(0)<=RXD;CNTBR<=0;PST<=S2;--接收LSB

  ELSE CNTBR<=CNTBR+1;PST<=S1;

  END IF;

  WHEN S2=>OE<='1';CE<='1';WE<='1';

  IF CNTBR=15 THEN TEMP(1)<=RXD;CNTBR<=0;PST<=S3;--接收第2位

  ELSE CNTBR<=CNTBR+1;PST<=S2;

  END IF;

  WHEN S3=>OE<='1';CE<='1';WE<='1';

  IF CNTBR=15 THEN TEMP(2)<=RXD;CNTBR<=0;PST<=S4;--接收第3位

  ELSE CNTBR<=CNTBR+1;PST<=S4;

  END IF;

  WHEN S4=>OE<='1';CE<='1';WE<='1';

  IF CNTBR=15 THEN TEMP(3)<=RXD;CNTBR<=0;PST<=S5;--接收第4位

  ELSE CNTBR<=CNTBR+1;PST<=S5;

  END IF;

  WHEN S5=>OE<='1';CE<='1';WE<='1';

  IF CNTBR=15 THEN TEMP(4)<=RXD;CNTBR<=0;PST<=S6;--接收第5位

  ELSE CNTBR<=CNTBR+1;PST<=S6;

  END IF;

  WHEN S6=>OE<='1';CE<='1';WE<='1';

  IF CNTBR=15 THEN TEMP(5)<=RXD;CNTBR<=0;PST<=S7;--接收第6位

  ELSE CNTBR<=CNTBR+1;PST<=S7;

  END IF;

  WHEN S7=>OE<='1';CE<='1';WE<='1';

  IF CNTBR=15 THEN TEMP(6)<=RXD;CNTBR<=0;PST<=S8;--接收第7位

  ELSE CNTBR<=CNTBR+1;

  END IF;

  WHEN S8=>OE<='1';CE<='0';WE<='0';--片选使能,写使能

  IF CNTBR=15 THEN TEMP(7)<=RXD;CNTBR<=0;PST<=S9;--接收MSB

  ELSE CNTBR<=CNTBR+1;PST<=S8;

  END IF;

  WHEN S9=>OE<='1';CE<='1';WE<='1';PST<=S10;--WE上升沿锁存数据

  WHEN S10=>OE<='1';CE<='1';WE<='1';ADDR<=ADDR+1;--地址+1

  IF CNTBYTE=6 THEN CNTBYTE<=0;PST<=S11;T_T<='0';

  IF NUML=9 THEN NUML<="0000";

  IF NUMH=9 THEN NUMH<="0000";

  ELSE NUMH<=NUMH+1;

  END IF;

  ELSE NUML<=NUML+1;--接收到完整手机号排号+1

  END IF;

  ELSE CNTBYTE<=CNTBYTE+1;PST<=S0;--未接收到完整手机号

  END IF;

  WHEN S11=>OE<='1';CE<='1';WE<='1';PST<=S0;

  IF CNTBR=15 THEN T_T<=NUML(0);CNTBR<=0;PST<=S12;--发送LSB

  ELSE CNTBR<=CNTBR+1;PST<=S11;

  END IF;

  WHEN S12=>OE<='1';CE<='1';WE<='1';PST<=S0;

  IF CNTBR=15 THEN T_T<=NUML(1);CNTBR<=0;PST<=S13;--发送第2位

  ELSE CNTBR<=CNTBR+1;PST<=S12;

  END IF;

  WHEN S13=>OE<='1';CE<='1';WE<='1';PST<=S0;

  IF CNTBR=15 THEN T_T<=NUML(2);CNTBR<=0;PST<=S14;--发送第3位

  ELSE CNTBR<=CNTBR+1;PST<=S13;

  END IF;

  WHEN S14=>OE<='1';CE<='1';WE<='1';PST<=S0;

  IF CNTBR=15 THEN T_T<=NUML(3);CNTBR<=0;PST<=S15;--发送第4位[!--empirenews.page--]

  ELSE CNTBR<=CNTBR+1;PST<=S14;

  END IF;

  WHEN S15=>OE<='1';CE<='1';WE<='1';PST<=S0;

  IF CNTBR=15 THEN T_T<=NUMH(0);CNTBR<=0;PST<=S16;--发送第5位

  ELSE CNTBR<=CNTBR+1;PST<=S15;

  END IF;

  WHEN S16=>OE<='1';CE<='1';WE<='1';PST<=S0;

  IF CNTBR=15 THEN T_T<=NUMH(1);CNTBR<=0;PST<=S17;--发送第6位

  ELSE CNTBR<=CNTBR+1;PST<=S16;

  END IF;

  WHEN S17=>OE<='1';CE<='1';WE<='1';PST<=S0;

  IF CNTBR=15 THEN T_T<=NUMH(2);CNTBR<=0;PST<=S18;--发送第7位

  ELSE CNTBR<=CNTBR+1;PST<=S17;

  END IF;

  WHEN S18=>OE<='1';CE<='1';WE<='1';PST<=S0;

  IF CNTBR=15 THEN T_T<=NUMH(3);CNTBR<=0;PST<=S0;--发送第8位

  ELSE CNTBR<=CNTBR+1;PST<=S0;

  END IF;

  WHEN OTHERS=>PST<=S0;

  END CASE;

  END IF;

  END PROCESS;

  END BHV;

  硬件连接示意图:

  连接下图TXD、RXD

  2、语音模块

  1、语音芯片ISD2560芯片介绍

  ISD公司的2500系列芯片,按录放时间60秒、75秒、90秒和120秒分成ISD2560、2575、2590和25120四个型号。ISD器件设有OVF(溢出)端,便于多个器件级联。

  ISD2500系列片内EEPROM容量都为480K,最多能分600段。四个型号的不同录放时间是靠不同的输入采样率来实现的,它们分别为:8.0、6.4、5.3、4.0kHz。

  ISD2560 是ISD2500 系列单片语音录放集成电路的一种, 是一种永久记忆型录放语音电路。录音时间为60 s, 最多可以分成600 个段, 能重复录放达10 万次。它采用模拟量电平直接存储技术,把每个采样值直接存储在片内单个EEPROM 单元中, 因此能够非常自然地再现语音、音乐、音调和效果声, 又省去了A/D、D/A 转换器, 具有良好的音色又避免了一般固体录音电路因量化和压缩造成的量化噪声。片内集成了很多功能电路, 包括前置放大器、内部时钟、定时器、采样时钟、滤波器、自动增益控制、逻辑控制、模拟收发器、解码器和480K 字节的EEPROM, 可以直接连接录音输入和放音输出。

  DIP器件封装为28脚,各引脚功能如下:

序号

名称

功能

1--7

A0/M0--A6/M6

地址/模式选择

8--10

A7--A9

输入地址线

11

AUX IN

辅助输入

12、13

VSSD、VSSA

数字地和模拟地

14、15

SP+、SP-

扬声器输出

16

VCCA

模拟信号电源正极

17、18

MIC、MIC REF

麦克风输入端和输入参考端

19

AGC

自动增益控制

20、21

ANA IN、ANA OUT

模拟信号输入和输出

22

O\V\F

溢出信号

23

C\E\

低电平运行芯片工作

24

PD

芯片低功耗状态控制

25

E\O\M\

录放音结束信号输出

26

XCLK

外部时钟

27

P/R\

录放音控制选择

28

VCCD

数字信号电源正极

  工作原理

  2500系列有10个地址输入端A0~A9,寻址能力可达1024位,地址空间为0~1023。其分配情况是:地址0~599作为分段用,地址600~767未使用,地址768~1023为工作模式选择(即A8、A9均为高)。2500系列的地址线有两种用途,一是作为工作模式控制,二是作为分段录放音的起始段地址。当最高位地址(MSB)A8、A9都为高电平时(即地址768~1023),地址端A0~A6就作为工作模式选择端M0~M6,对应7种工作模式。当A8、A9任一位为低或都为低时(即地址0~599),只要在分段录/放音操作前(不少于300ns)给地址A0~A9赋值,操作就从该地址开始。

  2500系列语音芯片将480K的EEPROM分为600个信息段,每段800个字节。作为一个整体单位进行寻址和控制,应给每个信息段分配一个供外部控制的地址,而不是对每个字节进行寻址,否则至少需要19个地址端口。这样,大大减少了信息检索所需要的地址线。对较长的语音信号可以跨越多个信息段进行录音,不受内部存储信息段的限制,且内部的信息段地址会自动增加。在每个语音段的尾部自动增加一个结束标志EOM,组合放音时,通过检测EOM来控制各语音段的结束和下一段的开始。

  每个信息段的录放音时间等于总时间除以600。如ISD2560的总时间为60s,则每个信息段的录放音时间为100ms;ISD25120的总时间为120s,则每个信息段的时间为200ms。因此可以利用该时间长度作为一个段地址,通过单片机定时器的计时平行地映射信息段的地址,从而得到每段录音的起始地址。这样,就需要设置一个地址计数器。一般录音从0地址开始,首先通过CPU将它赋给A0~A9,然后通过单片机控制ISD启动录音,同时启动单片机的定时器开始计时,每到一个信息段的时间,就给地址计数器加1。当单片机停止控制ISD录音时,同时停止定时器计时。此时地址计数器的值即为该段语音的末地址,加1即为下一段语音的首地址,并将它存入EEPROM中,为下一将放音提供的地址信息。通过CPU将该地址赋给A0~A9,即可录制下一段语音。依次下去,即可在录制完所有语音段的同时得到各段的起始地址。如果不是从0地址开始的语音段,只需将初始地址赋给A0~A9,加上地址计数器的值,即可得到语音段的末地址。这里不用同时保存各语音段的起始地址和结束地址,因为各个段是相邻的,前一段的末地址加1即是本段的起始地址,且每个语音段的结尾均有EOM标志,并可发出中断。放音时利用它和保存在EEPROM中各语音段的起始地址即可按任意顺序组合各个语音段。

  2、基于单片机的分段录音及存储

  单片机采用89C52, 它的P2.0 ~P2.7、P3.0、P3.1 分别连接ISD2560 的A0~A9。P3.7 控制ISD2560 的芯片使能信号CE, 而节电控制PD 恒接VCC。由于不使用外部时钟输入, 所以XCLK 直接和GND 相连。为确保语音芯片内已录制好的语音内容不会被干扰或误操作所冲毁, 采取了一些对保护PR 控制端的措施。由Q3、Q4和D触发器组成受单片机控制的录/放音输出控制电路。D 触发器中, Pin1 为异步清0端CLR, Pin2 为D 输入端, Pin3 为时钟输入端CLK, Pin4 为异步置1 端PK, Pin6 为反相输出端Q, 单片机的P3.4 ( 图中的T0) 经Q4 反相连到CLR。单片机上电复位时所有口线均输出高电平,因而此时CLR 为低电平, 确保了D 触发器被异步清0, Q 端输出高电平给ISD2560 的PR 端, 即保证ISD2560 复位后自动处于放音状态, 避免了上电时由于PR 端和CE 端的负脉冲干扰引起的误录操作。同样, P3.5( 图中的T1) 经Q3 反相为0 作为D 端输入信号, 即使在D 触发器的时钟端产生干扰脉冲引起同步触发也是使PR 为1, 也会使ISD2560 处于放音状态, 达到双重防误录的保护。P3.6( 图中的WR) 直接控制D 触发器的CLK 端,复位以后令P3.4 为0 使CLR 为1, 从而使D 触发器的状态只取决于P3.5( T1) 的反相信号。由单片机程序对P3.4 、P3.5、P3.6 的协作控制来输出ISD2560 所需的录放音控制信号, 防止了干扰或误操作对ISD2560 的内容进行误改写。CE 端的控制是分段的关键。当CE 由高变低的下降沿将锁存地址码和PR 状态, 如果最高两位地址都是1 且A6 为0 就执行命令操作模式; 如果A6 也是1 则执行按键模式; 如果最高两地址位有一个0 时, 则执行直接寻址模式。三种模式都根据PR 值决定录音或者放音, 并且将一直有效, 直到CE 再次由高变低, 芯片重新锁存新的地址和PR值。由于CE 变高自动写入EOM, 因此放时CE 端应该保持低电平。  

  程序源代码

  #include //52系列单片机头文件

  #define uint unsigned int

  #define uchar unsigned char

  sbit a=P3^4;

  sbit b=P3^5;

  sbit c=P3^6;

  sbit ce=P3^7;

  sbit A8=P3^0;

  sbit A9=P3^1;

  uchar code table[]= //每段录音开始地址,共16段,每段0.3s,段间间隔0.1s

  {0x00,0x04,0x08,0x0c,

  0x10,0x14,0x18,0x1c,

  0x20,0x24,0x28,0x2c,

  0x30,0x34,0x38,0x3c};

  uchar num;

  uint time=1;

  void record(void);

  void main()

  {

  ce=1;

  TMOD=0x01; //设置定时器0为方式1

  TH0=(65536-50000)/256; //设置定时50ms

  TL0=(65536-50000)%256;

  EA=1; //开总中断

  ET0=1; //开定时器0中断

  TR0=1; //启动定时器0

  record();

  }

  void T1_time()interrupt 1 //中断子程序

  {

  TH1=(65536-50000)/256; //重装初值

  TL1=(65536-50000)%256;

  num++;

  if(num==6) //设置段长度为0.3s

  {

  time=0;

  num=0;

  }

  }

  void record() //录音子程序

  {

  uint i;

  A8=A9=0;

  a=b=c=1;

  for(i=0;i<16;i++)

  {

  P2=table[i];

  if(time==1) {ce=0;}

  }

  }

  3、排队叫号语音模块VHDL代码

  LIBRARY IEEE;

  USE IEEE.STD_LOGIC_1164.ALL;

  USE IEEE.STD_LOGIC_UNSIGNED.ALL;

  ENTITY yuyin3 IS

  PORT(nextone,CLK:IN STD_LOGIC; --下一位,10Hz时钟

  paihao:IN STD_LOGIC; --排号输入

  A:OUT STD_LOGIC_VECTOR(3 DOWNTO 0); --语音芯片地址

  P:OUT STD_LOGIC; --高电平时播放,低电平时录音

  ce:OUT STD_LOGIC); --低电平时语音芯片工作

  END ENTITY;

  ARCHITECTURE behav OF yuyin3 IS

  TYPE states IS (s0,s1,s2,s3,s4,s5,s6,s7,s8); --定义各状态

  SIGNAL cs,next_state: states :=s0;

  SIGNAL shi,ge:INTEGER RANGE 0 TO 9;

  SIGNAL flag:STD_LOGIC;

  SIGNAL B,C:STD_LOGIC_VECTOR(3 DOWNTO 0);

  SIGNAL haoma:INTEGER RANGE 0 TO 99;

  SIGNAL number:INTEGER RANGE 0 TO 99;

  BEGIN

  PROCESS(paihao) BEGIN

  IF paihao'EVENT AND paihao='0' THEN

  IF number<99 THEN

  number<=number+1;

  ELSE number<=0;

  END IF;

  END IF;

  END PROCESS;

  PROCESS(cs,nextone) BEGIN

  IF (nextone='0') THEN flag<='0';ELSE flag<='1';END IF;

  CASE cs IS

  WHEN s0=>A<="0000";next_state<=s1;P<='1';ce<='0';[!--empirenews.page--]

  WHEN s1=>A<=B;next_state<=s2;ce<='0';

  WHEN s2=>A<=C;next_state<=s3;ce<='0';

  WHEN s3=>A<="1011";next_state<=s4;ce<='0';

  WHEN s4=>A<="1100";next_state<=s5;ce<='0';

  WHEN s5=>A<="1101";next_state<=s6;ce<='0';

  WHEN s6=>A<="1110";next_state<=s7;ce<='0';

  WHEN s7=>A<="1111";next_state<=s8;ce<='0';

  WHEN s8=>ce<='1';

  IF(flag='0')THEN next_state<=s0;

  ELSE next_state<=s8;END IF;

  WHEN OTHERS=>A<="0000";next_state<=s0;ce<='1';

  END CASE;

  IF (cs=s1) THEN

  IF (haoma

  haoma<=haoma+1;

  ELSE haoma<=number;ce<='1';

  END IF;

  END IF;

  END PROCESS;

  PROCESS(CLK) BEGIN

  IF CLK'EVENT AND CLK='1' THEN cs<=next_state;

  END IF;

  END PROCESS;

  PROCESS(shi,haoma) BEGIN

  shi<=haoma MOD 10;

  CASE shi IS

  WHEN 0 => B<="0001";

  WHEN 1 => B<="0010";

  WHEN 2 => B<="0011";

  WHEN 3 => B<="0100";

  WHEN 4 => B<="0101";

  WHEN 5 => B<="0110";

  WHEN 6 => B<="0111";

  WHEN 7 => B<="1000";

  WHEN 8 => B<="1001";

  WHEN 9 => B<="1010";

  END CASE;

  END PROCESS;

  PROCESS(ge,haoma) BEGIN

  ge<=haoma REM 10;

  CASE ge IS

  WHEN 0 => C<="0001";

  WHEN 1 => C<="0010";

  WHEN 2 => C<="0011";

  WHEN 3 => C<="0100";

  WHEN 4 => C<="0101";

  WHEN 5 => C<="0110";

  WHEN 6 => C<="0111";

  WHEN 7 => C<="1000";

  WHEN 8 => C<="1001";

  WHEN 9 => C<="1010";

  END CASE;

  END PROCESS;

  END ARCHITECTURE;

  3、短信模块

  用Spartan-6从EEPROM存储芯片中,通过寻址找出接收短信的病人的号码与信息。EEPROM中每一个地址,存储两个字节。因此每个地址存两个数字。六个地址可以存一个手机号码。第七个地址存病人的排号。

  EEPROM 在read状态下先对CE、OE两个使能端发低电平。通过A0~A12确定地址位置,通过I/O0~I/O7调出数据内容。

  存储器与FPGA数据端口连接如下:

 

  2、发送数据的格式

  (1)传输汉字或十六进制数据

  发送汉字或十六进制数据的具体格式如下表示:

 

  手机号码:6 字节的 8 位二进制 BCD 码,将电话号码转换成数据包中 BCD 码的格式的步骤就是:

  1.在电话号码 的左边补一个“0”

  2.从左向右每两位分成一组 3. 分别将各组转换成 BCD 码。如果要将数据包中的数据还原成电话号码,步骤正好相反。例如手机号为 13912345678,表示为 01H39H 12H 34H 56H 78H 。当发送数据时,是数据发送目的 SIM 卡号,当接收数据时,是发送数据的源 SIM 卡号。

  FPGA与GSM模块数据连接如下

  VHDL代码

  LIBRARY IEEE;

  USE IEEE.STD_LOGIC_1164.ALL;

  USE IEEE.STD_LOGIC_arith.ALL;

  USE IEEE.STD_logic_UNSIGNED.ALL;

  ENTITY message IS

  PORT(clk:IN STD_LOGIC;--9600Hz

  en,order:IN STD_LOGIC;--使能--医生按钮

  data_in:IN STD_LOGIC_VECTOR(7 DOWNTO 0);--数据输入

  address:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);--地址输出

  ce:OUT STD_LOGIC;--芯片使能

  we:OUT STD_LOGIC;--芯片使能

  txd:OUT STD_LOGIC);--发送数据

  END message;

  ARCHITECTURE dec_behave OF message IS

  TYPE states_send IS(s_s0,s_s1,s_s2,s_s3,s_s4,s_s5,s_s6,s_s7,s_s8,s_s9,s_s10,s_s11,s_s12,s_s13,s_s14,s_s15,s_s16,s_s17,s_s18,s_s19, s_s20,s_s21,s_s22,s_s23,s_s24,s_s25,s_s26,s_s27,s_s28,s_s29,s_s30,s_s31,s_s32,s_s33,s_s34,s_s35,s_s36,s_s37,s_s38,s_s39, s_s40,s_s41,s_s42,s_s43,s_s44,s_s45,s_s46,s_s47,s_s48,s_s49,s_s50,s_s51,s_s52,s_s53,s_s54,s_s55,s_s56,s_s57,s_s58,s_s59, s_s60,s_s61,s_s62,s_s63,s_s64,s_s65,s_s66,s_s67,s_s68,s_s69,s_s70,s_s71,s_s72,s_s73,s_s74,s_s75,s_s76,s_s77,s_s78,s_s79, s_s80,s_s81,s_s82,s_s83,s_s84,s_s85,s_s86,s_s87,s_s88,s_s89,s_s90,s_s91,s_s92,s_s93,s_s94,s_s95,s_s96,s_s97,s_s98,s_s99, s_s100,s_s101,s_s102,s_s103,s_s104,s_s105,s_s106,s_s107,s_s108,s_s109,s_s110,s_s111,s_s112,s_s113,s_s114,s_s115,s_s116,s_s117,s_s118,s_s119, s_s120,s_s121,s_s122,s_s123,s_s124,s_s125,s_s126,s_s127,s_s128,s_s129,s_s130,s_s131,s_s132,s_s133,s_s134,s_s135,s_s136,s_s137,s_s138,s_s139, s_s140,s_s141,s_s142,s_s143,s_s144,s_s145,s_s146,s_s147,s_s148,s_s149,s_s150,s_s151,s_s152,s_s153,s_s154,s_s155,s_s156,s_s157,s_s158);

  SIGNAL s_cst,s_nst:states_send:=s_s0;

  SIGNAL num1,num2,num3,num4,num5,num6,num7,num8,num9,num10,num11,NO_shi,NO_ge:STD_LOGIC_VECTOR(3 DOWNTO 0);

  SIGNAL add:STD_LOGIC_VECTOR(8 DOWNTO 0);

  SIGNAL flag1,flag2,send:STD_LOGIC;

  SIGNAL i:STD_LOGIC_VECTOR(2 DOWNTO 0);

  BEGIN

  PROCESS(clk)

  BEGIN

  IF clk'event AND clk='1' THEN

  IF order='1' THEN

  flag2<='1';

  END IF;

  END IF;

  END PROCESS;

  PROCESS(clk) --从EEPROM里获取病人手机号码与排号

  BEGIN

  IF clk'event AND clk='1' THEN

  IF en='1' THEN add<="000000000";

  ELSE add<=add+1;

  END IF;

  CASE i IS

  WHEN "000"=>i<=i+1;

  num3<=data_in(7)&data_in(6)&data_in(5)&data_in(4);

  num4<=data_in(3)&data_in(2)&data_in(1)&data_in(0);

  WHEN "001"=>i<=i+1;

  num5<=data_in(7)&data_in(6)&data_in(5)&data_in(4);

  num6<=data_in(3)&data_in(2)&data_in(1)&data_in(0);

  WHEN "010"=>i<=i+1;

  num7<=data_in(7)&data_in(6)&data_in(5)&data_in(4);

  num8<=data_in(3)&data_in(2)&data_in(1)&data_in(0);

  WHEN "011"=>i<=i+1;

  num9<=data_in(7)&data_in(6)&data_in(5)&data_in(4);

  num10<=data_in(3)&data_in(2)&data_in(1)&data_in(0);

  WHEN "100"=>i<=i+1;

  num11<=data_in(7)&data_in(6)&data_in(5)&data_in(4);

  WHEN "101"=>i<="000";

  NO_shi<=data_in(7)&data_in(6)&data_in(5)&data_in(4);

  NO_ge<=data_in(3)&data_in(2)&data_in(1)&data_in(0);

  flag1<='1';

  WHEN OTHERS=>null;

  END CASE;

  END IF;

  END PROCESS;

  PROCESS(flag1,clk)

  BEGIN

  IF clk'event AND clk='1' THEN

  IF flag1='1' THEN ce<='1';we<='1';

  ELSE ce<='0';we<='0';

  END IF;

  END IF;

  END PROCESS;

  PROCESS(clk) --控制GSM模块发送短信[!--empirenews.page--]

  BEGIN

  IF clk'event AND clk='1' THEN

  IF send='1' THEN GND<='1' ;

  CASE s_cst IS

  WHEN s_s0=>s_nst<=s_s1;WHEN s_s1=>s_nst<=s_s2;WHEN s_s2=>s_nst<=s_s3;WHEN s_s3=>s_nst<=s_s4;

  WHEN s_s4=>s_nst<=s_s5;WHEN s_s5=>s_nst<=s_s6;WHEN s_s6=>s_nst<=s_s7;WHEN s_s7=>s_nst<=s_s8;

  WHEN s_s8=>s_nst<=s_s9;WHEN s_s9=>s_nst<=s_s10;WHEN s_s10=>s_nst<=s_s11;WHEN s_s11=>s_nst<=s_s12;

  WHEN s_s12=>s_nst<=s_s13;WHEN s_s13=>s_nst<=s_s14;WHEN s_s14=>s_nst<=s_s15;WHEN s_s15=>s_nst<=s_s16;

  WHEN s_s16=>s_nst<=s_s17;WHEN s_s17=>s_nst<=s_s18;WHEN s_s18=>s_nst<=s_s19;WHEN s_s19=>s_nst<=s_s20;

  WHEN s_s20=>s_nst<=s_s21;WHEN s_s21=>s_nst<=s_s22;WHEN s_s22=>s_nst<=s_s23;WHEN s_s23=>s_nst<=s_s24;

  WHEN s_s24=>s_nst<=s_s25;WHEN s_s25=>s_nst<=s_s26;WHEN s_s26=>s_nst<=s_s27;WHEN s_s27=>s_nst<=s_s28;

  WHEN s_s28=>s_nst<=s_s29;WHEN s_s29=>s_nst<=s_s30;WHEN s_s30=>s_nst<=s_s31;WHEN s_s31=>s_nst<=s_s32;

  WHEN s_s32=>s_nst<=s_s33;WHEN s_s33=>s_nst<=s_s34;WHEN s_s34=>s_nst<=s_s35;WHEN s_s35=>s_nst<=s_s36;

  WHEN s_s36=>s_nst<=s_s37;WHEN s_s37=>s_nst<=s_s38;WHEN s_s38=>s_nst<=s_s39;WHEN s_s39=>s_nst<=s_s40;

  WHEN s_s40=>s_nst<=s_s41;WHEN s_s41=>s_nst<=s_s42;WHEN s_s42=>s_nst<=s_s43;WHEN s_s43=>s_nst<=s_s44;

  WHEN s_s44=>s_nst<=s_s45;WHEN s_s45=>s_nst<=s_s46;WHEN s_s46=>s_nst<=s_s47;WHEN s_s47=>s_nst<=s_s48;

  WHEN s_s48=>s_nst<=s_s49;WHEN s_s49=>s_nst<=s_s50;WHEN s_s50=>s_nst<=s_s51;WHEN s_s51=>s_nst<=s_s52;

  WHEN s_s52=>s_nst<=s_s53;WHEN s_s53=>s_nst<=s_s54;WHEN s_s54=>s_nst<=s_s55;WHEN s_s55=>s_nst<=s_s56;

  WHEN s_s56=>s_nst<=s_s57;WHEN s_s57=>s_nst<=s_s58;WHEN s_s58=>s_nst<=s_s59;WHEN s_s59=>s_nst<=s_s60;

  WHEN s_s60=>s_nst<=s_s61;WHEN s_s61=>s_nst<=s_s62;WHEN s_s62=>s_nst<=s_s63;WHEN s_s63=>s_nst<=s_s64;

  WHEN s_s64=>s_nst<=s_s65;WHEN s_s65=>s_nst<=s_s66;WHEN s_s66=>s_nst<=s_s67;WHEN s_s67=>s_nst<=s_s68;

  WHEN s_s68=>s_nst<=s_s69;WHEN s_s69=>s_nst<=s_s70;WHEN s_s70=>s_nst<=s_s71;WHEN s_s71=>s_nst<=s_s72;

  WHEN s_s72=>s_nst<=s_s73;WHEN s_s73=>s_nst<=s_s74;WHEN s_s74=>s_nst<=s_s75;WHEN s_s75=>s_nst<=s_s76;

  WHEN s_s76=>s_nst<=s_s77;WHEN s_s77=>s_nst<=s_s78;WHEN s_s78=>s_nst<=s_s79;WHEN s_s79=>s_nst<=s_s80;

  WHEN s_s80=>s_nst<=s_s81;WHEN s_s81=>s_nst<=s_s82;WHEN s_s82=>s_nst<=s_s83;WHEN s_s83=>s_nst<=s_s84;

  WHEN s_s84=>s_nst<=s_s85;WHEN s_s85=>s_nst<=s_s86;WHEN s_s86=>s_nst<=s_s87;WHEN s_s87=>s_nst<=s_s88;

  WHEN s_s88=>s_nst<=s_s89;WHEN s_s89=>s_nst<=s_s90;WHEN s_s90=>s_nst<=s_s91;WHEN s_s91=>s_nst<=s_s92;

  WHEN s_s92=>s_nst<=s_s93;WHEN s_s93=>s_nst<=s_s94;WHEN s_s94=>s_nst<=s_s95;WHEN s_s95=>s_nst<=s_s96;

  WHEN s_s96=>s_nst<=s_s97;WHEN s_s97=>s_nst<=s_s98;WHEN s_s98=>s_nst<=s_s99;WHEN s_s99=>s_nst<=s_s100;

  WHEN s_s100=>s_nst<=s_s101;WHEN s_s101=>s_nst<=s_s102;WHEN s_s102=>s_nst<=s_s103;WHEN s_s103=>s_nst<=s_s104;

  WHEN s_s104=>s_nst<=s_s105;WHEN s_s105=>s_nst<=s_s106;WHEN s_s106=>s_nst<=s_s107;WHEN s_s107=>s_nst<=s_s108;

  WHEN s_s108=>s_nst<=s_s109;WHEN s_s109=>s_nst<=s_s110;WHEN s_s110=>s_nst<=s_s111;WHEN s_s111=>s_nst<=s_s112;

  WHEN s_s112=>s_nst<=s_s113;WHEN s_s113=>s_nst<=s_s114;WHEN s_s114=>s_nst<=s_s115;WHEN s_s115=>s_nst<=s_s116;

  WHEN s_s116=>s_nst<=s_s117;WHEN s_s117=>s_nst<=s_s118;WHEN s_s118=>s_nst<=s_s119;WHEN s_s119=>s_nst<=s_s120;

  WHEN s_s120=>s_nst<=s_s121;WHEN s_s121=>s_nst<=s_s122;WHEN s_s122=>s_nst<=s_s123;WHEN s_s123=>s_nst<=s_s124;

  WHEN s_s124=>s_nst<=s_s125;WHEN s_s125=>s_nst<=s_s126;WHEN s_s126=>s_nst<=s_s127;WHEN s_s127=>s_nst<=s_s128;

  WHEN s_s128=>s_nst<=s_s129;WHEN s_s129=>s_nst<=s_s130;WHEN s_s130=>s_nst<=s_s131;WHEN s_s131=>s_nst<=s_s132;

  WHEN s_s132=>s_nst<=s_s133;WHEN s_s133=>s_nst<=s_s134;WHEN s_s134=>s_nst<=s_s135;WHEN s_s135=>s_nst<=s_s136;

  WHEN s_s136=>s_nst<=s_s137;WHEN s_s137=>s_nst<=s_s138;WHEN s_s138=>s_nst<=s_s139;WHEN s_s139=>s_nst<=s_s140;

  WHEN s_s140=>s_nst<=s_s141;WHEN s_s141=>s_nst<=s_s142;WHEN s_s142=>s_nst<=s_s143;WHEN s_s143=>s_nst<=s_s144;

  WHEN s_s144=>s_nst<=s_s145;WHEN s_s145=>s_nst<=s_s146;WHEN s_s146=>s_nst<=s_s147;WHEN s_s147=>s_nst<=s_s148;

  WHEN s_s148=>s_nst<=s_s149;WHEN s_s149=>s_nst<=s_s150;WHEN s_s150=>s_nst<=s_s151;WHEN s_s151=>s_nst<=s_s152;

  WHEN s_s152=>s_nst<=s_s153;WHEN s_s153=>s_nst<=s_s154;WHEN s_s154=>s_nst<=s_s155;WHEN s_s155=>s_nst<=s_s156;

  WHEN s_s156=>s_nst<=s_s0;

  END CASE;

  END IF;

  END IF;

  END PROCESS;

  PROCESS(clk)

  BEGIN

  IF clk'event AND clk='1' THEN

  IF flag2='1' and s_cst=s_s156 THEN send<='1';

  END IF;

  END IF;

  END PROCESS;

  PROCESS(clk)

  BEGIN

  IF clk'event AND clk='1' THEN

  IF en='1' THEN add<="000000000";

  ELSE add<=add+1;

  END IF;

  CASE s_cst IS

  WHEN s_s0=>txd<='1';--字头

  WHEN s_s1=>txd<='1';

  WHEN s_s2=>txd<='0';

  WHEN s_s3=>txd<='1';

  WHEN s_s4=>txd<='0';

  WHEN s_s5=>txd<='1';

  WHEN s_s6=>txd<='1';

  WHEN s_s7=>txd<='1';

  WHEN s_s8=>txd<='0';

  WHEN s_s9=>txd<='0';

  WHEN s_s10=>txd<='0';

  WHEN s_s11=>txd<='0';

  WHEN s_s12=>txd<='0';

  WHEN s_s13=>txd<='0';

  WHEN s_s14=>txd<='0';

  WHEN s_s15=>txd<='1';

  WHEN s_s16=>txd<=num1(3);WHEN s_s17=>txd<=num1(2);WHEN s_s18=>txd<=num1(1);WHEN s_s19=>txd<=num1(0);--号码

  WHEN s_s20=>txd<=num2(3);WHEN s_s21=>txd<=num2(2);WHEN s_s22=>txd<=num2(1);WHEN s_s23=>txd<=num2(0);

  WHEN s_s24=>txd<=num3(3);WHEN s_s25=>txd<=num3(2);WHEN s_s26=>txd<=num3(1);WHEN s_s27=>txd<=num3(0);

  WHEN s_s28=>txd<=num4(3);WHEN s_s29=>txd<=num4(2);WHEN s_s30=>txd<=num4(1);WHEN s_s31=>txd<=num4(0);

  WHEN s_s32=>txd<=num5(3);WHEN s_s33=>txd<=num5(2);WHEN s_s34=>txd<=num5(1);WHEN s_s35=>txd<=num5(0);

  WHEN s_s36=>txd<=num6(3);WHEN s_s37=>txd<=num6(2);WHEN s_s38=>txd<=num6(1);WHEN s_s39=>txd<=num6(0);

  WHEN s_s40=>txd<=num7(3);WHEN s_s41=>txd<=num7(2);WHEN s_s42=>txd<=num7(1);WHEN s_s43=>txd<=num7(0);

  WHEN s_s44=>txd<=num8(3);WHEN s_s45=>txd<=num8(2);WHEN s_s46=>txd<=num8(1);WHEN s_s47=>txd<=num8(0);

  WHEN s_s48=>txd<=num9(3);WHEN s_s49=>txd<=num9(2);WHEN s_s50=>txd<=num9(1);WHEN s_s51=>txd<=num9(0);

  WHEN s_s52=>txd<=num10(3);WHEN s_s53=>txd<=num10(2);WHEN s_s54=>txd<=num10(1);WHEN s_s55=>txd<=num10(0);

  WHEN s_s56=>txd<=num11(3);WHEN s_s57=>txd<=num11(2);WHEN s_s58=>txd<=num11(1);WHEN s_s59=>txd<=num11(0);

  WHEN s_s60=>txd<='1';WHEN s_s61=>txd<='0';WHEN s_s62=>txd<='0';WHEN s_s63=>txd<='0';--请

  WHEN s_s64=>txd<='1';WHEN s_s65=>txd<='0';WHEN s_s66=>txd<='1';WHEN s_s67=>txd<='1';

  WHEN s_s68=>txd<='1';WHEN s_s69=>txd<='1';WHEN s_s70=>txd<='1';WHEN s_s71=>txd<='1';

  WHEN s_s72=>txd<='0';WHEN s_s73=>txd<='0';WHEN s_s74=>txd<='0';WHEN s_s74=>txd<='0';

  WHEN s_s75=>txd<='0';WHEN s_s76=>txd<='1';WHEN s_s77=>txd<='1';WHEN s_s78=>txd<='1';

  WHEN s_s79=>txd<='0';WHEN s_s80=>txd<='1';WHEN s_s81=>txd<='0';WHEN s_s82=>txd<='0';--你

  WHEN s_s83=>txd<='1';WHEN s_s84=>txd<='1';WHEN s_s85=>txd<='1';WHEN s_s86=>txd<='1';

  WHEN s_s87=>txd<='0';WHEN s_s88=>txd<='1';WHEN s_s89=>txd<='1';WHEN s_s90=>txd<='0';

  WHEN s_s91=>txd<='0';WHEN s_s92=>txd<='0';WHEN s_s93=>txd<='0';WHEN s_s94=>txd<='0';

  WHEN s_s95=>txd<='0';WHEN s_s96=>txd<='0';WHEN s_s97=>txd<='0';WHEN s_s98=>txd<='0';

  WHEN s_s99=>txd<='0';WHEN s_s100=>txd<='1';WHEN s_s101=>txd<='0';WHEN s_s102=>txd<='1';--到

  WHEN s_s103=>txd<='0';WHEN s_s104=>txd<='0';WHEN s_s105=>txd<='1';WHEN s_s106=>txd<='0';

  WHEN s_s107=>txd<='0';WHEN s_s108=>txd<='0';WHEN s_s109=>txd<='1';WHEN s_s110=>txd<='1';

  WHEN s_s111=>txd<='0';WHEN s_s112=>txd<='0';WHEN s_s113=>txd<='0';WHEN s_s114=>txd<='0';

  WHEN s_s115=>txd<='0';WHEN s_s116=>txd<='0';WHEN s_s117=>txd<='0';WHEN s_s118=>txd<='0';

  WHEN s_s119=>txd<='0';WHEN s_s120=>txd<='1';WHEN s_s121=>txd<='0';WHEN s_s122=>txd<='1'; --医

  WHEN s_s123=>txd<='0';WHEN s_s124=>txd<='0';WHEN s_s125=>txd<='1';WHEN s_s126=>txd<='1';

  WHEN s_s127=>txd<='0';WHEN s_s128=>txd<='0';WHEN s_s129=>txd<='1';WHEN s_s130=>txd<='1';

  WHEN s_s131=>txd<='0';WHEN s_s132=>txd<='0';WHEN s_s133=>txd<='0';WHEN s_s134=>txd<='0';

  WHEN s_s135=>txd<='1';WHEN s_s136=>txd<='0';WHEN s_s137=>txd<='1';WHEN s_s138=>txd<='1';

  WHEN s_s139=>txd<='1';WHEN s_s140=>txd<='0';WHEN s_s141=>txd<='0';WHEN s_s142=>txd<='1'; --院

  WHEN s_s143=>txd<='0';WHEN s_s144=>txd<='1';WHEN s_s145=>txd<='1';WHEN s_s146=>txd<='0';

  WHEN s_s147=>txd<='0';WHEN s_s148=>txd<='1';WHEN s_s149=>txd<='1';WHEN s_s150=>txd<='0';

  WHEN s_s151=>txd<='0';WHEN s_s152=>txd<='0';WHEN s_s153=>txd<='0';WHEN s_s154=>txd<='0';

  WHEN s_s155=>txd<='0';WHEN s_s156=>txd<='0';WHEN s_s157=>txd<='1';WHEN s_s158=>txd<='0';flag2<='1';

  END CASE;

  END IF;

  END PROCESS;

  END;

  4、点阵显示模块

  在医院里,除了需要语音提醒以外。显示提醒也是必不可少。因此本系统也加了点阵显示功能。通过点阵来显示病人号码信息,提醒该病人前往就诊。

  VHDL代码如下:

  LIBRARY IEEE;

  USE IEEE.STD_LOGIC_1164.ALL;

  USE IEEE.STD_LOGIC_UNSIGNED.ALL;

  ENTITY dianzhen IS

  PORT (rst,en,clk:IN STD_LOGIC;-- rst为清零键,en为叫号键,clk为扫描时钟。

  inshi,inge:IN STD_LOGIC_VECTOR(3 DOWNTO 0);--为输入的两位数,跟内部的计数器进行比较。

  hang:OUT STD_LOGIC_VECTOR(15 DOWNTO 0);--点阵的行

  lie:OUT STD_LOGIC_VECTOR(4 DOWNTO 0));--点阵的列

  END dianzhen;

  ARCHITECTURE be OF dianzhen IS

  SIGNAL shi,ge: STD_LOGIC_VECTOR(3 DOWNTO 0);

  SIGNAL lie1: STD_LOGIC_VECTOR(4 DOWNTO 0);

  BEGIN

  PROCESS(rst,shi,ge,en) --99进制计数器

  BEGIN

  IF rst='1' THEN shi<="0000"; ge<="0000";

  ELSIF en='1' THEN

  IF ge<9 THEN ge<=ge+1;

  ELSIF shi=9 THEN shi<="0000";ge<="0000";

  ELSE ge<=(OTHERS=>'0');shi<=shi+1;

  END IF;

  END IF;

  END PROCESS;

  PROCESS(lie1,clk) --列扫描

  BEGIN

  IF RISING_EDGE(clk) THEN

  IF lie1<31 THEN lie1<=lie1+1;

  ELSE lie1<="00000";

  END IF;

  END IF;

  END PROCESS;

  PROCESS(inshi,inge,shi,ge,lie1) --显示部分

  BEGIN

  IF (inshi>shi OR (inshi=shi AND inge>=ge)) THEN

  CASE lie1 IS

  WHEN "00000" => hang<="1111110111111111";

  WHEN "00001" => hang<="1111010111111111";

  WHEN "00010" => hang<="1111100000011111";

  WHEN "00011" => hang<="1111111110111111";

  WHEN "00100" => hang<="1111110111111111";

  WHEN "00101" => hang<="1111010000000001";

  WHEN "00110" => hang<="1101010010101111";

  WHEN "00111" => hang<="1000000010101111";

  WHEN "01000" => hang<="1101010010101011";

  WHEN "01001" => hang<="1111010000000001";

  WHEN "01010" => hang<="1111110111111111";

  WHEN "01011" => hang<="1111111111111111";

  WHEN "01100" => CASE shi IS

  WHEN "0000"=> hang<="1100000100000111";

  WHEN "0001"=> hang<="1111111111111011";

  WHEN "0010"=> hang<="1101111100000111";

  WHEN "0011"=> hang<="1101111111110111";

  WHEN "0100"=> hang<="1000000111111111";

  WHEN "0101"=> hang<="1100000111111111";

  WHEN "0110"=> hang<="1100000100000111";

  WHEN "0111"=> hang<="1101111111111111";

  WHEN "1000"=> hang<="1100000100000111";

  WHEN "1001"=> hang<="1100000111111111";

  WHEN OTHERS=> hang<="1111111111111111";

  END CASE;

  WHEN "01101" => CASE shi IS

  WHEN "0000"=> hang<="1011111111111011";

  WHEN "0001"=> hang<="1101111111111011";

  WHEN "0010"=> hang<="1011111011111011";

  WHEN "0011"=> hang<="1011111011111011";

  WHEN "0100"=> hang<="1111111011111111";

  WHEN "0101"=> hang<="1011111011111011";

  WHEN "0110"=> hang<="1011111011111011";

  WHEN "0111"=> hang<="1011111111111111";

  WHEN "1000"=> hang<="1011111011111011";

  WHEN "1001"=> hang<="1011111011111011";

  WHEN OTHERS=> hang<="1111111111111111";

  END CASE;[!--empirenews.page--]

  WHEN "01110" => CASE shi IS

  WHEN "0000"=> hang<="1011111111111011";

  WHEN "0001"=> hang<="1000000000000011";

  WHEN "0010"=> hang<="1011111011111011";

  WHEN "0011"=> hang<="1011111011111011";

  WHEN "0100"=> hang<="1111111011111110";

  WHEN "0101"=> hang<="1011111011111011";

  WHEN "0110"=> hang<="1011111011111011";

  WHEN "0111"=> hang<="1011111111111111";

  WHEN "1000"=> hang<="1011111011111011";

  WHEN "1001"=> hang<="1011111011111011";

  WHEN OTHERS=> hang<="1111111111111111";

  END CASE;

  WHEN "01111" => CASE shi IS

  WHEN "0000"=> hang<="1011111111111011";

  WHEN "0001"=> hang<="1111111111111011";

  WHEN "0010"=> hang<="1011111011111011";

  WHEN "0011"=> hang<="1011111011111011";

  WHEN "0100"=> hang<="1111111011111111";

  WHEN "0101"=> hang<="1011111011111011";

  WHEN "0110"=> hang<="1011111011111011";

  WHEN "0111"=> hang<="1011111111111111";

  WHEN "1000"=> hang<="1011111011111011";

  WHEN "1001"=> hang<="1011111011111011";

  WHEN OTHERS=> hang<="1111111111111111";

  END CASE;

  WHEN "10000" => CASE shi IS

  WHEN "0000"=> hang<="1100000100000111";

  WHEN "0001"=> hang<="1111111111111011";

  WHEN "0010"=> hang<="1100000111111011";

  WHEN "0011"=> hang<="1100000100000111";

  WHEN "0100"=> hang<="1000000100000011";

  WHEN "0101"=> hang<="1111111100000111";

  WHEN "0110"=> hang<="1111111100000111";

  WHEN "0111"=> hang<="1100000000000011";

  WHEN "1000"=> hang<="1100000100000111";

  WHEN "1001"=> hang<="1100000100000111";

  WHEN OTHERS=> hang<="1111111111111111";

  END CASE;

  WHEN "10001" => CASE ge IS

  WHEN "0000"=> hang<="1100000100000111";

  WHEN "0001"=> hang<="1111111111111011";

  WHEN "0010"=> hang<="1101111100000111";

  WHEN "0011"=> hang<="1101111111110111";

  WHEN "0100"=> hang<="1000000111111111";

  WHEN "0101"=> hang<="1100000111111111";

  WHEN "0110"=> hang<="1100000100000111";

  WHEN "0111"=> hang<="1101111111111111";

  WHEN "1000"=> hang<="1100000100000111";

  WHEN "1001"=> hang<="1100000111111111";

  WHEN OTHERS=> hang<="1111111111111111";

  END CASE;

  WHEN "10010" => CASE ge IS

  WHEN "0000"=> hang<="1011111111111011";

  WHEN "0001"=> hang<="1101111111111011";

  WHEN "0010"=> hang<="1011111011111011";

  WHEN "0011"=> hang<="1011111011111011";

  WHEN "0100"=> hang<="1111111011111111";

  WHEN "0101"=> hang<="1011111011111011";

  WHEN "0110"=> hang<="1011111011111011";

  WHEN "0111"=> hang<="1011111111111111";

  WHEN "1000"=> hang<="1011111011111011";

  WHEN "1001"=> hang<="1011111011111011";

  WHEN OTHERS=> hang<="1111111111111111";

  END CASE;

  WHEN "10011" => CASE ge IS

  WHEN "0000"=> hang<="1011111111111011";

  WHEN "0001"=> hang<="1000000000000011";

  WHEN "0010"=> hang<="1011111011111011";

  WHEN "0011"=> hang<="1011111011111011";

  WHEN "0100"=> hang<="1111111011111110";

  WHEN "0101"=> hang<="1011111011111011";

  WHEN "0110"=> hang<="1011111011111011";

  WHEN "0111"=> hang<="1011111111111111";

  WHEN "1000"=> hang<="1011111011111011";

  WHEN "1001"=> hang<="1011111011111011";

  WHEN OTHERS=> hang<="1111111111111111";

  END CASE;

  WHEN "10100" => CASE ge IS

  WHEN "0000"=> hang<="1011111111111011";

  WHEN "0001"=> hang<="1111111111111011";

  WHEN "0010"=> hang<="1011111011111011";

  WHEN "0011"=> hang<="1011111011111011";

  WHEN "0100"=> hang<="1111111011111111";

  WHEN "0101"=> hang<="1011111011111011";

  WHEN "0110"=> hang<="1011111011111011";

  WHEN "0111"=> hang<="1011111111111111";

  WHEN "1000"=> hang<="1011111011111011";

  WHEN "1001"=> hang<="1011111011111011";

  WHEN OTHERS=> hang<="1111111111111111";

  END CASE;

  WHEN "10101" => CASE ge IS

  WHEN "0000"=> hang<="1100000100000111";

  WHEN "0001"=> hang<="1111111111111011";

  WHEN "0010"=> hang<="1100000111111011";

  WHEN "0011"=> hang<="1100000100000111";

  WHEN "0100"=> hang<="1000000100000011";

  WHEN "0101"=> hang<="1111111100000111";

  WHEN "0110"=> hang<="1111111100000111";

  WHEN "0111"=> hang<="1100000000000011";

  WHEN "1000"=> hang<="1100000100000111";

  WHEN "1001"=> hang<="1100000100000111";

  WHEN OTHERS=> hang<="1111111111111111";

  END CASE;

  WHEN "10110" => hang<="1111111111111111";

  WHEN "10111" => hang<="1111110111111111";

  WHEN "11000" => hang<="1111110111111111";

  WHEN "11001" => hang<="1100010111111111";

  WHEN "11010" => hang<="1011100111110111";

  WHEN "11011" => hang<="1011100001111011";

  WHEN "11100" => hang<="1011100110111011";

  WHEN "11101" => hang<="1100010110111011";

  WHEN "11110" => hang<="1111110110111011";

  WHEN "11111" => hang<="1111110111000111";

  WHEN OTHERS=> hang<="1111111111111111";

  END CASE;

  ELSE hang<="1111111111111111";

  END IF;

  END PROCESS;

  lie<=lie1;

  END be;

  5、例化各模块

  LIBRARY IEEE;

  USE IEEE.STD_LOGIC_1164.ALL;

  USE IEEE.STD_LOGIC_UNSIGNED.ALL;

  ENTITY TOP IS

  PORT(CLK:IN STD_LOGIC;--100MHz

  RXD_PC:IN STD_LOGIC;--模拟RXD

  TXD_PC:OUT STD_LOGIC;--模拟TXD

  OE:OUT STD_LOGIC;--储存器输出使能

  CE:OUT STD_LOGIC;--储存器片选

  WE:OUT STD_LOGIC;--储存器写使能

  A_EEPROM:OUT STD_LOGIC_VECTOR(12 DOWNTO 0);--储存器地址

  IO:INOUT STD_LOGIC_VECTOR(7 DOWNTO 0);--储存器数据线

  NEXTONE:IN STD_LOGIC;--医生按钮

  A_VOICE:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);--语音芯片地址

  P:OUT STD_LOGIC;--高电平时播放,低电平时录音

  CS:OUT STD_LOGIC;--低电平时语音芯片工作

  TXD_GSM:OUT STD_LOGIC;--发送数据

  en:IN STD_LOGIC;--使能

  rst:IN STD_LOGIC;--复位

  hang:OUT STD_LOGIC_VECTOR(15 DOWNTO 0);--点阵的行

  lie:OUT STD_LOGIC_VECTOR(4 DOWNTO 0));--点阵的列

  END ENTITY TOP;

  ARCHITECTURE BHV OF TOP IS

  COMPONENT PC_FPGA IS

  PORT(CLK:IN STD_LOGIC;

  RXD:IN STD_LOGIC;

  TXD:OUT STD_LOGIC;

  OE:OUT STD_LOGIC;

  CE:OUT STD_LOGIC;

  WE:OUT STD_LOGIC;

  PH:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);

  PHH:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);

  PHL:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);

  A:OUT STD_LOGIC_VECTOR(12 DOWNTO 0);

  IO:INOUT STD_LOGIC_VECTOR(7 DOWNTO 0));

  END COMPONENT PC_FPGA;

  COMPONENT yuyin3 IS

  PORT(nextone,CLK:IN STD_LOGIC;

  paihao:IN STD_LOGIC;

  A:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);

  P:OUT STD_LOGIC;

  ce:OUT STD_LOGIC);

  END COMPONENT yuyin3;

  COMPONENT message IS

  PORT(clk:IN STD_LOGIC;

  en,order:IN STD_LOGIC;

  data_in:IN STD_LOGIC_VECTOR(7 DOWNTO 0);

  address:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);

  ce:OUT STD_LOGIC;

  we:OUT STD_LOGIC;

  txd:OUT STD_LOGIC);

  END COMPONENT message;

  COMPONENT dianzhen IS

  PORT (rst,en,clk:IN STD_LOGIC;

  inshi,inge:IN STD_LOGIC_VECTOR(3 DOWNTO 0);

  hang:OUT STD_LOGIC_VECTOR(15 DOWNTO 0);

  lie:OUT STD_LOGIC_VECTOR(4 DOWNTO 0));

  END COMPONENT dianzhen;

  SIGNAL PH:STD_LOGIC_VECTOR(7 DOWNTO 0);--排号数据

  SIGNAL PHH:STD_LOGIC_VECTOR(3 DOWNTO 0);

  SIGNAL PHL:STD_LOGIC_VECTOR(3 DOWNTO 0);

  SIGNAL FD:STD_LOGIC_VECTOR(26 DOWNTO 0);--100M分频

  SIGNAL CLK1:STD_LOGIC;--每个模块所需频率

  SIGNAL CLK2:STD_LOGIC;

  SIGNAL CLK3:STD_LOGIC;

  SIGNAL CLK4:STD_LOGIC;

  BEGIN

  PROCESS(CLK) BEGIN

  IF CLK'EVENT AND CLK='1' THEN

  IF FD="1010001011" THEN CLK1<=NOT CLK1;--100M/153600

  ELSIF FD="100110001001011010000000" THEN CLK2<=NOT CLK2;--100M/10

  ELSIF FD="10100010110000" THEN CLK3<=NOT CLK3;--100M/9600

  ELSIF FD="11110100001001000000" THEN CLK4<=NOT CLK4;--100M/1000

  ELSE FD<=FD+1;

  END IF;

  END IF;

  END PROCESS;

  U1:PC_FPGA PORT MAP(CLK1,RXD_PC,TXD_PC,OE,CE,WE,PHH,PHL,A_EEPROM,IO);

  U2:yuyin3 PORT MAP(NEXTONE,CLK2,A_VOICE,P,CS);

  U3:message PORT MAP(CLK3,en,NEXTONE,PH,A_EEPROM,CE,WE,TXD_GSM);

  U4:dianzhen PORT MAP(rst,en,CLK4,PHH,PHL,hang,lie);

  END ARCHITECTURE BHV;

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

大数据集计算的真正限制来自网络和内存两大瓶颈,而AMD Alveo V80则能够处理掉这两大瓶颈,并且帮助客户大幅降低TCO。

关键字: AMD HBM Alveo V80 加速卡 FPGA 自适应SoC

随着嵌入式的快速发展,在工控、通信、5G通信领域,FPGA以其超灵活的可编程能力,被越来越多的工程师选择。近日,米尔电子发布2款FPGA的核心板和开发板,型号分别为:基于紫光同创Logos-2系列PG2L100H的MYC...

关键字: FPGA 核心板 开发板

在某FPGA系统中,对电源系统进行调试,在同样的测试条件下,发现其中有一块板相对其它的板功耗总偏大,进而对其进行调试分析。

关键字: 电源 纹波调试 FPGA

在许多无线基站应用中,隔离电源转换器的电源是通过 -48 V 电源提供的。通信基站使用-48V电源很大部分有历史原因,历史上,通信行业设备一直使用-48V直流供电。-48V也就是正极接地。

关键字: GSM 电流 电压

UART(Universal Asynchronous Receiver/Transmitter)是一种通信协议,用于在电子设备之间传输数据。它是一种串行通信协议,意味着数据位按顺序一个接一个地传输。

关键字: FPGA UART串口通信

Bourns® TLVR1005T 和 TLVR1105T 系列采用双绕组结构和低感值设计,可提供快速瞬态响应,并可依据 CPU、FPGA 和 ASIC 负载要求进行延展

关键字: 数据驱动 电感器 FPGA

对于大规模数据处理,最佳性能不仅取决于原始计算能力,还取决于高存储器带宽。 因此,全新 AMD Alveo™ V80 计算加速卡专为具有大型数据集的内存受限型应用而设计,这些应用需要 FPGA 硬件灵活应变能力以实现工作...

关键字: 自适应计算 FPGA

8b10b编码作为数字通信领域中的一项重要线路编码方案,其核心理念在于将每8位数据映射到10位编码中。这个映射过程严格按照特定规则进行,旨在保证编码中的电平转换足够,以维持信号的直流平衡,并提供足够的时钟信息,使接收端能...

关键字: FPGA 8b/10b编码 IC设计

在FPGA和IC设计领域,经常会面临一个挑战:多个端口同时竞争一个端口的数据。在这种情况下,采用RR调度策略可能是一种解决方案。

关键字: FPGA 嵌入式系统 IC设计
关闭
关闭