當前位置:首頁 » 編程軟體 » 介面機編程

介面機編程

發布時間: 2022-10-17 19:49:06

『壹』 求教一道微機原理的介面編程題!!謝謝!!

(方波半上周期計數溢出,OUT0電平置反,進入下半周期)
4Hz的方波的半周期=(1/4Hz)/2 =0.125s =125ms
10KHz脈沖周期=(1/10kHz) =0.1ms
計數初裝值 =125ms/0.1ms =1250
控制字 =00110110b,通道0,方式3,二進制初值先低位元組後高位元組裝入
.
初始化程序如下:
MOV AL,00110110b ;控制字送入AL
OUT 283h, AL ;控制字送8253控制口
MOV AX, 1250 ;計數初裝值
OUT 280h, AL ;裝入計數初值低位元組
MOV AL, AH
OUT 280h, AL ;裝入計數初值高位元組

『貳』 急求關於C# 的USB介面編程

C#操作USB口需要看是什麼硬體。
一些硬體雖然使用USB介面和PC通訊,但是它的驅動程序將它模擬成一個COM口、網口或者大容量存儲設備。
那麼C#完全可以按照COM通訊、網路通訊和文件讀寫的方法操作這些設備。
關鍵看你的USB設備的驅動程序。

『叄』 微機介面編程採用的是什麼語言

c語言。匯編語言移植性差。

『肆』 什麼叫作編程介面

簡單的說,編程就是為了藉助於計算機來達到某一目的或解決某個問題,而使用某種程序設計語言編寫程序代碼,並最終得到結果的過程。
計算機雖然功能十分強大。可以供你上網、打游戲、管理公司人事關系等等,但是沒有程序,它就等於是一堆廢鐵,不會理會我們對它下達的「命令」。於是,我們要馴服它,只有通過一種方式——程序,這也是我們和計算機溝通的唯一方式。

程序也就是指令的集合,它告訴計算機如何執行特殊的任務。

寫出程序後,再由特殊的軟體將你的程序解釋或翻譯成計算機能夠識別的「計算機語言」,然後計算機就可以「聽得懂」你的話了,並會按照你的吩咐去做事了。因此,編程實際上也就是「人給計算機出規則」這么一個過程。
隨計算機語言的種類非常的多,總的來說可以分成機器語言,匯編語言,高級語言三大類。
電腦每做的一次動作,一個步驟,都是按照已經用計算機語言編好的程序來執行,程序是計算機要執行的指令的集合,而程序全部都是用我們所掌握的語言來編寫的。所以人們要控制計算機一定要通過計算機語言向計算機發出命令。

計算機所能識別的語言只有機器語言,即由構成的代碼。但通常人們編程時,不採用機器語言,因為它非常難於記憶和識別。

匯編語言的實質和機器語言是相同的,都是直接對硬體操作,只不過指令採用了英文縮寫的標識符,更容易識別和記憶。它同樣需要編程者將每一步具體的操作用命令的形式寫出來。

匯編程序的每一句指令只能對應實際操作過程中的一個很細微的動作,例如移動、自增,因此匯編源程序一般比較冗長、復雜、容易出錯,而且使用匯編語言編程需要有更多的計算機專業知識,但匯編語言的優點也是顯而易見的,用匯編語言所能完成的操作不是一般高級語言所能實現的,而且源程序經匯編生成的可執行文件不僅比較小,而且執行速度很快。

高級語言是目前絕大多數編程者的選擇。和匯編語言相比,它不但將許多相關的機器指令合成為單條指令並且去掉了與具體操作有關但與完成工作無關的細節,例如使用堆棧、寄存器等,這樣就大大簡化了程序中的指令。由於省略了很多細節,所以編程者也不需要具備太多的專業知識。

高級語言主要是相對於匯編語言而言,它並不是特指某一種具體的語言,而是包括了很多編程語言,如目前流行的VB、VC、FoxPro、Delphi等,這些語言的語法、命令格式都各不相同。

從二十世紀60年代以後,計算機得到了突飛猛進的發展。似乎歷史上沒有任何一門科學的發展速度超過了計算機的發展,無論硬體、軟體、還是網路都以驚人的速度向前發展。軟體的發展速度和硬體一樣,二十世紀九十年代中國的軟體業還不是很成熟,而現在大大小小 的軟體企業四處聳立,共享軟體網上隨處可見。不斷發展的技術需要不斷變化的程序員,例如,如今Visual Basic可以快速構建Windows下的應用程序,程序設計方面的技術不斷發展著,不斷引進新的概念、新的方法,如從結構化的C開始,當面向對象的思想被提出後,出現了C++,微軟在C++的基礎上為使用戶構建win32應用程序更加方便,推出了Visual C++。這也就需要程序員也要不斷的更新自己的技術。

