新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > RS232接口規范及編程資料(下)

        RS232接口規范及編程資料(下)

        作者: 時間:2016-12-12 來源:網絡 收藏
        上篇我們詳細介紹了PC機的串行通訊硬件環境,以下將分別給出使用查詢及中斷驅動的方法編寫的串行口驅動程序。這些程序僅使用RXD/TXD,無需硬件握手信號。

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

        本文引用地址:http://www.104case.com/article/201612/328776.htm

        #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以下的應用。

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

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

        #include
        #include
        #include
        #include
        #include
        #include "llio.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);
        }

        }
        }

        #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 );
        }


        void ser_close(COM *c)
        {
        int i;


        if( !c->ready ) return;

        ser_close0(c);

        free( c->in_buf );
        free( c->out_buf );

        }


        char serline( COM *c )
        {

        if( !c->ready ) return(FALSE);

        if( c->in_crcnt > 0 ) return( TRUE );
        else return( FALSE );
        }

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

        i = 0;
        while( i while( !serhit(c) ) {
        if(kbhit()) return( -1 );
        }

        ch = 0x7f & getser(c);
        switch( ch ) {

        case 0x0d: str[i++] =

        主站蜘蛛池模板: 什邡市| 六枝特区| 祁门县| 青铜峡市| 保康县| 乡宁县| 乐东| 邹平县| 张掖市| 星子县| 西华县| 边坝县| 台江县| 营山县| 永胜县| 略阳县| 四会市| 克拉玛依市| 阿拉善盟| 利津县| 鹤岗市| 夏河县| 贵港市| 鄱阳县| 交口县| 易门县| 新蔡县| 扶余县| 龙陵县| 女性| 美姑县| 冀州市| 赤水市| 新疆| 台南市| 阿拉善右旗| 永宁县| 秦皇岛市| 广德县| 远安县| 固始县|