成人AV在线无码|婷婷五月激情色,|伊人加勒比二三四区|国产一区激情都市|亚洲AV无码电影|日av韩av无码|天堂在线亚洲Av|无码一区二区影院|成人无码毛片AV|超碰在线看中文字幕

doc sever

中國DOS 聯(lián)盟聯(lián)盟域名:www.cn-dos.net 論壇域名:bbs.cn-dos.net DOS ,代表著自由開放與發(fā)展,我們努力起來,學(xué)習(xí)FreeDOS 和Linux 的自由開放與GN

中國DOS 聯(lián)盟

聯(lián)盟域名:www.cn-dos.net 論壇域名:bbs.cn-dos.net DOS ,代表著自由開放與發(fā)展,我們努力起來,學(xué)習(xí)FreeDOS 和Linux 的自由開放與GNU

精神,共同創(chuàng)造和發(fā)展美好的自由與GNU GPL世界吧!

? 游客: 注冊 | 登錄 | 命令行 | 會員 | 搜索 | 上傳 | 幫助

中國DOS 聯(lián)盟論壇 ? DOS 開發(fā)編程 & 發(fā)展交流 (開發(fā)室) ? MS-DOS下如何編程控制RS232串口詳細(xì)資料及源程序

<< >> >

上一主題 | 下一主題 作者: 標(biāo)題: MS-DOS下如何編程控制RS232串口詳

細(xì)資料及源程序

BA_WANG_

MAO

初級用戶

『樓 主』: MS-DOS下如何編程控制RS232串口詳細(xì)資料及源程序 PC 機(jī)與單片機(jī)的通訊 大多數(shù)的電腦設(shè)備都具有RS-232C 接口,盡管它的性能指標(biāo)并非很好。在廣泛的市場支

持下依然常勝不衰。就使用而言,RS-232也確實有其優(yōu)勢:僅需3根線便可在兩個數(shù)字設(shè)備之間全雙工的傳送數(shù)據(jù)。不過,RS-232C 的控制要比使用并行通訊的打印機(jī)接口更 難于控制。RS-232C 使用了遠(yuǎn)較并行口更多的寄存器。這些寄存器用來實現(xiàn)串行數(shù)據(jù)的傳送及RS-232C 設(shè)備之間的握手與流量控制。本文將分別描述PC 機(jī)及單片機(jī)MCS-51的串行通訊的原理及具體的軟件設(shè)計。

(1)RS-232C 介紹與PC 硬件

RS-232C 使用-3到-25V 表示數(shù)字“1”,使用3V 到25V 表示數(shù)字“0”,RS-232C 在空閑時處于邏輯“1”狀態(tài),在開始傳送時,首先產(chǎn)生一起始位,起始位為一個寬度的邏輯“0”,緊隨其后為所要傳送的數(shù)據(jù),所要傳送的數(shù)據(jù)有最低位開始依此送出,并以一個結(jié)束位標(biāo)志該字節(jié)傳送結(jié)束,結(jié)束位為一個寬度的邏輯“1”狀態(tài)。

PC 機(jī)一般使用8250或16550作為串行通訊的控制器,使用9針或25針的接插件將串 積分 147 發(fā)帖 13 注冊 2005-3-25 狀態(tài) 離線

,

行口的信號送出。該插座的信號定義如下:

DB-25 DB-9 信號名稱 方向 含義

2 3 TXD 輸出 數(shù)據(jù)發(fā)送端

3 2 RXD 輸入 數(shù)據(jù)接收端

4 7 RTS 輸出 請求發(fā)送(計算機(jī)要求發(fā)送數(shù)據(jù))

5 8 CTS 輸入 清除發(fā)送(MODEM 準(zhǔn)備接收數(shù)據(jù)) 6 6 DSR 輸入 數(shù)據(jù)設(shè)備準(zhǔn)備就緒

7 5 SG - 信號地

8 1 DCD 輸入 數(shù)據(jù)載波檢測

20 4 DTR 輸出 數(shù)據(jù)終端準(zhǔn)備就緒(計算機(jī))

