《接口課設(shè)實驗報告.doc》由會員分享,可在線閱讀,更多相關(guān)《接口課設(shè)實驗報告.doc(33頁珍藏版)》請在裝配圖網(wǎng)上搜索。
接口課設(shè)實驗報告
計算機0206班 熊蘭君(012002013804)
一.緒論
本實驗是一個利用接口硬件平臺開發(fā)的微機模擬系統(tǒng),它不僅考查了我們的對接口硬件的掌握和理解程度,同樣了鍛煉了我們的編程能力。在組長的帶領(lǐng)下我們順利完成了這次實驗課設(shè),并收獲了很多的相關(guān)知識,而且鍛煉了我們的團隊精神,受益匪淺。
二.實驗?zāi)康?
掌握接口硬件開發(fā)平臺的使用方法,利用現(xiàn)有的實驗平臺和PC機,組成一個微機模擬應(yīng)用系統(tǒng);
掌握基本接口電路的綜合應(yīng)用
掌握接口電路的驅(qū)動程序和界面軟件的設(shè)計與編制,學(xué)會調(diào)試與測試接口軟件的一般方法
微機接口技術(shù)及接口芯片的綜合應(yīng)用(重點)
三. 實驗題目及要求
選課系統(tǒng)
學(xué)生通過下位機進行選課,上位機對選課信息進行統(tǒng)計。進入系統(tǒng)需要密碼,密碼錯誤或者操作錯誤時報警。
系統(tǒng)由一個主控機監(jiān)控和若干個下位機組成,主控機負責數(shù)據(jù)處理,下位機負責訪問接口。
四. 實驗內(nèi)容
這次我們所做的選課系統(tǒng)功能還比較強大,它主要由主控機,下位機,執(zhí)行部件構(gòu)成。
1.機實現(xiàn)管理員的功能,界面如下:
主界面主要是方便管理員管理學(xué)生基本信息,課程基本信息,選課基本信息。它的功能有:1.增加基本信息;2.刪除基本信息;3.查詢基本信息。注意,所有的數(shù)據(jù)信息都存放在Sql server 數(shù)據(jù)庫上,程序先分析管理員的指令,然后通過ODBC(Open DataBase Connecttion)接口操作數(shù)據(jù)庫。另外,主控機程序?qū)崿F(xiàn)的另一個功能,也就是本程序的核心功能,就是接受下位機的選課信息。當操作員按下“接受選課”按鈕后,主控機程序開始接受遠程選課信息,接收后會將該信息存入Sql server 數(shù)據(jù)庫中。
2.下位機是給選課學(xué)生的信息窗口,它同時也起到了主控機和執(zhí)行部件信息傳送的作用,而實現(xiàn)這個功能是通過接口實驗臺上的可編程串行接口芯片8251。
但是選課還是通過執(zhí)行部件,而不是通過下位機,這一點是十分重要的。以下就下位機的界面:
下位機程序的功能是接受用戶選課信息,然后將該信息發(fā)送給上位機。需要選課的學(xué)生,可以先點擊“開始選課”的按鈕,然后用撥碼開關(guān)輸入想要選擇的功能。
功能1代表選課,功能2代表查詢所有課程,功能3表示結(jié)束選課。
選功能2后,程序會通過文本框輸出所有可供選擇的課程的相關(guān)信息。選功能1后,程序會一步一步提示用戶來操作。這里有兩個問題,第一是如果學(xué)生輸入的密碼錯誤,上位機會發(fā)送回代表錯誤的信息,下位機根據(jù)該信息驅(qū)動LED顯示燈報警;第二,如果學(xué)生所選的課程不存在,上位機亦會發(fā)送回相應(yīng)錯誤代號,下位機根據(jù)該代號啟動報警程序。
3執(zhí)行部件由接口實驗臺上的芯片:可編程的并行I/O接口芯片8255,可編程計數(shù)器8253,LED顯示燈,手動開關(guān)和一個按鈕開關(guān)組成。它主要做為學(xué)生選課的輸入和警報提示。
學(xué)生通過手動開關(guān)撥出用戶名密碼,還有想選的課程號,按下按鈕表示確定。還可以選擇查看課程號和課程名。
以上就是本系統(tǒng)的大致功能,當然這只是一個模擬的系統(tǒng),它實現(xiàn)的功能都很簡單。真正要達到實用的階段,還有很多細節(jié)需要完善。但基本的框架,在本系統(tǒng)中已經(jīng)得到了體現(xiàn)。
五.實施計劃及分工
分工如下:首先夏永同學(xué)負責整個系統(tǒng)框架的設(shè)計,odbc數(shù)據(jù)源的配置以及界面的設(shè)計。吳莎同學(xué)和武孟夢同學(xué)負責上位機各個功能的實現(xiàn)以及與下位機的通信。我和賈玉芳同學(xué)負責下位機各個功能的實現(xiàn)以及硬件連接。同時我們所有人都參與了系統(tǒng)的測試工作。
首先是硬件的連接,按照我們的大概的設(shè)計,下位機有一個很重要的的功能,就是反饋執(zhí)行部件的選擇信息,而這項功能除了軟件的設(shè)計外,最重要的就是硬件連接。對于執(zhí)行部件與下位機的通信重要是靠可編程并口8255實現(xiàn)的,對于8255我們用到了它的A口進行輸出,B口進行輸入,C口作為控制口。PA0~PA7依次連接的是實驗臺上的八個燈,其作用是當用戶名和密碼不符合主控機中已存的相應(yīng)的用戶名和密碼時,這八個燈就會輪回閃爍產(chǎn)生報警的效果。PB0~PB7依次與實驗臺上八個撥碼開關(guān)連接,當用戶要輸入數(shù)字信息時,通過這八個開關(guān)進行輸入(注意這里的數(shù)字是用二進制輸入而不是八位十進制數(shù)字),開始的時候我們將高低位接反了,直接導(dǎo)致整個系統(tǒng)混亂,因為功能項輸入錯誤。PC0口作為SW1的輸入口,當SW1按下時,會給PC0一個電平,程序輪詢查看,若發(fā)現(xiàn)PC0口變?yōu)椤?”時,就將撥碼開關(guān)的數(shù)字傳送給下位機進行處理,所以這里PC0作為控制作用,這里還要注意在連接SW1時,還要經(jīng)過一個74SL373芯片,這個芯片的OE#口必須和8255的PC4口連接,用PC4口來控制74SL373,當PC4等于“1”時,74SL373關(guān)閉,這時SW1就沒有任何作用了。還有就是負責雙機通信的8251芯片,這里我們用一根連接線將主控機和下位機到26芯插座連接起來進行近距離通信,這個在實驗平臺已經(jīng)完成好了,所以不再贅述。控制8251時鐘的是8253芯片,它的OUT2端與 8251的 TxC和RxC相連進行控制,
而8253的時鐘脈沖端CLK2與1MHZ脈沖信號進行連接,至于它的GATE2與8255的PC6口連接進行脈沖源的控制,以上就是下位機與執(zhí)行部件的硬件連接。
接下來就是程序的設(shè)計了,我們開始用的C語言進行編寫,后來因為要進一步完善系統(tǒng)功能,要用到ODBC連接數(shù)據(jù)庫,還有界面的編寫就將持續(xù)移植到VC上使用C++語言。程序主要實現(xiàn)的功能有:1.將用戶名和密碼輸入并傳給主控機進行正確性的判斷;2. 當用戶選擇“1”號功能時,用戶可以進行選課,下位機將選課信息(學(xué)生號和課程號)傳給主控機并存儲起來;3. 當用戶選擇“2”號功能時,用戶可以查看選課信息(課程號和課程名); 4.當用戶選擇“3”功能時,退出選課系統(tǒng)。
這個程序按照功能來劃分兩大部分,一個是與傳送信息有關(guān)程序,二者是與界面有關(guān)的程序。由于界面相關(guān)程序由夏永同學(xué)負責,所以這里就不多說了,我們主要負責的是傳送信息有關(guān)的程序,大概如下:
#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; /*界面相關(guān)*/
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) /*寫字符傳到對應(yīng)地
{ /*址的端口
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) /*讀對應(yīng)地址的端口的信息
{
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); /*設(shè)置8253計數(shù)器的計數(shù)初值
void sTrans(char * s); /*傳送字符串s
void sRecei(char * s); /*接受一個字符串,并存入s中
void AddSC(int sid,int cid); /*添加一個選課記錄
void sw(); /*檢測開關(guān)sw1有沒有按下,如沒有按下,則等待
void Warning(int level); /*當用戶名和密碼不對時進行報警
enum { IDD = IDD_SERVER_DIALOG };
CEdit m_Output; /*系統(tǒng)信息
CString m_sid; /*學(xué)生信息中的學(xué)號信息
CString m_sname; /*學(xué)生信息中的學(xué)生姓名信息
CString m_password; /*密碼信息
CString m_cid; /*課程信息中的課程號信息
CString m_cname; /*課程信息中的課程名信息
CString m_ssid; /*選課信息中的學(xué)生號信息
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ū)?yīng)的變量的定義
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
}
//以上是變量與資源的對應(yīng)關(guān)系
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()
//以上是消息與按鈕對應(yīng)關(guān)系的說明
void CClientDlg::Init8251(int state,int work){ /*8251的初始化*/
outportb(IO_BASE+9, 0x0) ; /* 空操作*/
outportb(IO_BASE+9, 0x40) ; /* 內(nèi)部復(fù)位(使D6=1)*/
outportb(IO_BASE+9, 0x4e) ; /* 方式命令字,,查課本p180*/
outportb(IO_BASE+9, 0x27) ; /*工作命令字,例子p183*/
}
void CClientDlg::set_bps(int bps){ /*計數(shù)器設(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);//設(shè)置8253計數(shù)器的計數(shù)初值
int getPassword(int ssid);//返回學(xué)號為ssid的同學(xué)的密碼
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ū)?yīng)的變量的定義
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
}
//以上是變量與資源的對應(yīng)關(guān)系
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()
//以上是消息與按鈕對應(yīng)關(guān)系的說明
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ù)學(xué)號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://www.820124.com/p-9044376.html