基于FPGA與GSM的醫(yī)院排號(hào)系統(tǒng)完整硬件設(shè)計(jì)與源代碼
時(shí)間等于金錢。隨著科技的不斷發(fā)展,人們?cè)絹碓阶非蟾咝?,討厭把時(shí)間花在一些排隊(duì)的事情上。電子信息技術(shù)的發(fā)展,改變了原始呆板固化的排隊(duì)等候方式,轉(zhuǎn)變?yōu)榛?strong>FPGA和GSM排號(hào)系統(tǒng)的舒適、休閑的等候方式,人們不僅可以自由安排等待時(shí)間,而且可以輕松的享受其他服務(wù),這方式不僅提高了業(yè)務(wù)員的工作效率,也提高了其業(yè)務(wù)素質(zhì)。以下詳細(xì)介紹了我們這個(gè)系統(tǒng)的設(shè)計(jì)。
一、設(shè)計(jì)目的與要求
目的:建設(shè)了一套由FPGA、微機(jī)與GSM模塊的通信系統(tǒng),基于此種架設(shè)的系統(tǒng)來實(shí)現(xiàn)遠(yuǎn)程的排隊(duì)叫號(hào)。在一定條件下由系統(tǒng)向指定號(hào)碼發(fā)送請(qǐng)求,再由FPGA處理請(qǐng)求,在適宜時(shí)間協(xié)助服務(wù)提供者完成服務(wù)項(xiàng)目。在此過程中,F(xiàn)PGA為該系統(tǒng)的主要中心,GSM協(xié)助其實(shí)現(xiàn)功能。
要求:
1、患者向護(hù)士提交個(gè)人手機(jī)號(hào)碼,護(hù)士給予患者相關(guān)排號(hào)的號(hào)碼(例如號(hào)碼是10號(hào))。(擴(kuò)展:患者不用去醫(yī)院護(hù)士站利用網(wǎng)絡(luò)也能提前提交申請(qǐng)服務(wù),即提前叫號(hào))。
2、護(hù)士將登記的患者手機(jī)號(hào)碼輸入微機(jī)系統(tǒng),完成排號(hào)登記。
3、醫(yī)生每完成一個(gè)患者的服務(wù)后,護(hù)士就點(diǎn)擊相關(guān)按鈕。系統(tǒng)自動(dòng)完成以下任務(wù):
若下一個(gè)患者是第7號(hào),則系統(tǒng)利用語音和LCD顯示屏提示第7號(hào)患者前來服務(wù)。同時(shí)GSM發(fā)送相關(guān)信息給第10號(hào)患者,提醒其做好準(zhǔn)備。(具體是否安排第10或第11號(hào)患者,可由系統(tǒng)設(shè)定)。
二、系統(tǒng)方案與框圖
從電腦輸入患者的手機(jī)號(hào)碼,數(shù)據(jù)通過串口經(jīng)電平轉(zhuǎn)換,傳給FPGA,然后由FPGA儲(chǔ)存到存儲(chǔ)器,F(xiàn)PGA返回患者一個(gè)排號(hào)給電腦;當(dāng)醫(yī)生接診完一個(gè)病人后,按一下next按鈕,F(xiàn)PGA控制LED點(diǎn)陣顯示滾動(dòng)消息,提示某某號(hào)病人前去就診,同時(shí)控制語音模塊和喇叭通知這位病人,并且讀取儲(chǔ)存器中的數(shù)據(jù)送到GSM短信模塊,使其發(fā)短信通知后面正在等待的某位病人做好準(zhǔn)備。系統(tǒng)框圖如下:
四、模塊設(shè)計(jì)
1、PC與FPGA通信
PC方面,利用Visual C++ 6.0創(chuàng)建一個(gè)MFC應(yīng)用程序,加入MSComm控件,在應(yīng)用程序框架中添加要實(shí)現(xiàn)的功能的代碼,設(shè)置合適的參數(shù),即可實(shí)現(xiàn)串口通信。首先用MFC AppWizard(exe)建立一個(gè)基于對(duì)話框的應(yīng)用程序界面,添加所需控件,設(shè)置控件ID,接著用“建立類導(dǎo)向”建立各個(gè)控件的函數(shù)。結(jié)果如下圖所示:
在VC++生成的應(yīng)用程序框架下添加串口初始化函數(shù)的代碼:
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++自動(dòng)生成的代碼
if(m_ctrlComm.GetPortOpen())//如果串口已經(jīng)打開
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,無校驗(yàn)位,8個(gè)數(shù)據(jù)位,1個(gè)停止位
m_ctrlComm.SetInputMode(1); //“1”表示以二進(jìn)制方式接收數(shù)據(jù)
m_ctrlComm.SetRThreshold(1); //“1”表示每當(dāng)接收接收到一個(gè)字節(jié)時(shí)將引發(fā)一個(gè)接收數(shù)據(jù)的OnComm事件
m_ctrlComm.SetInputLen(0); //“0”表示設(shè)置讀取緩沖區(qū)全部數(shù)據(jù)
m_ctrlComm.GetInput();//初始化時(shí)讀緩沖區(qū)以清除數(shù)據(jù)
return TRUE; // return TRUE unless you set the focus to a control
}
下面是產(chǎn)生OnComm事件后接收數(shù)據(jù)的代碼:
void CFC_FPGADlg::OnComm()
{
// TODO: Add your control notification handler code here
m_strPaihao=" ";
VARIANT variant_inp;//定義VARIANT型變量
COleSafeArray safearray_inp;//定義COleSafeArray類實(shí)例
LONG len,k;
BYTE rxdata[2048]; //設(shè)置BYTE數(shù)組
CString strtemp;//臨時(shí)變量
if(m_ctrlComm.GetCommEvent()==2) //事件值為2表示接收緩沖區(qū)內(nèi)有字符
{
variant_inp=m_ctrlComm.GetInput(); //讀緩沖區(qū)
safearray_inp=variant_inp; //VARIANT型變量轉(zhuǎn)換為ColeSafeArray型變量
len=safearray_inp.GetOneDimSize(); //得到有效數(shù)據(jù)長(zhǎng)度
for(k=0;k
safearray_inp.GetElement(&k,rxdata+k);//轉(zhuǎn)換為BYTE型數(shù)組
for(k=0;k
{
BYTE bt=*(char*)(rxdata+k); //字符型
strtemp.Format("%c",bt); //將字符送入臨時(shí)變量strtemp存放
m_strPaihao=m_strPaihao+strtemp; //在編輯框顯示排號(hào)
}
}
UpdateData(FALSE); //更新編輯框內(nèi)容
}
“確定” 按鈕的實(shí)現(xiàn)代碼:
void CPC_FPGADlg::OnOK()
{
// TODO: Add your control notification handler code here
m_strComm.SetOutput(COleVariant(m_strNum));//發(fā)送手機(jī)號(hào)
}
“清除”按鈕的實(shí)現(xiàn)代碼:
void CPC_FPGADlg::OnClear()
{
// TODO: Add your control notification handler code here
m_strNum = _T("");//清除手機(jī)號(hào)
m_strPaihao = _T("");//清除排號(hào)
}
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;--波特率系數(shù)為16,采樣時(shí)鐘CLK=153600Hz
RXD:IN STD_LOGIC;--模擬RXD
TXD:OUT STD_LOGIC;--模擬TXD
OE:OUT STD_LOGIC;--儲(chǔ)存器輸出使能
CE:OUT STD_LOGIC;--儲(chǔ)存器片選
WE:OUT STD_LOGIC;--儲(chǔ)存器寫使能
PH:OUT STD_LOGIC_VECTOR(7 DOWNTO 0); --排號(hào)數(shù)據(jù)
PHH:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);--高位排號(hào)數(shù)據(jù)
PHL:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);--低位排號(hào)數(shù)據(jù)
A:OUT STD_LOGIC_VECTOR(12 DOWNTO 0);--儲(chǔ)存器地址
IO:INOUT STD_LOGIC_VECTOR(7 DOWNTO 0));--儲(chǔ)存器數(shù)據(jù)線
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);--返回號(hào)碼十位
SIGNAL NUML:STD_LOGIC_VECTOR(3 DOWNTO 0);--返回號(hào)碼個(gè)位
SIGNAL CNTBR:INTEGER RANGE 0 TO 15;--波特率系數(shù)16
SIGNAL CNTBYTE:INTEGER RANGE 0 TO 6;--計(jì)算收到的字節(jié)數(shù)
SIGNAL T_T:STD_LOGIC;--發(fā)送寄存器
SIGNAL TEMP:STD_LOGIC_VECTOR(7 DOWNTO 0);--接收數(shù)據(jù)暫存
SIGNAL ADDR:STD_LOGIC_VECTOR(12 DOWNTO 0);--儲(chǔ)存器地址
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;--檢測(cè)到起始位
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上升沿鎖存數(shù)據(jù)
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;--接收到完整手機(jī)號(hào)排號(hào)+1
END IF;
ELSE CNTBYTE<=CNTBYTE+1;PST<=S0;--未接收到完整手機(jī)號(hào)
END IF;
WHEN S11=>OE<='1';CE<='1';WE<='1';PST<=S0;
IF CNTBR=15 THEN T_T<=NUML(0);CNTBR<=0;PST<=S12;--發(fā)送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;--發(fā)送第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;--發(fā)送第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;--發(fā)送第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;--發(fā)送第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;--發(fā)送第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;--發(fā)送第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;--發(fā)送第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系列芯片,按錄放時(shí)間60秒、75秒、90秒和120秒分成ISD2560、2575、2590和25120四個(gè)型號(hào)。ISD器件設(shè)有OVF(溢出)端,便于多個(gè)器件級(jí)聯(lián)。
ISD2500系列片內(nèi)EEPROM容量都為480K,最多能分600段。四個(gè)型號(hào)的不同錄放時(shí)間是靠不同的輸入采樣率來實(shí)現(xiàn)的,它們分別為:8.0、6.4、5.3、4.0kHz。
ISD2560 是ISD2500 系列單片語音錄放集成電路的一種, 是一種永久記憶型錄放語音電路。錄音時(shí)間為60 s, 最多可以分成600 個(gè)段, 能重復(fù)錄放達(dá)10 萬次。它采用模擬量電平直接存儲(chǔ)技術(shù),把每個(gè)采樣值直接存儲(chǔ)在片內(nèi)單個(gè)EEPROM 單元中, 因此能夠非常自然地再現(xiàn)語音、音樂、音調(diào)和效果聲, 又省去了A/D、D/A 轉(zhuǎn)換器, 具有良好的音色又避免了一般固體錄音電路因量化和壓縮造成的量化噪聲。片內(nèi)集成了很多功能電路, 包括前置放大器、內(nèi)部時(shí)鐘、定時(shí)器、采樣時(shí)鐘、濾波器、自動(dòng)增益控制、邏輯控制、模擬收發(fā)器、解碼器和480K 字節(jié)的EEPROM, 可以直接連接錄音輸入和放音輸出。
DIP器件封裝為28腳,各引腳功能如下:
序號(hào) |
名稱 |
功能 |
1--7 |
A0/M0--A6/M6 |
地址/模式選擇 |
8--10 |
A7--A9 |
輸入地址線 |
11 |
AUX IN |
輔助輸入 |
12、13 |
VSSD、VSSA |
數(shù)字地和模擬地 |
14、15 |
SP+、SP- |
揚(yáng)聲器輸出 |
16 |
VCCA |
模擬信號(hào)電源正極 |
17、18 |
MIC、MIC REF |
麥克風(fēng)輸入端和輸入?yún)⒖级?/p> |
19 |
AGC |
自動(dòng)增益控制 |
20、21 |
ANA IN、ANA OUT |
模擬信號(hào)輸入和輸出 |
22 |
O\V\F |
溢出信號(hào) |
23 |
C\E\ |
低電平運(yùn)行芯片工作 |
24 |
PD |
芯片低功耗狀態(tài)控制 |
25 |
E\O\M\ |
錄放音結(jié)束信號(hào)輸出 |
26 |
XCLK |
外部時(shí)鐘 |
27 |
P/R\ |
錄放音控制選擇 |
28 |
VCCD |
數(shù)字信號(hào)電源正極 |
工作原理
2500系列有10個(gè)地址輸入端A0~A9,尋址能力可達(dá)1024位,地址空間為0~1023。其分配情況是:地址0~599作為分段用,地址600~767未使用,地址768~1023為工作模式選擇(即A8、A9均為高)。2500系列的地址線有兩種用途,一是作為工作模式控制,二是作為分段錄放音的起始段地址。當(dāng)最高位地址(MSB)A8、A9都為高電平時(shí)(即地址768~1023),地址端A0~A6就作為工作模式選擇端M0~M6,對(duì)應(yīng)7種工作模式。當(dāng)A8、A9任一位為低或都為低時(shí)(即地址0~599),只要在分段錄/放音操作前(不少于300ns)給地址A0~A9賦值,操作就從該地址開始。
2500系列語音芯片將480K的EEPROM分為600個(gè)信息段,每段800個(gè)字節(jié)。作為一個(gè)整體單位進(jìn)行尋址和控制,應(yīng)給每個(gè)信息段分配一個(gè)供外部控制的地址,而不是對(duì)每個(gè)字節(jié)進(jìn)行尋址,否則至少需要19個(gè)地址端口。這樣,大大減少了信息檢索所需要的地址線。對(duì)較長(zhǎng)的語音信號(hào)可以跨越多個(gè)信息段進(jìn)行錄音,不受內(nèi)部存儲(chǔ)信息段的限制,且內(nèi)部的信息段地址會(huì)自動(dòng)增加。在每個(gè)語音段的尾部自動(dòng)增加一個(gè)結(jié)束標(biāo)志EOM,組合放音時(shí),通過檢測(cè)EOM來控制各語音段的結(jié)束和下一段的開始。
每個(gè)信息段的錄放音時(shí)間等于總時(shí)間除以600。如ISD2560的總時(shí)間為60s,則每個(gè)信息段的錄放音時(shí)間為100ms;ISD25120的總時(shí)間為120s,則每個(gè)信息段的時(shí)間為200ms。因此可以利用該時(shí)間長(zhǎng)度作為一個(gè)段地址,通過單片機(jī)定時(shí)器的計(jì)時(shí)平行地映射信息段的地址,從而得到每段錄音的起始地址。這樣,就需要設(shè)置一個(gè)地址計(jì)數(shù)器。一般錄音從0地址開始,首先通過CPU將它賦給A0~A9,然后通過單片機(jī)控制ISD啟動(dòng)錄音,同時(shí)啟動(dòng)單片機(jī)的定時(shí)器開始計(jì)時(shí),每到一個(gè)信息段的時(shí)間,就給地址計(jì)數(shù)器加1。當(dāng)單片機(jī)停止控制ISD錄音時(shí),同時(shí)停止定時(shí)器計(jì)時(shí)。此時(shí)地址計(jì)數(shù)器的值即為該段語音的末地址,加1即為下一段語音的首地址,并將它存入EEPROM中,為下一將放音提供的地址信息。通過CPU將該地址賦給A0~A9,即可錄制下一段語音。依次下去,即可在錄制完所有語音段的同時(shí)得到各段的起始地址。如果不是從0地址開始的語音段,只需將初始地址賦給A0~A9,加上地址計(jì)數(shù)器的值,即可得到語音段的末地址。這里不用同時(shí)保存各語音段的起始地址和結(jié)束地址,因?yàn)楦鱾€(gè)段是相鄰的,前一段的末地址加1即是本段的起始地址,且每個(gè)語音段的結(jié)尾均有EOM標(biāo)志,并可發(fā)出中斷。放音時(shí)利用它和保存在EEPROM中各語音段的起始地址即可按任意順序組合各個(gè)語音段。
2、基于單片機(jī)的分段錄音及存儲(chǔ)
單片機(jī)采用89C52, 它的P2.0 ~P2.7、P3.0、P3.1 分別連接ISD2560 的A0~A9。P3.7 控制ISD2560 的芯片使能信號(hào)CE, 而節(jié)電控制PD 恒接VCC。由于不使用外部時(shí)鐘輸入, 所以XCLK 直接和GND 相連。為確保語音芯片內(nèi)已錄制好的語音內(nèi)容不會(huì)被干擾或誤操作所沖毀, 采取了一些對(duì)保護(hù)PR 控制端的措施。由Q3、Q4和D觸發(fā)器組成受單片機(jī)控制的錄/放音輸出控制電路。D 觸發(fā)器中, Pin1 為異步清0端CLR, Pin2 為D 輸入端, Pin3 為時(shí)鐘輸入端CLK, Pin4 為異步置1 端PK, Pin6 為反相輸出端Q, 單片機(jī)的P3.4 ( 圖中的T0) 經(jīng)Q4 反相連到CLR。單片機(jī)上電復(fù)位時(shí)所有口線均輸出高電平,因而此時(shí)CLR 為低電平, 確保了D 觸發(fā)器被異步清0, Q 端輸出高電平給ISD2560 的PR 端, 即保證ISD2560 復(fù)位后自動(dòng)處于放音狀態(tài), 避免了上電時(shí)由于PR 端和CE 端的負(fù)脈沖干擾引起的誤錄操作。同樣, P3.5( 圖中的T1) 經(jīng)Q3 反相為0 作為D 端輸入信號(hào), 即使在D 觸發(fā)器的時(shí)鐘端產(chǎn)生干擾脈沖引起同步觸發(fā)也是使PR 為1, 也會(huì)使ISD2560 處于放音狀態(tài), 達(dá)到雙重防誤錄的保護(hù)。P3.6( 圖中的WR) 直接控制D 觸發(fā)器的CLK 端,復(fù)位以后令P3.4 為0 使CLR 為1, 從而使D 觸發(fā)器的狀態(tài)只取決于P3.5( T1) 的反相信號(hào)。由單片機(jī)程序?qū)3.4 、P3.5、P3.6 的協(xié)作控制來輸出ISD2560 所需的錄放音控制信號(hào), 防止了干擾或誤操作對(duì)ISD2560 的內(nèi)容進(jìn)行誤改寫。CE 端的控制是分段的關(guān)鍵。當(dāng)CE 由高變低的下降沿將鎖存地址碼和PR 狀態(tài), 如果最高兩位地址都是1 且A6 為0 就執(zhí)行命令操作模式; 如果A6 也是1 則執(zhí)行按鍵模式; 如果最高兩地址位有一個(gè)0 時(shí), 則執(zhí)行直接尋址模式。三種模式都根據(jù)PR 值決定錄音或者放音, 并且將一直有效, 直到CE 再次由高變低, 芯片重新鎖存新的地址和PR值。由于CE 變高自動(dòng)寫入EOM, 因此放時(shí)CE 端應(yīng)該保持低電平?! ?/p>
程序源代碼:
#include
#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; //設(shè)置定時(shí)器0為方式1
TH0=(65536-50000)/256; //設(shè)置定時(shí)50ms
TL0=(65536-50000)%256;
EA=1; //開總中斷
ET0=1; //開定時(shí)器0中斷
TR0=1; //啟動(dòng)定時(shí)器0
record();
}
void T1_time()interrupt 1 //中斷子程序
{
TH1=(65536-50000)/256; //重裝初值
TL1=(65536-50000)%256;
num++;
if(num==6) //設(shè)置段長(zhǎng)度為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、排隊(duì)叫號(hào)語音模塊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時(shí)鐘
paihao:IN STD_LOGIC; --排號(hào)輸入
A:OUT STD_LOGIC_VECTOR(3 DOWNTO 0); --語音芯片地址
P:OUT STD_LOGIC; --高電平時(shí)播放,低電平時(shí)錄音
ce:OUT STD_LOGIC); --低電平時(shí)語音芯片工作
END ENTITY;
ARCHITECTURE behav OF yuyin3 IS
TYPE states IS (s0,s1,s2,s3,s4,s5,s6,s7,s8); --定義各狀態(tài)
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存儲(chǔ)芯片中,通過尋址找出接收短信的病人的號(hào)碼與信息。EEPROM中每一個(gè)地址,存儲(chǔ)兩個(gè)字節(jié)。因此每個(gè)地址存兩個(gè)數(shù)字。六個(gè)地址可以存一個(gè)手機(jī)號(hào)碼。第七個(gè)地址存病人的排號(hào)。
EEPROM 在read狀態(tài)下先對(duì)CE、OE兩個(gè)使能端發(fā)低電平。通過A0~A12確定地址位置,通過I/O0~I/O7調(diào)出數(shù)據(jù)內(nèi)容。
存儲(chǔ)器與FPGA數(shù)據(jù)端口連接如下:
2、發(fā)送數(shù)據(jù)的格式
(1)傳輸漢字或十六進(jìn)制數(shù)據(jù)
發(fā)送漢字或十六進(jìn)制數(shù)據(jù)的具體格式如下表示:
手機(jī)號(hào)碼:6 字節(jié)的 8 位二進(jìn)制 BCD 碼,將電話號(hào)碼轉(zhuǎn)換成數(shù)據(jù)包中 BCD 碼的格式的步驟就是:
1.在電話號(hào)碼 的左邊補(bǔ)一個(gè)“0”
2.從左向右每?jī)晌环殖梢唤M 3. 分別將各組轉(zhuǎn)換成 BCD 碼。如果要將數(shù)據(jù)包中的數(shù)據(jù)還原成電話號(hào)碼,步驟正好相反。例如手機(jī)號(hào)為 13912345678,表示為 01H39H 12H 34H 56H 78H 。當(dāng)發(fā)送數(shù)據(jù)時(shí),是數(shù)據(jù)發(fā)送目的 SIM 卡號(hào),當(dāng)接收數(shù)據(jù)時(shí),是發(fā)送數(shù)據(jù)的源 SIM 卡號(hào)。
FPGA與GSM模塊數(shù)據(jù)連接如下
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;--使能--醫(yī)生按鈕
data_in:IN STD_LOGIC_VECTOR(7 DOWNTO 0);--數(shù)據(jù)輸入
address:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);--地址輸出
ce:OUT STD_LOGIC;--芯片使能
we:OUT STD_LOGIC;--芯片使能
txd:OUT STD_LOGIC);--發(fā)送數(shù)據(jù)
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里獲取病人手機(jī)號(hào)碼與排號(hào)
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模塊發(fā)送短信[!--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);--號(hào)碼
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';--請(qǐng)
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'; --醫(yī)
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、點(diǎn)陣顯示模塊
在醫(yī)院里,除了需要語音提醒以外。顯示提醒也是必不可少。因此本系統(tǒng)也加了點(diǎn)陣顯示功能。通過點(diǎn)陣來顯示病人號(hào)碼信息,提醒該病人前往就診。
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為叫號(hào)鍵,clk為掃描時(shí)鐘。
inshi,inge:IN STD_LOGIC_VECTOR(3 DOWNTO 0);--為輸入的兩位數(shù),跟內(nèi)部的計(jì)數(shù)器進(jìn)行比較。
hang:OUT STD_LOGIC_VECTOR(15 DOWNTO 0);--點(diǎn)陣的行
lie:OUT STD_LOGIC_VECTOR(4 DOWNTO 0));--點(diǎn)陣的列
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進(jìn)制計(jì)數(shù)器
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;--儲(chǔ)存器輸出使能
CE:OUT STD_LOGIC;--儲(chǔ)存器片選
WE:OUT STD_LOGIC;--儲(chǔ)存器寫使能
A_EEPROM:OUT STD_LOGIC_VECTOR(12 DOWNTO 0);--儲(chǔ)存器地址
IO:INOUT STD_LOGIC_VECTOR(7 DOWNTO 0);--儲(chǔ)存器數(shù)據(jù)線
NEXTONE:IN STD_LOGIC;--醫(yī)生按鈕
A_VOICE:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);--語音芯片地址
P:OUT STD_LOGIC;--高電平時(shí)播放,低電平時(shí)錄音
CS:OUT STD_LOGIC;--低電平時(shí)語音芯片工作
TXD_GSM:OUT STD_LOGIC;--發(fā)送數(shù)據(jù)
en:IN STD_LOGIC;--使能
rst:IN STD_LOGIC;--復(fù)位
hang:OUT STD_LOGIC_VECTOR(15 DOWNTO 0);--點(diǎn)陣的行
lie:OUT STD_LOGIC_VECTOR(4 DOWNTO 0));--點(diǎn)陣的列
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);--排號(hào)數(shù)據(jù)
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;--每個(gè)模塊所需頻率
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;