22 9 RI 輸入 響鈴指示

以上信號在通訊過程之中可能會被全部或部分使用,最簡單的通訊僅需TXD 及RXD 及SG 即可完成,其他的握手信號可以做適當(dāng)處理或直接懸空,至于是否可以懸空這視乎你的通訊軟件。比如說,如果使用DOS 所提供的BIOS 通訊驅(qū)動程序,那么,這些握手信號則需要做如下處理,因為BIOS 的通訊驅(qū)動使用了這些信號。如果使用自己編寫的串行驅(qū)動程序則可以完全不使用這些握手信號(詳見下面有關(guān)章節(jié))。

PC 機(jī)一般使用8250或16550的作為串行通訊控制器,8250及16550的管腳排列如下:

8250(16550)的寄存器如下表所示:

基地址 讀/寫 寄存器縮寫 注釋

0 Write - 發(fā)送保持寄存器(DLAB=0)

0 Read - 接收數(shù)據(jù)寄存器(DLAB=0)

0 Read/Write - 波特率低八位(DLAB=1)

1 Read/Write IER 中斷允許寄存器

1 Read/Write - 波特率高八位(DLAB=1)

2 Read IIR 中斷標(biāo)識寄存器

2 Write FCR FIFO 控制寄存器

3 Read/Write LCR 線路控制寄存器

4 Read/Write MCR MODEM 控制寄存器

5 Read LSR 線路狀態(tài)寄存器

6 Read MSR MODEM 狀態(tài)寄存器

7 Read/Write - Scratch Register

PC 機(jī)支持1-4個串行口,即COM1-COM4,其基地址在BIOS 數(shù)據(jù)區(qū)0000:0400-0000:0406中描述,對應(yīng)地址分別為3F8/2F8/3E8/2E8,COM1及COM3使用PC 機(jī)中斷4,COM2及COM4使用中斷3。

在上表中,8250共有12個寄存器,使用了8個地址,其中部分寄存器共用一個地址,由DLAB=0/1來區(qū)分,在DLAB=1用于設(shè)定通訊所需的波特率。常用的波特率參數(shù)見下表:

速率(BPS ) 波特率高八位 波特率低八位

50 09h 00h

300 01h 80h

,

600 00h C0h

2400 00h 30h

4800 00h 18h

9600 00h 0Ch

19200 00h 06h

38400 00h 03h

57600 00h 02h

115200 00h 01h

以下幾個表格為8250的寄存器的功能描述:

中斷允許寄存器(IER ):

位 注釋

7 未使用

6 未使用

5 進(jìn)入低功耗模式(16750)

4 進(jìn)入睡眠模式(16750)

3 允許MODEM 狀態(tài)中斷

2 允許接收線路狀態(tài)中斷

1 允許發(fā)送保持器空中斷

0 允許接收數(shù)據(jù)就緒中斷

Bit0置1將允許接收到數(shù)據(jù)時產(chǎn)生中斷,Bit1置1時允許發(fā)送保持寄存器空時產(chǎn)生中斷,Bit2置1將在LSR 變化時產(chǎn)生中斷,相應(yīng)的Bit3置位將在MSR 變化時產(chǎn)生中斷。 中斷識別寄存器(IIR ):

位 注釋

Bit6:7=00 無FIFO

Bit6:7=01 允許FIFO ,但不可用

Bit6:7=11 允許FIFO

Bit5 允許64字節(jié)FIFO (16750)

Bit4 未使用

Bit3 16550超時中斷

Bit2:1=00 MODEM 狀態(tài)中斷(CTS/RI/DTR/DCD)

Bit2:1=01 發(fā)送保持寄存器空中斷

Bit2:1=10 接收數(shù)據(jù)就緒中斷

Bit2:1=11 接收線路狀態(tài)中斷

Bit0=0 有中斷產(chǎn)生

Bit0=1 無中斷產(chǎn)生

