RS232接口规范及编程资料(下)
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);
RS232接口规范编程资 相关文章:
- RS232接口规范及编程资料(上)(12-12)
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)