《接口課設實驗報告.doc》由會員分享,可在線閱讀,更多相關《接口課設實驗報告.doc(33頁珍藏版)》請在裝配圖網(wǎng)上搜索。
接口課設實驗報告
計算機0206班 熊蘭君(012002013804)
一.緒論
本實驗是一個利用接口硬件平臺開發(fā)的微機模擬系統(tǒng),它不僅考查了我們的對接口硬件的掌握和理解程度,同樣了鍛煉了我們的編程能力。在組長的帶領下我們順利完成了這次實驗課設,并收獲了很多的相關知識,而且鍛煉了我們的團隊精神,受益匪淺。
二.實驗目的
掌握接口硬件開發(fā)平臺的使用方法,利用現(xiàn)有的實驗平臺和PC機,組成一個微機模擬應用系統(tǒng);
掌握基本接口電路的綜合應用
掌握接口電路的驅(qū)動程序和界面軟件的設計與編制,學會調(diào)試與測試接口軟件的一般方法
微機接口技術及接口芯片的綜合應用(重點)
三. 實驗題目及要求
選課系統(tǒng)
學生通過下位機進行選課,上位機對選課信息進行統(tǒng)計。進入系統(tǒng)需要密碼,密碼錯誤或者操作錯誤時報警。
系統(tǒng)由一個主控機監(jiān)控和若干個下位機組成,主控機負責數(shù)據(jù)處理,下位機負責訪問接口。
四. 實驗內(nèi)容
這次我們所做的選課系統(tǒng)功能還比較強大,它主要由主控機,下位機,執(zhí)行部件構成。
1.機實現(xiàn)管理員的功能,界面如下:
主界面主要是方便管理員管理學生基本信息,課程基本信息,選課基本信息。它的功能有:1.增加基本信息;2.刪除基本信息;3.查詢基本信息。注意,所有的數(shù)據(jù)信息都存放在Sql server 數(shù)據(jù)庫上,程序先分析管理員的指令,然后通過ODBC(Open DataBase Connecttion)接口操作數(shù)據(jù)庫。另外,主控機程序?qū)崿F(xiàn)的另一個功能,也就是本程序的核心功能,就是接受下位機的選課信息。當操作員按下“接受選課”按鈕后,主控機程序開始接受遠程選課信息,接收后會將該信息存入Sql server 數(shù)據(jù)庫中。
2.下位機是給選課學生的信息窗口,它同時也起到了主控機和執(zhí)行部件信息傳送的作用,而實現(xiàn)這個功能是通過接口實驗臺上的可編程串行接口芯片8251。
但是選課還是通過執(zhí)行部件,而不是通過下位機,這一點是十分重要的。以下就下位機的界面:
下位機程序的功能是接受用戶選課信息,然后將該信息發(fā)送給上位機。需要選課的學生,可以先點擊“開始選課”的按鈕,然后用撥碼開關輸入想要選擇的功能。
功能1代表選課,功能2代表查詢所有課程,功能3表示結(jié)束選課。
選功能2后,程序會通過文本框輸出所有可供選擇的課程的相關信息。選功能1后,程序會一步一步提示用戶來操作。這里有兩個問題,第一是如果學生輸入的密碼錯誤,上位機會發(fā)送回代表錯誤的信息,下位機根據(jù)該信息驅(qū)動LED顯示燈報警;第二,如果學生所選的課程不存在,上位機亦會發(fā)送回相應錯誤代號,下位機根據(jù)該代號啟動報警程序。
3執(zhí)行部件由接口實驗臺上的芯片:可編程的并行I/O接口芯片8255,可編程計數(shù)器8253,LED顯示燈,手動開關和一個按鈕開關組成。它主要做為學生選課的輸入和警報提示。
學生通過手動開關撥出用戶名密碼,還有想選的課程號,按下按鈕表示確定。還可以選擇查看課程號和課程名。
以上就是本系統(tǒng)的大致功能,當然這只是一個模擬的系統(tǒng),它實現(xiàn)的功能都很簡單。真正要達到實用的階段,還有很多細節(jié)需要完善。但基本的框架,在本系統(tǒng)中已經(jīng)得到了體現(xiàn)。
五.實施計劃及分工
分工如下:首先夏永同學負責整個系統(tǒng)框架的設計,odbc數(shù)據(jù)源的配置以及界面的設計。吳莎同學和武孟夢同學負責上位機各個功能的實現(xiàn)以及與下位機的通信。我和賈玉芳同學負責下位機各個功能的實現(xiàn)以及硬件連接。同時我們所有人都參與了系統(tǒng)的測試工作。
首先是硬件的連接,按照我們的大概的設計,下位機有一個很重要的的功能,就是反饋執(zhí)行部件的選擇信息,而這項功能除了軟件的設計外,最重要的就是硬件連接。對于執(zhí)行部件與下位機的通信重要是靠可編程并口8255實現(xiàn)的,對于8255我們用到了它的A口進行輸出,B口進行輸入,C口作為控制口。PA0~PA7依次連接的是實驗臺上的八個燈,其作用是當用戶名和密碼不符合主控機中已存的相應的用戶名和密碼時,這八個燈就會輪回閃爍產(chǎn)生報警的效果。PB0~PB7依次與實驗臺上八個撥碼開關連接,當用戶要輸入數(shù)字信息時,通過這八個開關進行輸入(注意這里的數(shù)字是用二進制輸入而不是八位十進制數(shù)字),開始的時候我們將高低位接反了,直接導致整個系統(tǒng)混亂,因為功能項輸入錯誤。PC0口作為SW1的輸入口,當SW1按下時,會給PC0一個電平,程序輪詢查看,若發(fā)現(xiàn)PC0口變?yōu)椤?”時,就將撥碼開關的數(shù)字傳送給下位機進行處理,所以這里PC0作為控制作用,這里還要注意在連接SW1時,還要經(jīng)過一個74SL373芯片,這個芯片的OE#口必須和8255的PC4口連接,用PC4口來控制74SL373,當PC4等于“1”時,74SL373關閉,這時SW1就沒有任何作用了。還有就是負責雙機通信的8251芯片,這里我們用一根連接線將主控機和下位機到26芯插座連接起來進行近距離通信,這個在實驗平臺已經(jīng)完成好了,所以不再贅述??刂?251時鐘的是8253芯片,它的OUT2端與 8251的 TxC和RxC相連進行控制,
而8253的時鐘脈沖端CLK2與1MHZ脈沖信號進行連接,至于它的GATE2與8255的PC6口連接進行脈沖源的控制,以上就是下位機與執(zhí)行部件的硬件連接。
接下來就是程序的設計了,我們開始用的C語言進行編寫,后來因為要進一步完善系統(tǒng)功能,要用到ODBC連接數(shù)據(jù)庫,還有界面的編寫就將持續(xù)移植到VC上使用C++語言。程序主要實現(xiàn)的功能有:1.將用戶名和密碼輸入并傳給主控機進行正確性的判斷;2. 當用戶選擇“1”號功能時,用戶可以進行選課,下位機將選課信息(學生號和課程號)傳給主控機并存儲起來;3. 當用戶選擇“2”號功能時,用戶可以查看選課信息(課程號和課程名); 4.當用戶選擇“3”功能時,退出選課系統(tǒng)。
這個程序按照功能來劃分兩大部分,一個是與傳送信息有關程序,二者是與界面有關的程序。由于界面相關程序由夏永同學負責,所以這里就不多說了,我們主要負責的是傳送信息有關的程序,大概如下:
#define PORTTALK_TYPE 40001
#define IOCTL_READ_PORT_UCHAR \
CTL_CODE(PORTTALK_TYPE, 0x904, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_WRITE_PORT_UCHAR \
CTL_CODE(PORTTALK_TYPE, 0x905, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_GETINTCODE_PORT_UCHAR \
CTL_CODE(PORTTALK_TYPE, 0x906, METHOD_BUFFERED, FILE_ANY_ACCESS)
unsigned char OpenPortTalk(void);
void ClosePortTalk(void);
void outportb(unsigned short PortAddress, unsigned char byte);
unsigned char inportb(unsigned short PortAddress);portb(unsigned short PortAddress);
//myport.cpp
#include "stdafx.h"
#include "conio.h"
#include "windows.h"
#include
#include "myport.h"
HANDLE PortTalk_Handle = NULL; /*界面相關*/
unsigned char OpenPortTalk()
{
PortTalk_Handle = CreateFile("\\\\.\\MPNP1",
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(PortTalk_Handle == INVALID_HANDLE_VALUE)
{
return -1;
}
return 0;
}
void ClosePortTalk()
{
CloseHandle(PortTalk_Handle);
}
void outportb(unsigned short PortAddress, unsigned char byte) /*寫字符傳到對應地
{ /*址的端口
DWORD dwError = 0;
unsigned int error;
DWORD BytesReturned;
unsigned char Buffer[3]; /*BUFFER和pBUFFER是傳送過程中的
unsigned char * pBuffer; /*中間緩沖區(qū)
pBuffer = (unsigned char *)&Buffer[0];
*pBuffer = (unsigned char)PortAddress&0x0f;
Buffer[2] = byte;
error = DeviceIoControl(PortTalk_Handle,
IOCTL_WRITE_PORT_UCHAR,
&Buffer,
3,
NULL,
0,
&BytesReturned,
NULL);
}
unsigned char inportb(unsigned short PortAddress) /*讀對應地址的端口的信息
{
unsigned int error;
DWORD BytesReturned;
unsigned char Buffer[3]; /*BUFFER和pBUFFER是傳送過程中的
unsigned short * pBuffer; /*中間緩沖區(qū)
pBuffer = (unsigned short *)&Buffer[0];
*pBuffer = (unsigned char)PortAddress&0x0f;
error = DeviceIoControl(PortTalk_Handle,
IOCTL_READ_PORT_UCHAR,
&Buffer,
2,
&Buffer,
1,
&BytesReturned,
NULL);
return(Buffer[0]);
}
// class CClientDlg : public CDialog
{
public:
CClientDlg(CWnd* pParent = NULL);
void Init8251(int state,int work); /*初始化8251芯片
void Trans(int tran); /*通過8251芯片傳送數(shù)值tran
int Recei(); /*接收發(fā)送到8251芯片的數(shù)值,便返回該值
void set_bps(int bps); /*設置8253計數(shù)器的計數(shù)初值
void sTrans(char * s); /*傳送字符串s
void sRecei(char * s); /*接受一個字符串,并存入s中
void AddSC(int sid,int cid); /*添加一個選課記錄
void sw(); /*檢測開關sw1有沒有按下,如沒有按下,則等待
void Warning(int level); /*當用戶名和密碼不對時進行報警
enum { IDD = IDD_SERVER_DIALOG };
CEdit m_Output; /*系統(tǒng)信息
CString m_sid; /*學生信息中的學號信息
CString m_sname; /*學生信息中的學生姓名信息
CString m_password; /*密碼信息
CString m_cid; /*課程信息中的課程號信息
CString m_cname; /*課程信息中的課程名信息
CString m_ssid; /*選課信息中的學生號信息
CString m_ccid; /*選課信息中的課程號信息
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CServerDlg)
public:
virtual LRESULT DisplayMessage(WPARAM wParam, LPARAM lParam) ;
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
protected:
// Generated message map functions
//{{AFX_MSG(CServerDlg)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnDestroy();
afx_msg void OnButton1();//查詢所有課程
afx_msg void OnButton2();//選課
afx_msg void OnButton3();//確定
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
// CClientDlg.cpp
#include "StdAfx.h"
#include "Server.h"
#include "ServerDlg.h"
#include "ServerDlg.h"
#include
#define factor 16 /*波特率因子16
unsigned long int clk = 1193182; /*8251輸入時鐘頻率(十六進制表示)
CClientDlg:: CClientDlg (CWnd* pParent )
: CDialog(CClientDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CServerDlg)
m_sid = _T("");
m_password = _T("");
m_cid = _T("");
//}}AFX_DATA_INIT
}
//以上是程序面板上文本框?qū)淖兞康亩x
void CClientDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CServerDlg)
DDX_Control(pDX, IDC_EDIT1, m_Output);
DDX_Text(pDX, IDC_EDIT2, m_sid);
DDX_Text(pDX, IDC_EDIT4, m_password);
DDX_Text(pDX, IDC_EDIT5, m_cid);
//}}AFX_DATA_MAP
}
//以上是變量與資源的對應關系
BEGIN_MESSAGE_MAP(CServerDlg, CDialog)
//{{AFX_MSG_MAP(CServerDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_DESTROY()
ON_BN_CLICKED(IDC_BUTTON3, OnButton3)
ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
//以上是消息與按鈕對應關系的說明
void CClientDlg::Init8251(int state,int work){ /*8251的初始化*/
outportb(IO_BASE+9, 0x0) ; /* 空操作*/
outportb(IO_BASE+9, 0x40) ; /* 內(nèi)部復位(使D6=1)*/
outportb(IO_BASE+9, 0x4e) ; /* 方式命令字,,查課本p180*/
outportb(IO_BASE+9, 0x27) ; /*工作命令字,例子p183*/
}
void CClientDlg::set_bps(int bps){ /*計數(shù)器設置
int i,sendhigh,sendlow;
i=clk/bps;
i=i/factor;//計算計數(shù)初值
sendhigh = (i>>8)&0x00ff;
sendlow = i & 0x00ff;
outportb(IO_BASE+7,0xb6);
outportb(IO_BASE+6,sendlow);//裝計數(shù)初值低字節(jié)
outportb(IO_BASE+6,sendhigh);//裝計數(shù)初值高字節(jié)
}
void CClientDlg::Trans(int tran){//發(fā)送字符
int state;
do
state=inportb(IO_BASE+9);
while(!(state=state&0x01));
outportb(IO_BASE+8,tran);/*發(fā)送字符*/
}
int CClientDlg::Recei(){//接收字符
int r,state;
do
state=inportb(IO_BASE+9);
while(!(state=state&0x02));
r=inportb(IO_BASE+8);/*接收字符*/
return r;
}
void CClientDlg::sTrans(char * s){//傳送字符串
int length=strlen(s);
Trans(length);
int i=0;
for(;i
#include "myport.h"
HANDLE PortTalk_Handle = NULL; /* Handle for PortTalk Driver */
unsigned char OpenPortTalk()
{
PortTalk_Handle = CreateFile("\\\\.\\MPNP1",
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(PortTalk_Handle == INVALID_HANDLE_VALUE)
{
return -1;
}
return 0;
}
void ClosePortTalk()
{
CloseHandle(PortTalk_Handle);
}
void outportb(unsigned short PortAddress, unsigned char byte)
{
DWORD dwError = 0;
unsigned int error;
DWORD BytesReturned;
unsigned char Buffer[3];
unsigned char * pBuffer;
pBuffer = (unsigned char *)&Buffer[0];
*pBuffer = (unsigned char)PortAddress&0x0f;
Buffer[2] = byte;
error = DeviceIoControl(PortTalk_Handle,
IOCTL_WRITE_PORT_UCHAR,
&Buffer,
3,
NULL,
0,
&BytesReturned,
NULL);
}
unsigned char inportb(unsigned short PortAddress)
{
unsigned int error;
DWORD BytesReturned;
unsigned char Buffer[3];
unsigned short * pBuffer;
pBuffer = (unsigned short *)&Buffer[0];
*pBuffer = (unsigned char)PortAddress&0x0f;
error = DeviceIoControl(PortTalk_Handle,
IOCTL_READ_PORT_UCHAR,
&Buffer,
2,
&Buffer,
1,
&BytesReturned,
NULL);
return(Buffer[0]);
}
//ServerDlg.h :
class CServerDlg : public CDialog
{
public:
CServerDlg(CWnd* pParent = NULL);
void Init8251(int state,int work);//初始化8251芯片
void Trans(int tran);//通過8251芯片傳送數(shù)值tran
int Recei();//接收發(fā)送到8251芯片的數(shù)值,便返回該值
void set_bps(int bps);//設置8253計數(shù)器的計數(shù)初值
int getPassword(int ssid);//返回學號為ssid的同學的密碼
int checkCid(int ccid);//檢查課號為ccid的課程是否存在
void sTrans(char * s);//傳送字符串s
void sRecei(char * s);//接受一個字符串,并存入s中
void AddSC(int sid,int cid);//添加一個選課記錄
enum { IDD = IDD_SERVER_DIALOG };
CEdit m_Output;
CString m_sid;
CString m_sname;
CString m_password;
CString m_cid;
CString m_cname;
CString m_ssid;
CString m_ccid;
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CServerDlg)
public:
virtual LRESULT DisplayMessage(WPARAM wParam, LPARAM lParam) ;
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
protected:
// Generated message map functions
//{{AFX_MSG(CServerDlg)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnDestroy();
afx_msg void OnButton3();
afx_msg void OnButton1();
afx_msg void OnButton2();
afx_msg void OnButton5();
afx_msg void OnButton4();
afx_msg void OnButton6();
afx_msg void OnButton7();
afx_msg void OnButton11();
afx_msg void OnButton12();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
// ServerDlg.cpp
#include "StdAfx.h"
#include "Server.h"
#include "ServerDlg.h"
#include "ServerDlg.h"
#include
#define factor 16 //波特率因子16
unsigned long int clk = 1193182;//8251輸入時鐘頻率(十六進制表示)
CServerDlg::CServerDlg(CWnd* pParent )
: CDialog(CServerDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CServerDlg)
m_sid = _T("");
m_sname = _T("");
m_password = _T("");
m_cid = _T("");
m_cname = _T("");
m_ssid = _T("");
m_ccid = _T("");
//}}AFX_DATA_INIT
}
//以上是程序面板上文本框?qū)淖兞康亩x
void CServerDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CServerDlg)
DDX_Control(pDX, IDC_EDIT1, m_Output);
DDX_Text(pDX, IDC_EDIT2, m_sid);
DDX_Text(pDX, IDC_EDIT3, m_sname);
DDX_Text(pDX, IDC_EDIT4, m_password);
DDX_Text(pDX, IDC_EDIT5, m_cid);
DDX_Text(pDX, IDC_EDIT6, m_cname);
DDX_Text(pDX, IDC_EDIT7, m_ssid);
DDX_Text(pDX, IDC_EDIT8, m_ccid);
//}}AFX_DATA_MAP
}
//以上是變量與資源的對應關系
BEGIN_MESSAGE_MAP(CServerDlg, CDialog)
//{{AFX_MSG_MAP(CServerDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_DESTROY()
ON_BN_CLICKED(IDC_BUTTON3, OnButton3)
ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
ON_BN_CLICKED(IDC_BUTTON5, OnButton5)
ON_BN_CLICKED(IDC_BUTTON4, OnButton4)
ON_BN_CLICKED(IDC_BUTTON6, OnButton6)
ON_BN_CLICKED(IDC_BUTTON7, OnButton7)
ON_BN_CLICKED(IDC_BUTTON11, OnButton11)
ON_BN_CLICKED(IDC_BUTTON12, OnButton12)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
//以上是消息與按鈕對應關系的說明
void CServerDlg::Init8251(int state,int work){
outportb(IO_BASE+9, 0x0) ;
outportb(IO_BASE+9, 0x40) ;
outportb(IO_BASE+9, 0x4e) ;
outportb(IO_BASE+9, 0x27) ;
}
void CServerDlg::set_bps(int bps){
int i,sendhigh,sendlow;
i=clk/bps;
i=i/factor;//計算計數(shù)初值
sendhigh = (i>>8)&0x00ff;
sendlow = i & 0x00ff;
outportb(IO_BASE+7,0xb6);
outportb(IO_BASE+6,sendlow);//裝計數(shù)初值低字節(jié)
outportb(IO_BASE+6,sendhigh);//裝計數(shù)初值高字節(jié)
}
void CServerDlg::Trans(int tran){//發(fā)送字符
int state;
do
state=inportb(IO_BASE+9);
while(!(state=state&0x01));
outportb(IO_BASE+8,tran);/*發(fā)送字符*/
}
int CServerDlg::Recei(){//接收字符
int r,state;
do
state=inportb(IO_BASE+9);
while(!(state=state&0x02));
r=inportb(IO_BASE+8);/*接收字符*/
return r;
}
int CServerDlg::getPassword(int ssid){//根據(jù)學號ssid查詢數(shù)據(jù)庫中該記錄的pssword
CDatabase database;
database.Open(_T("select"));//數(shù)據(jù)源名稱
CString temp=" ";
int pass;
CRecordset recset;
recset.m_pDatabase=&database;
CString str="";
CDBVariant var;
str.Format("%d",ssid);
CString Req="SELECT * FROM St where sid="+str+";";
str="";
recset.Open(CRecordset::forwardOnly, Req, CRecordset::readOnly);
if(recset.IsEOF()){
m_Output.ReplaceSel("用戶不存在!");
return 0;
}else{
m_Output.ReplaceSel("該用戶存在 !\r\n");
recset.GetFieldValue("password", var );
pass=var.m_iVal;
recset.Close();
return pass;
}
}
int CServerDlg::checkCid(int ccid){
//檢查課程號為ccid的課程是否存在
CDatabase database;
database.Open(_T("select"));//數(shù)據(jù)源名稱
CString temp=" ";
CRecordset recset;
recset.m_pDatabase=&database;
CString str="";
CDBVariant var;
str.Format("%d",ccid);
CString Req="SELECT * FROM Co where cid="+str+";";
str="";
recset.Open(CRecordse
鏈接地址:http://zhongcaozhi.com.cn/p-9044376.html