IIR 為只讀寄存器,Bit6:7用來指示FIFO 的狀態(tài),均為0時則無FIFO ,此時為8250或16450芯片,為01時有FIFO 但不可以使用,為11時FIFO 有效并可以正常工作。Bit3用來指示超時中斷(16550/16750)。

Bit0用來指示是否有中斷發(fā)生,Bit1:2標(biāo)識具體的中斷類型,這些中斷具有不同的優(yōu)先級別,其中LSR 中斷級別最高,其次是數(shù)據(jù)就緒中斷,然后是發(fā)送寄存器空中斷,而MSR 中斷級別最低。

FIFO 控制寄存器(FCR ):

位 注釋

,

Bit7:6=00 1Byte 產(chǎn)生中斷

Bit7:6=01 4Byte 產(chǎn)生中斷

Bit7:6=10 8Byte 產(chǎn)生中斷

Bit7:6=11 14Byte 產(chǎn)生中斷

Bit5 允許64字節(jié)FIFO

Bit4 未使用

Bit3 DMA 模式選擇

Bit2 清除發(fā)送FIFO

Bit1 清除接收FIFO

Bit0 允許FIFO

FCR 可寫但不可以讀,該寄存器用來控制16550或16750的FIFO 寄存器。Bit0置1將允許發(fā)送/接收的FIFO 工作,Bit1和Bit2置1分別用來清除接收及發(fā)送FIFO 。清除接收及發(fā)送FIFO 并不影響移位寄存器。Bit1:2可自行復(fù)位,因此無需使用軟件對其清零。Bit6:7用來設(shè)定產(chǎn)生中斷的級別,發(fā)送/接收中斷將在發(fā)送/接收到對應(yīng)字節(jié)數(shù)時產(chǎn)生。 線路控制寄存器(LCR ):

位 注釋

Bit7=1 允許訪問波特率因子寄存器

Bit7=0 允許訪問接收/發(fā)送及中斷允許寄存器

Bit6 設(shè)置間斷,0-禁止,1-設(shè)置

Bit5:3=XX0 無校驗

Bit5:3=001 奇校驗

Bit5:3=011 偶校驗

Bit5:3=101 奇偶保持為1

Bit5:3=111 奇偶保持為0

Bit2=0 1位停止位

Bit2=1 2位停止位(數(shù)據(jù)位6-8位),1.5位停止位(5位數(shù)據(jù)位)

Bit1:0=00 5位數(shù)據(jù)位

Bit1:0=01 6位數(shù)據(jù)位

Bit1:0=10 7位數(shù)據(jù)位

Bit1:0=11 8位數(shù)據(jù)位

LCR 用來設(shè)定通訊所需的一些基本參數(shù)。Bit7為1指定波特率因子寄存器有效,為0則指定發(fā)送/接收及IER 有效。Bit6置1會將發(fā)送端置為0,這將會使接收端產(chǎn)生一個“間斷”。Bit3-5用來設(shè)定是否使用奇偶校驗以及奇偶校驗的類型,Bit3=1時使用校驗,Bit4為0則為奇校驗,1為偶校驗,而Bit5則強(qiáng)制校驗為1或0,并由Bit4決定具體為0或

1。Bit2用來設(shè)定停止位的長度,0表示1位停止位,為1則根據(jù)數(shù)據(jù)長度的不同使用

1.5-2位停止位。Bit0:1用來設(shè)定數(shù)據(jù)長度。

MODEM 控制寄存器(MCR ):

位 注釋

Bit7 未使用

Bit6 未使用

Bit5 自動流量控制(僅16750)

Bit4 環(huán)路測試

Bit3 輔助輸出2

Bit2 輔助輸出1

,

Bit1 設(shè)置RTS

Bit0 設(shè)置DSR

MCR 寄存器可讀可寫,Bit4=1進(jìn)入環(huán)路測試模式。Bit3-0用來控制對應(yīng)的管腳。 線路狀態(tài)寄存器(LSR ):

位 注釋

Bit7 FIFO 中接收數(shù)據(jù)錯誤

Bit6 發(fā)送移位寄存器空