目前常用的基本程序語言的種類比較繁多,比較簡單的有:Pascal、c語言、qBasic、 Fortran、Visual Basic等等。但前幾種都是在DOS下進行編程的工具,Visual Basic是在 Windows下進行應用程序設計的編程工具,現在一般的計算機用戶幾乎都不再使用DOS了,因此我們通常會選擇Visual Basic作為初學者的編程工具。Visual Basic是Windows應用程序設計中最容易上手的編程工具,學習步驟也比較容易被初學者接受。對於剛開始學習編程的初學者來說,還是選擇Visual Basic,學習編程語言不能想像著一步登天,一步一個腳印的學習才是最佳方法。

『伍』 【高分】微機介面編程,兩個cup通過8251A向對方發送100個字元

(1)收發聯絡信號DTR、DSR、RTS、CTS
注意,RS-232-C標準的對應信號是:DTR、DSR、RTS、CTS。
(1)/DTR——數據終端准備好信號/DTR是由8251A送往外設的,CPU通過命令可以使/DTR變為低電平即有效低電平,從而通知外部設備,CPU當前已經准備就緒。
(2)/DSR——數據設備准備好信號/DSR是由外設送往8251A的,低電平時有效,它用來表示當前外設已經准備好。當/DSR端出現低電平時,會在8251A的狀態寄存器第7位上反映出來,所以,CPU通過對狀態寄存器的讀取操作,便可以實現對/DSR信號的檢測。例如,數據通信設備(Modem)准備好,該信號是外部設備(數據通信設備Modem)送給8251的。8251收到該信號後,使狀態寄存器的DSR位置1。CPU可以查詢狀態寄存器的DSR位,以了解外部設備的狀態。
(3)/RTS——請求發送信號/RTS是8251A送往外設,低電平時有效,CPU可以通過編程命令使/RTS變為有效電平,以表示CPU已經准備好發送。
(4)/CTS——清除請求發送信號/CTS是對/RTS的響應信號,它是由外設送往8251A的,當/CTS為低電平時,8251A才能執行發送操作。

『陸』 java編寫一個有關介面的程序

給你的也不是什麼系統之類的.
也就是一個思想而已,想了一下用<設計模式之Factory>來回答你的問題.

///////////////////////////////////////////////////////////////
工廠模式定義:提供創建對象的介面.

為何使用?
工廠模式是我們最常用的模式了,著名的Jive論壇 ,就大量使用了工廠模式,工廠模式在Java程序系統可以說是隨處可見。

為什麼工廠模式是如此常用?因為工廠模式就相當於創建實例對象的new,我們經常要根據類Class生成實例對象,如A a=new A() 工廠模式也是用來創建實例對象的,所以以後new時就要多個心眼,是否可以考慮實用工廠模式,雖然這樣做,可能多做一些工作,但會給你系統帶來更大的可擴展性和盡量少的修改量。

我們以類Sample為例, 如果我們要創建Sample的實例對象:

Sample sample=new Sample();

可是,實際情況是,通常我們都要在創建sample實例時做點初始化的工作,比如賦值 查詢資料庫等。

首先,我們想到的是,可以使用Sample的構造函數,這樣生成實例就寫成:

Sample sample=new Sample(參數);

但是,如果創建sample實例時所做的初始化工作不是象賦值這樣簡單的事,可能是很長一段代碼,如果也寫入構造函數中,那你的代碼很難看了(就需要Refactor重整)。

為什麼說代碼很難看,初學者可能沒有這種感覺,我們分析如下,初始化工作如果是很長一段代碼,說明要做的工作很多,將很多工作裝入一個方法中,相當於將很多雞蛋放在一個籃子里,是很危險的,這也是有背於Java面向對象的原則,面向對象的封裝(Encapsulation)和分派(Delegation)告訴我們,盡量將長的代碼分派「切割」成每段,將每段再「封裝」起來(減少段和段之間偶合聯系性),這樣,就會將風險分散,以後如果需要修改,只要更改每段,不會再發生牽一動百的事情。

在本例中,首先,我們需要將創建實例的工作與使用實例的工作分開, 也就是說,讓創建實例所需要的大量初始化工作從Sample的構造函數中分離出去。

這時我們就需要Factory工廠模式來生成對象了,不能再用上面簡單new Sample(參數)。還有,如果Sample有個繼承如MySample, 按照面向介面編程,我們需要將Sample抽象成一個介面.現在Sample是介面,有兩個子類MySample 和HisSample .我們要實例化他們時,如下:

Sample mysample=new MySample();
Sample hissample=new HisSample();

