微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > RS232接口规范及编程资料(下)

RS232接口规范及编程资料(下)

时间:12-12 来源:互联网 点击:

if( i == MAX_PORTS ) /* Not found */
return( NULL );

c->in_buf = ibuf;
c->in_size = isize;
c->in_mt = TRUE;
c->in_head = 0;
c->in_tail = 0;
c->in_crcnt = 0;

c->out_buf = obuf;
c->out_size = osize;
c->out_full = FALSE;
c->out_mt = TRUE;
c->out_head = 0;
c->out_tail = 0;

switch( port ) {

case 0: /* Here set up for COM1 */
c->ready = TRUE;
c->com_base = COM1_BASE;
c->irq_mask = COM1_IRQ_MASK;
c->irq_eoi = COM1_IRQ_EOI;
c->int_number = COM1_INT_NUM;

_disable();

com1 = c;
c->old = _dos_getvect( c->int_number );
_dos_setvect(c->int_number,int_ser1);
break;

case 1: /* Here set up for COM1 */
c->ready = TRUE;
c->com_base = COM2_BASE;
c->irq_mask = COM2_IRQ_MASK;
c->irq_eoi = COM2_IRQ_EOI;
c->int_number = COM2_INT_NUM;

_disable();

com2 = c;
c->old = _dos_getvect( c->int_number );
_dos_setvect(c->int_number,int_ser2);
break;

default: return(NULL); /* Bad port SKIP */
}

val = inp( INTC_MASK );
val &= c->irq_mask;
outp( INTC_MASK, val );

val = inp( SREG(LSR) ); /* Read and discard STATUS */
val = inp( SREG(RBR) ); /* Read and discard DATA */

val = inp( SREG(LCR) ); /* Rst DLAB for IER access */
val &= 0x7F; /* 01111111B */
outp( SREG(LCR),val );

outp( SREG(IER),1); /* Enable Data READY INT */

outp( SREG(MCR),0xB ); /* Enable OUT2,RTS & DTR */

_enable();

return( c );

}

void ser_close0( COM *c )
{
char val;

if( !c->ready ) return;

_disable();

val = inp(INTC_MASK);
val |= ~c->irq_mask;
outp(INTC_MASK,val);

val = inp( SREG(LCR) ); /* Reset DLAB for IER access */
val &= 0x7F; /* Clear IER access bit */
outp(SREG(LCR),val);

val = inp( SREG(RBR) );
val = inp( SREG(LSR));
val = inp(SREG(IIR) );
val = inp(SREG(IER) );
outp(SREG(IER),0); /* Disable 8250 Interrupts */

outp(SREG(MCR),0); /* Disable RTS,DTR and OUT2 */

outp(SREG(MCR),0); /* Disable OUT2 */

_dos_setvect(c->int_number, c->old );

_enable();

c->ready = FALSE;

}

void _interrupt _far int_ser1( void )
{

com_xfer = com1;
_chain_intr( int_ser_sup );
}

void _interrupt _far int_ser2( void )
{

com_xfer = com2;
_chain_intr( int_ser_sup );
}

void _interrupt _far int_ser_sup( void )
{
char val;
char ch;
int ptr;
COM *c;

c = com_xfer;

while( TRUE ) {
val = inp( SREG(LSR) ); /* Read and discard STATUS */
val = inp( SREG(IIR) ); /* Get interrupt status register */

if( val & 0x04 ) /* Receive Interrupt */
{

ptr = c->in_head;
ch = inp( SREG(RBR) );

if( c->in_mt || ptr != c->in_tail ) {
c->in_buf[ptr++] = ch;
if( ptr == c->in_size ) ptr = 0;
c->in_head = ptr;
c->in_mt = FALSE;

if( ch == CR ) /* Count lines */
c->in_crcnt++;
}
} else {
if( val & 0x02 ) /* Transmit Interrupt */
{
if( (!c->out_full) && (c->out_head == c->out_tail) ) {

c->out_mt = TRUE;
val = inp( SREG(LCR) );
val &= 0x7F;
outp(SREG(LCR),val);

outp(SREG(IER),0x01);
/* RX interrupts ON */
} else {

outp(SREG(THR),
c->out_buf[c->out_tail++]);
if( c->out_tail == c->out_size ) c->out_tail = 0;
}
} else return; /* No Interrupt */
}

outp(INTC_EOI,c->irq_eoi);
}
}

(4)MCS-51串行通讯:

MCS-51的串行口使用起来非常简单,因为MCS-51单片机的串行口没有与MODEM控制相关的信号。这使得51的通讯口非常易于使用。使用查询方式时,仅需初始化有关的寄存器即可。演示程序如下:

#include
#include

void putch(unsigned char);
unsigned char getch(void);

main()
{
unsigned char ch;

SCON = 0x50;
TMOD |= 0x20;
TH1 = 0xfd;
TL1 = 0xfd;
TR1 = 1;
TI = 1;
RI = 0;

while(1) {
ch = getch(); putch(ch);

}
}

void putch(unsigned char ch) {

SBUF = ch;
TI = 0;
while(!TI);
}

unsigned char getch(void) {

while(!RI);
RI = 0;
return(SBUF);

}

使用中断驱动的程序比较复杂,下面为完整的MCS-51串行通讯底层驱动程序,由头文件serint.hJ及serint.c组成。

serint.h

unsigned char RR_iHead; /* receiver head index */
unsigned char RR_iTail; /* receiver tail index */
unsigned char RR_cLev; /* receiver buffer count */
unsigned char RR_cMax; /* receiver buffer count */

unsigned char TR_iHead; /* transmitter head index */
unsigned char TR_iTail; /* transmitter tail index */
unsigned char TR_cLev; /* transmitter buffer count */
unsigned char TR_cMax; /* transmitter buffer count */

unsigned char UnGotCh; /* saved char for ungetch() */

unsigned char SerFlags; /* serial flag */

bit FlagTransIdle; /* set when transmitter is finished */
bit FlagStripOutLF; /* dont send linefeeds */
bit FlagCvtInCR; /* convert incoming CR to LF */

unsigned char TestBits;

#define INRINGSIZE 128 /* must be <= 254 to avoid wraps */
#define OUTRINGSIZE 250 /* ditto */

#define T1RELOAD 253

#define CR 13
#define LF 10
#define ESC 27

#define EOF -1

unsigned char xdata RRing[INRINGSIZE]; /* receiver ring buffer */
unsigned char xdata TRing[OUTRINGSIZE]; /* receiver ring buffer */

int putstr (const char *);
int putch(int);
int chkch();
int getch();
void SerWaitOutDone();
int SerFlushIn();
int putc(int TransChar);

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top