Bit5 發(fā)送保持寄存器空

Bit4 間斷

Bit3 幀格式錯

Bit2 奇偶錯

Bit1 超越錯

Bit0 接收數(shù)據(jù)就緒

LSR 為只讀寄存器,當(dāng)發(fā)生錯誤時Bit7為1,Bit6為1時標(biāo)示發(fā)送保持及發(fā)送移位寄存器均空,Bit5為1時標(biāo)示僅發(fā)送保持寄存器空,此時,可以由軟件發(fā)送下一數(shù)據(jù)。當(dāng)線路狀態(tài)為0時Bit4置位為1,幀格式錯時Bit3置位為1,奇偶錯和超越錯分別將Bit2及Bit1置位為1。Bit0置位為1表示接收數(shù)據(jù)就緒。

MODEM 狀態(tài)寄存器(MSR ):

位 注釋

Bit7 載波檢測

Bit6 響鈴指示

Bit5 DSR 準(zhǔn)備就緒

Bit4 CTS 有效

Bit3 DCD 已改變

Bit2 RI 已改變

Bit1 DSR 已改變

Bit0 CTS 已改變

MSR 寄存器的高4位分別對應(yīng)MODEM 的狀態(tài)線,低4位表示MODEM 的狀態(tài)線是否發(fā)生了變化。

以上我們詳細(xì)介紹了PC 機(jī)的串行通訊硬件環(huán)境,以下將分別給出使用查詢及中斷驅(qū)動的方法編寫的串行口驅(qū)動程序。這些程序僅使用RXD/TXD,無需硬件握手信號。

(2)使用查詢方法的串行通訊程序設(shè)計

CODE: [Copy to clipboard]

polling.c

#include

#include

#include

#define PortBase 0x2F8

void com_putch(unsigned char);

int com_chkch(void);

main()

,

{

int c;

unsigned char ch;

outportb(PortBase 1 , 0); /* Turn off interrupts - Port1 *//* Set COM1: 9600,8,N,1*/

outportb(PortBase 3 , 0x80);

outportb(PortBase 0 , 0x0C);

outportb(PortBase 1 , 0x00);

outportb(PortBase 3 , 0x03);

clrscr();

while(1) {

c = com_chkch();

if(c!=-1) {

c &= 0xff; putch(c);

if(c=='n') putch('r');

}

if(kbhit()) {

ch = getch(); com_putch(ch);

}

}

}

void com_putch(unsigned char ch) {

unsigned char status;

while(1) {

status = inportb(PortBase 5);

if(status&0x01) inportb(PortBase 0); else break;

}

outportb(PortBase,ch);

}

int com_chkch(void) {

unsigned char status;

status = inportb(PortBase 5);

status &= 0x01;

if(status) return((int)inportb(PortBase 0)); else return(-1);

}

使用查詢方式的通訊程序適合9600bps 以下的應(yīng)用。

,

(3)使用中斷的串行通訊程序設(shè)計

該程序由兩部分組成,serial.c 及sercom.c ,sercom.c 為通訊的底層驅(qū)動,使用中斷的串行通訊程序可以工作到115.2Kbps.

CODE: [Copy to clipboard]

serial.c

#include

#include

#include

#include

#include

#include "sercom.c"

COM *c;

main()

{

unsigned char ch;

c =

ser_init( PORT_B,BAUD_9600,_COM_CHR8,_COM_NOPARITY,4096,4096 ); while(1) {

if( serhit(c)) {

ch = getser(c);

putchar(ch);

}

if(kbhit()) {

ch = getch();

putser(ch,c);

}

}

}

llio.c

#include

#include

#include

#include

#define CR 0x0d

#define TRUE 0xff

#define FALSE 0

#define PORT_A 0 /* COM1 */

#define PORT_B 1 /* COM2 */

,

#define BAUD_9600 _COM_9600

#define BAUD_4800 _COM_4800

#define BAUD_2400 _COM_2400

#define BAUD_1200 _COM_1200

#define BAUD_600 _COM_600