隨著項目的深入,Sample可能還會\"生出很多兒子出來\", 那麼我們要對這些兒子一個個實例化,更糟糕的是,可能還要對以前的代碼進行修改:加入後來生出兒子的實例.這在傳統程序中是無法避免的.

但如果你一開始就有意識使用了工廠模式,這些麻煩就沒有了.

工廠方法
你會建立一個專門生產Sample實例的工廠:

public class Factory{

public static Sample creator(int which){

//getClass 產生Sample 一般可使用動態類裝載裝入類。
if (which==1)
return new SampleA();
else if (which==2)
return new SampleB();

}

}

那麼在你的程序中,如果要實例化Sample時.就使用

Sample sampleA=Factory.creator(1);

這樣,在整個就不涉及到Sample的具體子類,達到封裝效果,也就減少錯誤修改的機會,這個原理可以用很通俗的話來比喻:就是具體事情做得越多,越容易范錯誤.這每個做過具體工作的人都深有體會,相反,官做得越高,說出的話越抽象越籠統,范錯誤可能性就越少.好象我們從編程序中也能悟出人生道理?呵呵.

使用工廠方法 要注意幾個角色,首先你要定義產品介面,如上面的Sample,產品介面下有Sample介面的實現類,如SampleA,其次要有一個factory類,用來生成產品Sample,如下圖,最右邊是生產的對象Sample:

進一步稍微復雜一點,就是在工廠類上進行拓展,工廠類也有繼承它的實現類concreteFactory了。

抽象工廠
工廠模式中有: 工廠方法(Factory Method) 抽象工廠(Abstract Factory).

這兩個模式區別在於需要創建對象的復雜程度上。如果我們創建對象的方法變得復雜了,如上面工廠方法中是創建一個對象Sample,如果我們還有新的產品介面Sample2.

這里假設:Sample有兩個concrete類SampleA和SamleB,而Sample2也有兩個concrete類Sample2A和SampleB2

那麼,我們就將上例中Factory變成抽象類,將共同部分封裝在抽象類中,不同部分使用子類實現,下面就是將上例中的Factory拓展成抽象工廠:

public abstract class Factory{

public abstract Sample creator();

public abstract Sample2 creator(String name);

}

public class SimpleFactory extends Factory{

public Sample creator(){
.........
return new SampleA
}

public Sample2 creator(String name){
.........
return new Sample2A
}

}

public class BombFactory extends Factory{

public Sample creator(){
......
return new SampleB
}

public Sample2 creator(String name){
......
return new Sample2B
}

}

從上面看到兩個工廠各自生產出一套Sample和Sample2,也許你會疑問,為什麼我不可以使用兩個工廠方法來分別生產Sample和Sample2?

抽象工廠還有另外一個關鍵要點,是因為 SimpleFactory內,生產Sample和生產Sample2的方法之間有一定聯系,所以才要將這兩個方法捆綁在一個類中,這個工廠類有其本身特徵,也許製造過程是統一的,比如:製造工藝比較簡單,所以名稱叫SimpleFactory。

在實際應用中,工廠方法用得比較多一些,而且是和動態類裝入器組合在一起應用.
....後面還有一些,但是我想這些應該可以解決你想知道的了.

『柒』 禹鼎遙控器和接收機編程介面怎麼定義的

禹鼎行車遙控器配對需要完成兩個步驟:
第一需要將內部的晶振換成成對的 比如接收機裝R068發射器上裝T068
第二步將識別碼(SN號)弄成相同的 這個有兩個方法弄都能完成
1.用拷貝機直接拷貝 2.你用電腦軟體用數據編程線連接發射器或者接收機直接修改或者復制這個識別碼輸入進去就可以 完成上面步驟就可以了 。

『捌』 在VC++如何對微機的介面進行編程

對於串口的使用,可以使用winapi,這里使用串口就像文件的讀寫,在開始打開串口,然後讀寫數據,結束後關閉串口.
在VC++中,串口和磁碟文件可以統一的方式來簡單讀寫。這兩者幾乎沒有什麼不同,只是在WINDOWS 9X下磁碟文件只能做同步訪問,而串口只能做非同步訪問。

CreateFile:用指定的方式打開指定的串口。通常的方式為

m_hCom = CreateFile( "COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL );

m_hCom為文件句柄。GENERIC_READ | GENERIC_WRITE指定可以對串口進行讀寫操作。第三個參數0表示串口為獨占打開。OPEN_EXISTING表示當指定串口不存在時,程序將返回失敗。 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED則表示文件屬性。當打開串口時,必須指定 FILE_FLAG_OVERLAPPED,它表示文件或設備不會維護訪問指針,則在讀寫時,必須使用OVERLAPPED 結構指定訪問的文件偏移量。

ReadFile:讀取串口數據。

WriteFile:向串口寫數據。

CloseHandle:關閉串口。

COMMTIMEOUTS:COMMTIMEOUTS主要用於串口超時參數設置。COMMTIMEOUTS結構如下:

typedef struct _COMMTIMEOUTS {
DWORD ReadIntervalTimeout;
DWORD ReadTotalTimeoutMultiplier;
DWORD ReadTotalTimeoutConstant;
DWORD WriteTotalTimeoutMultiplier;
DWORD WriteTotalTimeoutConstant;
} COMMTIMEOUTS,*LPCOMMTIMEOUTS;

ReadIntervalTimeout:兩字元之間最大的延時,當讀取串口數據時,一旦兩個字元傳輸的時間差超過該時間,讀取函數將返回現有的數據。設置為0表示該參數不起作用。

ReadTotalTimeoutMultiplier:讀取每字元間的超時。

ReadTotalTimeoutConstant:一次讀取串口數據的固定超時。所以在一次讀取串口的操作中,其超時為ReadTotalTimeoutMultiplier乘以讀取的位元組數再加上 ReadTotalTimeoutConstant。將ReadIntervalTimeout設置為MAXDWORD,並將ReadTotalTimeoutMultiplier 和ReadTotalTimeoutConstant設置為0,表示讀取操作將立即返回存放在輸入緩沖區的字元。

WriteTotalTimeoutMultiplier:寫入每字元間的超時。

WriteTotalTimeoutConstant:一次寫入串口數據的固定超時。所以在一次寫入串口的操作中,其超時為WriteTotalTimeoutMultiplier乘以寫入的位元組數再加上 WriteTotalTimeoutConstant。

SetCommTimeouts函數可以設置某設備句柄的超時參數,要得到某設備句柄的超時參數可以用GetCommTimeouts函數。

DCB:DCB結構主要用於串口參數設置。該結構太龐大,這里就不一一講述了,有興趣者可查看MSDN關於DCB的描述。其中下面兩個是比較重要的屬性。

BaudRate:串口的通訊速度。一般設置為9600。

ByteSize:位元組位數。一般設置為8。

DCB結構可以用SetCommState函數來設置,並可以用GetCommState來得到現有串口的屬性。

SetupComm:設置串口輸入、輸出緩沖區。

OVERLAPPED:保存串口非同步通訊的信息。具體結構如下:

typedef struct _OVERLAPPED {
DWORD Internal;
DWORD InternalHigh;
DWORD Offset;
DWORD OffsetHigh;
HANDLE hEvent;
} OVERLAPPED;

Internal,InternalHigh是保留給系統使用的,用戶不需要設置。

Offset,OffsetHigh是讀寫串口的偏移量,一般設置OffsetHigh為NULL,可以支持2GB數據。

hEvent讀寫事件,因為串口是非同步通訊,操作可能被其他進程堵塞,程序可以通過檢查該時間來得知是否讀寫完畢。事件將在讀寫完成後,自動設置為有效。

通過以上這些函數和結構,我們就可以通過串口進行通訊了,現在我們具體看下面的實例:

BOOL CSerial::Open( int nPort, int nBaud )
{
if( m_bOpened ) return( TRUE );

char szPort[15];
DCB dcb;

wsprintf( szPort, "COM%d", nPort );
m_hComDev = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL );
if( m_hComDev == NULL ) return( FALSE );

memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) );
memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) );

COMMTIMEOUTS CommTimeOuts;
CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
CommTimeOuts.ReadTotalTimeoutConstant = 0;
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
CommTimeOuts.WriteTotalTimeoutConstant = 5000;
SetCommTimeouts( m_hComDev, &CommTimeOuts );

m_OverlappedRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
m_OverlappedWrite.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );

dcb.DCBlength = sizeof( DCB );
GetCommState( m_hComDev, &dcb );
dcb.BaudRate = nBaud;
dcb.ByteSize = 8;
if( !SetCommState( m_hComDev, &dcb ) ||
!SetupComm( m_hComDev, 10000, 10000 ) ||
m_OverlappedRead.hEvent == NULL ||
m_OverlappedWrite.hEvent == NULL ){
DWORD dwError = GetLastError();
if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent );
if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent );
CloseHandle( m_hComDev );
return FALSE;
}

m_bOpened = TRUE;

return m_bOpened;

}

int CSerial::InBufferCount( void )
{

if( !m_bOpened || m_hComDev == NULL ) return( 0 );

DWORD dwErrorFlags;
COMSTAT ComStat;

ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );

return (int)ComStat.cbInQue;

}

DWORD CSerial::ReadData( void *buffer, DWORD dwBytesRead)
{

if( !m_bOpened || m_hComDev == NULL ) return 0;

BOOL bReadStatus;
DWORD dwErrorFlags;
COMSTAT ComStat;

ClearCommError( m_hComDev, &dwErrorFlags, &ComStat );
if( !ComStat.cbInQue ) return 0;

dwBytesRead = min(dwBytesRead,(DWORD) ComStat.cbInQue);

bReadStatus = ReadFile( m_hComDev, buffer, dwBytesRead, &dwBytesRead, &m_OverlappedRead );
if( !bReadStatus ){
if( GetLastError() == ERROR_IO_PENDING ){
WaitForSingleObject( m_OverlappedRead.hEvent, 2000 );
return dwBytesRead;
}
return 0;
}

return dwBytesRead;

}

DWORD CSerial::SendData( const char *buffer, DWORD dwBytesWritten)
{

if( !m_bOpened || m_hComDev == NULL ) return( 0 );

BOOL bWriteStat;

bWriteStat = WriteFile( m_hComDev, buffer, dwBytesWritten, &dwBytesWritten, &m_OverlappedWrite );
if( !bWriteStat){
if ( GetLastError() == ERROR_IO_PENDING ) {
WaitForSingleObject( m_OverlappedWrite.hEvent, 1000 );
return dwBytesWritten;
}
return 0;
}
return dwBytesWritten;

}

『玖』 1.編程介面是什麼我應該如何理解

「介面」是個抽象的概念!
編程介面,就是所謂的API(Application Programming Interface),是軟體系統不同組成部分銜接的約定。

在軟體裡面,介面開放給程序員,讓他們可以通過簡單的介面來調用已有程序所具有的功能,而無需關心這個程序的細節。通過介面把多個程序組合到一起,就成了一個「系統」了。

舉個例子,就好比說你看電視,遙控器就是電視機的介面,你通過控制遙控器從而打開電視(調用了電視機的打開功能),而無需關心電視機到底是怎麼工作的。

再舉個例子,水龍頭就是自來水公司的介面,你打開水龍頭(調用了水公司的服務),但是你無需關心這水來自哪家水廠。

『拾』 微型計算機原理與介面技術的編程題都有哪些

一、8253
.MODEL TINY

PCIBAR3 EQU 1CH ;8位I/O空間基地址(它就是實驗儀的基地址,也為DMA & 32 BIT RAM板卡上的8237提供基地址)
Vendor_ID EQU 10EBH ;廠商ID號
Device_ID EQU 8376 ;設備ID號

.STACK 100

.DATA
COM_ADDR DW 00B3H
T0_ADDR DW 00B0H
T1_ADDR DW 00B1H
IO_Bit8_BaseAddress DW
msg0 DB 'BIOS不支持訪問PCI
msg1 DB '找不到Star PCI9052板卡
msg2 DB '讀8位I/O空間基地址時出錯

.CODE
START: MOV AX,@DATA
MOV DS,AX
NOP
CALL InitPCI
CALL ModifyAddress ;根據PCI提供的基地址,將偏移地址轉化為實地址
mov dx,COM_ADD
mov al,35h;?
out dx,al ;計數器T0設置在模式2狀態,BCD碼計數
mov dx,T0_ADDR
mov al,00h
out dx,al
mov al,10h
out dx,al ;CLK0/1000
mov dx,COM_ADDR
mov al,77h
out dx,al ;計數器T1為模式3狀態,輸出方波,BCD碼計數
mov dx,T1_ADDR
mov al,00h
out dx,al
mov al,10h
out dx,al ;CLK1/1000
START1: CALL IfExit ;OUT1輸出頻率為1S的方波
JZ START1
JMP Exit

IfExit PROC NEAR
PUSH AX
PUSH DX
MOV AH,06H
MOV DL,0FFH
INT 21H
POP DX
POP AX
RET
IfExit ENDP

InitPCI PROC NEAR
MOV AH,00H
MOV AL,03H
INT 10H ;清屏
MOV AH,0B1H
MOV AL,01H
INT 1AH
CMP AH,0
JZ InitPCI2
LEA DX,msg0
InitPCI1: MOV AH,09H
INT 21H
JMP Exit
InitPCI2: MOV AH,0B1H
MOV AL,02H
MOV CX,Device_ID
MOV DX,Vendor_ID
MOV SI,0
INT 1AH
JNC InitPCI3 ;是否存在Star PCI9052板卡
LEA DX,msg1
JMP InitPCI1
InitPCI3: MOV DI,PCIBAR3
MOV AH,0B1H
MOV AL,09H
INT 1AH ;讀取該卡PCI9052基地址
JNC InitPCI4
LEA DX,msg2
JMP InitPCI1
InitPCI4: AND CX,0FFFCH
MOV IO_Bit8_BaseAddress,CX
RET
InitPCI ENDP

ModifyAddress PROC NEAR
ADD COM_ADDR,CX
ADD T0_ADDR,CX
ADD T1_ADDR,CX
RET
ModifyAddress ENDP

Exit: MOV AH,4CH
INT 21H

END START

二、8259
.MODEL TINY

PCIBAR1 EQU 14H ;PCI9052 I/O基地址(用於訪問局部配置寄存器)
PCIBAR3 EQU 1CH ;8位I/O空間基地址(它就是實驗儀的基地址,也為DMA & 32 BIT RAM板卡上的8237提供基地址)
PCIIPR EQU 3CH ;IRQ號
INTCSR EQU 4CH ;PCI9052 INTCSR地址
mask_int_9052 EQU 24H

Vendor_ID EQU 10EBH ;廠商ID號
Device_ID EQU 8376 ;設備ID號

.STACK 100
.DATA
IO8259_0 DW 00F0H
IO8259_1 DW 00F1H
RD_IO8259 DW 0000H
IO_Bit8_BaseAddress DW ?
PCI_IO_BaseAddress0 DW ?
PCI_IRQ_NUMBER DB ?
INT_MASK DB ?
INT_Vector DB ?
INT_CS DW ? ;保護原中斷入口地址
INT_IP DW ?
msg0 DB 'BIOS不支持訪問PCI
msg1 DB '找不到Star PCI9052板卡
msg2 DB '讀PCI9052 I/O基地址時出錯$'
msg3 DB '讀8位I/O空間基地址時出錯$'
msg4 DB '讀IRQ號出錯$'
msg5 DB '8259中斷 00H 次$'

BUFFER DB
Counter DB ?
ReDisplayFlag DB 0

.CODE
START: MOV AX,@DATA
MOV DS,AX
MOV ES,AX
NOP
CALL InitPCI
CALL ModifyAddress ;根據PCI提供的基地址,將偏移地址轉化為實地址
CALL ModifyVector ;修改中斷向量、允許中斷
MOV AH,00H
MOV AL,03H
INT 10H ;清屏
MOV AH,09H
LEA DX,msg5
INT 21H

CALL Init8259
MOV Counter,0 ;中斷次數
MOV ReDisplayFlag,1 ;需要顯示
STI ;開中斷
START1: CALL IfExit
CMP ReDisplayFlag,0
JZ START1
CALL LedDisplay
MOV ReDisplayFlag,0
JMP START1

Init8259 PROC NEAR
MOV DX,IO8259_0
mov al,13H
out dx,al

MOV DX,IO8259_1
mov al,08H
out dx,al

MOV AL,09H
OUT DX,AL
mov al,0feH ;屏蔽寄存器
OUT DX,AL
RET
Init8259 ENDP

ToChar PROC NEAR ;轉化為可顯示的16進制數
ADD AL,'0'
CMP AL,'9'
JBE ToChar1
ADD AL,07H
ToChar1: RET
ToChar ENDP

LedDisplay PROC NEAR
MOV AL,Counter
MOV AH,AL
AND AL,0FH
CALL ToChar
MOV Buffer + 1,AL
AND AH,0F0H
ROR AH,4
MOV AL,AH
CALL ToChar
MOV Buffer,AL
MOV AH,02H
MOV DL,10
MOV DH,0
INT 10H ;定位游標
MOV AH,09H
LEA DX,Buffer
INT 21H
RET
LedDisplay ENDP

INT_0: PUSH DX
PUSH AX
CALL ClearInt
JC INT_0_0
MOV DX,RD_IO8259
IN AL,DX
IN AL,DX ;判斷由哪個中斷源引起的中斷
MOV AL,Counter
ADD AL,1
DAA
MOV Counter,AL
MOV ReDisplayFlag,1
INT_0_0: MOV DX,IO8259_0
MOV AL,20H
OUT DX,AL
POP AX
POP DX
IRET

IfExit PROC NEAR
PUSH AX
PUSH DX
MOV AH,06H
MOV DL,0FFH
INT 21H
POP DX
POP AX
JZ IfExit1
JMP Exit
IfExit1: RET
IfExit ENDP

InitPCI PROC NEAR
MOV AH,00H
MOV AL,03H
INT 10H ;清屏
MOV AH,0B1H
MOV AL,01H
INT 1AH
CMP AH,0
JZ InitPCI2
LEA DX,msg0
InitPCI1: MOV AH,09H
INT 21H
JMP Exit
InitPCI2: MOV AH,0B1H
MOV AL,02H
MOV CX,Device_ID
MOV DX,Vendor_ID
MOV SI,0
INT 1AH
JNC InitPCI3 ;是否存在Star PCI9052板卡
LEA DX,msg1
JMP InitPCI1
InitPCI3: MOV DI,PCIBAR1
MOV AH,0B1H
MOV AL,09H
INT 1AH ;讀取該卡PCI9052基地址
JNC InitPCI4
LEA DX,msg2
JMP InitPCI1
InitPCI4: AND CX,0FFFCH
MOV PCI_IO_BaseAddress0,CX
MOV DI,PCIBAR3
MOV AH,0B1H
MOV AL,09H
INT 1AH ;讀取該卡擴展的8位IO基地址
JNC InitPCI5
LEA DX,msg3
JMP InitPCI1
InitPCI5: AND CX,0FFFCH
MOV IO_Bit8_BaseAddress,CX
MOV DI,PCIIPR
MOV AH,0B1H
MOV AL,09H
INT 1AH ;讀取IRQ號
JNC InitPCI6
LEA DX,msg4
JMP InitPCI1
InitPCI6: MOV PCI_IRQ_NUMBER,CL
RET
InitPCI ENDP

ModifyAddress PROC NEAR
MOV AX,IO_Bit8_BaseAddress
ADD IO8259_0,AX
ADD IO8259_1,AX
ADD RD_IO8259,AX
RET
ModifyAddress ENDP

ModifyVector PROC NEAR
PUSH ES
MOV AL,PCI_IRQ_NUMBER
CMP AL,08H
JAE ModifyVector1
ADD AL,08H ;IRQ0..7 -> 中斷向量8..F
JMP ModifyVector2
ModifyVector1: ADD AL,70H-08H ;IRQ8..F -> 中斷向量70H..77H
ModifyVector2: MOV INT_Vector,AL
MOV AH,35H
INT 21H
MOV INT_IP,BX ;保護原中斷處理常式地址
MOV AX,ES
MOV INT_CS,AX

MOV AL,INT_Vector
LEA DX,INT_0
PUSH DS
PUSH CS
POP DS
MOV AH,25H
INT 21H ;設置新中斷向量
POP DS
MOV BL,PCI_IRQ_NUMBER
MOV DX,21H
CMP AL,08H
JB ModifyVector3
MOV DX,0A1H
ModifyVector3: IN AL,DX
MOV INT_MASK,AL
AND BL,07H
MOV CL,BL
MOV BL,1
SHL BL,CL
NOT BL
AND AL,BL
OUT DX,AL ;允許中斷

POP ES
STI
RET
ModifyVector ENDP

ClearInt PROC NEAR ;清楚PCI9052、系統中斷控制器的中斷標志
MOV DX,PCI_IO_BaseAddress0
ADD DX,INTCSR
; IN AL,DX
; AND AL,mask_int_9052
; JZ ClearInt3 ;不是8259引取的中斷
INC DX
IN AL,DX
OR AL,0CH
OUT DX,AL ;清除PCI9052的中斷標志位

MOV AL,PCI_IRQ_NUMBER
CMP AL,08H
JAE ClearInt1
AND AL,7
OR AL,60H
MOV DX,20H
OUT DX,AL
JMP ClearInt2
ClearInt1: AND AL,7
OR AL,60H
MOV DX,0A0H
OUT DX,AL
MOV DX,20H
MOV AL,62H
OUT DX,AL
ClearInt2: CLC
RET
;ClearInt3: STC
; RET
ClearInt ENDP

Exit: CLI
MOV BL,PCI_IRQ_NUMBER
MOV DX,21H
CMP AL,08H
JB Exit1
MOV DX,0A1H
Exit1: MOV AL,INT_MASK
OUT DX,AL ;屏蔽中斷

PUSH DS
MOV AL,INT_Vector
MOV DX,INT_IP ;保護原中斷處理常式地址
MOV AX,INT_CS
MOV AH,25H
INT 21H ;設置新中斷向量
POP DS
STI
MOV AH,4CH
INT 21H
END START
三、8251
.MODEL TINY
;使用8253的計數器0,外接2Mhz,經26分頻後,送給8251,產生4800bps
PCIBAR3 EQU 1CH ;8位I/O空間基地址(它就是實驗儀的基地址,也為DMA & 32 BIT RAM板卡上的8237提供基地址)
Vendor_ID EQU 10EBH ;廠商ID號
Device_ID EQU 8376 ;設備ID號

.STACK 100
.DATA
CTL_ADDR DW 00F1H ;控制字或狀態字
DATA_ADDR DW 00F0H ;讀寫數據
W_8253_T0 DW 00B0H ;計數器0地址
W_8253_C DW 00B3H ;控制字

IO_Bit8_BaseAddress DW
msg0 DB 'BIOS不支持訪問PCI
msg1 DB '找不到Star PCI9052板卡
msg2 DB '讀8位I/O空間基地址時出錯$'

Receive_Buffer DB 10 DUP(0) ;接受緩沖器
Send_Buffer EQU Receive_Buffer ;發送緩沖器

.CODE
START: MOV AX,@DATA
MOV DS,AX
MOV ES,AX
NOP
CALL InitPCI
CALL ModifyAddress ;根據PCI提供的基地址,將偏移地址轉化為實地址
CALL INIT_8253
CALL INIT_8251
START1: MOV CX,10
CALL Receive_Group
MOV CX,10
CALL Send_Group
CALL IfExit ;OUT1輸出頻率為1S的方波
JZ START1
JMP Exit
; JMP START1

INIT_8253 PROC NEAR
MOV DX,W_8253_C
MOV AL,37H ;定時器0,方式3
OUT DX,AL
MOV DX,W_8253_T0
MOV AL,26H ;BCD碼26(2000000/26)=16*4800
OUT DX,AL
MOV AL,0
OUT DX,AL
RET
INIT_8253 ENDP

INIT_8251 PROC NEAR
CALL RESET_8251
mov dx,CTL_ADDR
mov al,7eh ;波特率系數為16,8個數據位
out dxx,al ;一個停止位,偶校驗
CALL DLTIME ;延時
mov al,15h ;允許接收和發送發送數據,清錯誤標志
out dx,al
CALL DLTIME
RET
INIT_8251 ENDP

Reset_8251 PROC NEAR
MOV DX,CTL_ADDR
MOV AL,0
OUT DX,AL ;向控制口寫入"0"
CALL DLTIME ;延時,等待寫操作完成
OUT DX,AL ;向控制口寫入"0"
CALL DLTIME ;延時
OUT DX,AL ;向控制口寫入"0"
CALL DLTIME ;延時
MOV AL,40H ;向控制口寫入復位字40H
OUT DX,AL
CALL DLTIME
RET
Reset_8251 ENDP

;接受一組數據,CX--接受數目
Receive_Group PROC NEAR
LEA DI,Receive_Buffer
Receive_Group1: CALL Receive_Byte
STOSB
LOOP Receive_Group1
RET
Receive_Group ENDP

;接受一個位元組
Receive_Byte PROC NEAR
MOV DX,CTL_ADDR
Receive_Byte1: in al,dx ;讀入狀態
test al,2
jz Receive_Byte1 ;
mov dx, DATA_ADDR ;有
in al,dx
RET
Receive_Byte ENDP

;發送一組數據,CX--發送數目
Send_Group PROC NEAR
LEA SI,Send_Buffer
Send_Group1: lodsb
call Sendbyte
loop Send_Group1
RET
Send_Group ENDP

;發送一個位元組
Sendbyte PROC NEAR
PUSH AX
MOV DX,CTL_ADDR ;讀入狀態
Sendbyte1: in al,dx
test al,1
jz Sendbyte1 ;允許數據發送嗎?
pop ax ;發送
mov dx,DATA_
MOV CX,Device_ID
MOV DX,Vendor_ID
MOV SI,0
INT 1AH
JNC InitPCI3 ;是否存在Star PCI9052板卡
LEA DX,msg1
JMP InitPCI1
InitPCI3: MOV DI,PCIBAR3
MOV AH,0B1H
MOV AL,09H
INT 1AH ;讀取該卡PCI9052基地址
JNC InitPCI4
LEA DX,msg2
JMP InitPCI1
InitPCI4: AND CX,0FFFCH
MOV IO_Bit8_BaseAddress,CX
RET
InitPCI ENDP

ModifyAddress PROC NEAR
ADD COM_ADD,CX
ADD PA_ADD,CX
ADD PB_ADD,CX
ADD PC_ADD,CX
RET
ModifyAddress ENDP

Exit: MOV AH,4CH
INT 21H

END START

熱點內容
地址存儲器的容量 發布:2025-07-17 23:42:56 瀏覽:166
win7電腦用戶名和密碼在哪裡查詢 發布:2025-07-17 23:39:44 瀏覽:475
安卓手機顏色怎麼變色 發布:2025-07-17 23:26:43 瀏覽:374
java離線安裝 發布:2025-07-17 23:23:31 瀏覽:376
位置伺服器地址是什麼 發布:2025-07-17 23:18:00 瀏覽:840
phpif一行 發布:2025-07-17 23:12:27 瀏覽:729
安裝腳本精靈 發布:2025-07-17 23:11:35 瀏覽:126
我的世界基岩版中國玩家的生存伺服器 發布:2025-07-17 23:06:34 瀏覽:680
顯示linux隱藏文件 發布:2025-07-17 23:00:24 瀏覽:923
三地的演算法 發布:2025-07-17 22:56:09 瀏覽:354