#define BAUD_300 _COM_300

#define BAUD_110 _COM_110

typedef struct {

char ready; /* TRUE when ready */

unsigned com_base; /* 8250 Base Address */

char irq_mask; /* IRQ Enable Mask */

char irq_eoi; /* EOI reply for this port */ char int_number; /* Interrupt # used */

void (_interrupt _far *old)( void ); /* Old Interrupt */

/* Buffers for I/O */

char *in_buf; /* Input buffer */

int in_tail; /* Input buffer TAIL ptr */ int in_head; /* Input buffer HEAD ptr */ int in_size; /* Input buffer size */

int in_crcnt; /* Input count */

char in_mt; /* Input buffer FLAG */

char *out_buf; /* Output buffer */

int out_tail; /* Output buffer TAIL ptr */ int out_head; /* Output buffer HEAD ptr */ int out_size; /* Output buffer size */

char out_full; /* Output buffer FLAG */

char out_mt; /* Output buffer MT */

} COM;

COM *ser_init( int port,int baud,int bit,int parity,int isize,int osize );

void ser_close( COM *c );

int getsers( COM *c,int len,char *str );

int putsers( char *str, COM *c );

char serline( COM *c );

int getser( COM *c );

,

char serhit(COM *c);

char putser(char outch,COM *c);

void cntl_rts(int flag,COM *c);

void cntl_dtr(int flag,COM *c);

void clean_ser( COM *c );

#define COM1_BASE 0x03F8

#define COM1_IRQ_MASK 0xEF /*11101111B IRQ 4 For COM1 */

#define COM1_IRQ_EOI 0x64 /* IRQ 4 Spec EOI */ #define COM1_INT_NUM 0x0C /* Int # for IRQ4 */

#define COM2_BASE 0x02F8

#define COM2_IRQ_MASK 0xF7 /*11110111B IRQ 3 For COM2 */

#define COM2_IRQ_EOI 0x63 /* IRQ 3 Spec EOI */ #define COM2_INT_NUM 0x0B /* Int # for IRQ3 */

/* 8250 ACE register defs */

#define THR 0 /* Offset to Xmit hld reg (write) */ #define RBR 0 /* Receiver holding buffer (read) */ #define IER 1 /* Interrupt enable register */ #define IIR 2 /* Interrupt identification reg */ #define LCR 3 /* Line control register */

#define MCR 4 /* Modem control register */

#define LSR 5 /* Line status register */

#define MSR 6 /* Modem status register */

#define SREG(x) ((unsigned)((unsigned)x c->com_base))

/* 8259 Int controller registers */

#define INTC_MASK 0x21 /* Interrupt controller MASK reg */

#define INTC_EOI 0x20 /* Interrupt controller EOI reg */

#define MAX_PORTS 2 /* # I/O ports (DOS limit) */ static int count = 0;

static COM com_list[MAX_PORTS]; /* I/O data structure */

,

static COM *com1; /* Pointers for interrupt actions */

static COM *com2;

static COM *com_xfer; /* Transfer interrupt data structure */

COM *ser_init0(int port,char *ibuf,int isize, char *obuf,int osize);

void ser_close0( COM *c );

void (_interrupt _far int_ser1)( void ); /* Int rtn for serial I/O COM 1 */

void (_interrupt _far int_ser2)( void ); /* Int rtn for serial I/O COM 2 */

void (_interrupt _far int_ser_sup)( void ); /* Support int actions */

COM *ser_init( int port,int baud,int bit,int parity,int isize,int osize )

{

unsigned status;

char ch;

COM *c;

char *in_buf,*out_buf;

status = _bios_serialcom(_COM_INIT,port,(bit | parity | _COM_STOP2| baud ));

in_buf = malloc( isize );

if( in_buf == NULL ) return( NULL );

out_buf = malloc( osize );

if( out_buf == NULL ) return( NULL );

c = ser_init0(port,in_buf,isize,out_buf,osize );

clean_ser(c);

return( c );

}

標(biāo)簽: