全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:2154
推到 Plurk!
推到 Facebook!

一个串口通信 for Dos 的代码,请帮帮忙看看怎用.

尚未結案
One2Free
一般會員


發表:26
回覆:28
積分:20
註冊:2004-05-12

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-08-10 19:53:03 IP:219.129.xxx.xxx 未訂閱
在一份产品的设计文档中找到一个封装成 Class 的串口通信代码, 可少了 GSERIAL.CPP 文件, 加上对 C++ 不熟悉, 不知道怎样用, 请各位大大帮帮忙,看看怎用,最好能帮忙写个 Demo.谢谢!  
 
/*---------------------------------------------------------------------*
FILENAME: GSERIAL.H
This file is used to define const and class for GSERIAL.CPP
TC   3.0 for DOS
*--------------------------------------------------------------------*/    #define COM1            1
#define COM2            2
#define COM3            3
#define COM4            4
#define COM5            5
#define COM6            6    #define COM1BASE        0x3F8   /*  Base port address for COM1  */
#define COM2BASE        0x2F8   /*  Base port address for COM2  */
#define COM3BASE        0x3E8   /*  Base port address for COM3  */
#define COM4BASE        0x2E8   /*  Base port address for COM4  */
#define COM5BASE        0x3A8   /*  Base port address for COM5  */
#define COM6BASE        0x2A8   /*  Base port address for COM6  */    /*
The 8250 UART has 10 registers accessible through 7 port addresses.
Here are their addresses relative to COM1BASE and COM2BASE. Note
that the baud rate registers, (DLL) and (DLH) are active only when
the Divisor-Latch Access-Bit (DLAB除数锁存器访问位) is on. The (DLAB)
is bit 7 of the (LCR--Line Control Register线路控制寄存器).    * TXR Output data to the serial port.
* RXR Input data from the serial port.
* LCR Initialize the serial port.
* IER Controls interrupt generation.
* IIR Identifies interrupts.
* MCR Send contorl signals to the modem.
* LSR Monitor the status of the serial port.
* MSR Receive status of the modem.
* DLL Low byte of baud rate divisor.
* DHH High byte of baud rate divisor.
*/    /*The following is the adress of the registers               DLAB status    */    #define TXR             0       /*  Transmit register (WRITE)   0           */
#define RXR             0       /*  Receive register  (READ)    0           */
#define IER             1       /*  Interrupt Enable            x           */
#define IIR             2       /*  Interrupt ID                x           */
#define LCR             3       /*  Line control                x           */
#define MCR             4       /*  Modem control               x           */
#define LSR             5       /*  Line Status                 x           */
#define MSR             6       /*  Modem Status                x           */    #define DLL             0       /*  Divisor Latch Low           1           */
#define DLH             1       /*  Divisor latch High          1           */    /*-------------------------------------------------------------------*
Bit values held in the Line Control Register (LCR).
bit     meaning
---     -------
0-1     00=5 bits, 01=6 bits, 10=7 bits, 11=8 bits. /word length select bit
2       Stop bits.                                  /
3       0=parity off, 1=parity on.                  /Parity Enable=1
4       0=parity odd, 1=parity even.                /Odd or Even select
5       Sticky parity.                              /
6       Set break.
7       Toggle port addresses.                      /1:access
*-------------------------------------------------------------------*/    #define LCR_NO_PARITY       0x00
#define LCR_EVEN_PARITY     0x18
#define LCR_ODD_PARITY      0x08    /*-------------------------------------------------------------------*
Bit values held in the Line Status Register (LSR).
bit     meaning
---     -------
0       Data ready.
1       Overrun error - Data register overwritten.
2       Parity error - bad transmission.
3       Framing error - No stop bit was found.
4       Break detect - End to transmission requested.
5       Transmitter holding register is empty.
6       Transmitter shift register is empty.
7               Time out - off line.
*-------------------------------------------------------------------*/    #define LSR_RCVRDY          0x01
#define LSR_OVRERR          0x02
#define LSR_PRTYERR         0x04
#define LSR_FRMERR          0x08
#define LSR_BRKERR          0x10
#define LSR_XMTRDY          0x20
#define LSR_XMTRSR          0x40
#define LSR_TIMEOUT         0x80    /*-------------------------------------------------------------------*
Bit values held in the Modem Output Control Register (MCR).
bit         meaning
---     -------
0       Data Terminal Ready. Computer ready to go.
1       Request To Send. Computer wants to send data.
2       auxillary output #1.
3       auxillary output #2.(Note: This bit must be
                  set to allow the communications card to send
                  interrupts to the system)
4       UART ouput looped back as input.
5-7     not used.
*------------------------------------------------------------------*/    #define MCR_DTR             0x01
#define MCR_RTS             0x02
#define MCR_INT             0x08    /*------------------------------------------------------------------*
Bit values held in the Modem Input Status Register (MSR).
bit     meaning
---     -------
0       delta Clear To Send.
1       delta Data Set Ready.
2       delta Ring Indicator.
3       delta Data Carrier Detect.
4       Clear To Send.
5       Data Set Ready.
6       Ring Indicator.
7       Data Carrier Detect.
*------------------------------------------------------------------*/    #define MSR_CTS             0x10
#define MSR_DSR             0x20    /*------------------------------------------------------------------*
Bit values held in the Interrupt Enable Register (IER).
bit     meaning
---     -------
0       Interrupt when data received.
1       Interrupt when transmitter holding reg. empty.
2       Interrupt when data reception error.
3       Interrupt when change in modem status register.
4-7     Not used.
*------------------------------------------------------------------*/    #define IER_RX_INT          0x01
#define IER_TX_INT          0x02    /*------------------------------------------------------------------*
Bit values held in the Interrupt Identification Register (IIR).
bit     meaning
---     -------
0       Interrupt pending
1-2             Interrupt ID code
00=Change in modem status register,
01=Transmitter holding register empty,
10=Data received,
11=reception error, or break encountered.
3-7     Not used.
*------------------------------------------------------------------*/    #define IIR_MS_ID           0x00   // Modem status
#define IIR_RX_ID           0x04   // Rceived data OK,and to read the receive buffer
#define IIR_TX_ID           0x02   // Transmitter holding register empty
#define IIR_MASK            0x07   // Get the low 3 bits of IIR    /*------------------------------------------------------------------*
These are the port addresses of the 8259 Programmable Interrupt
Controller (PIC).
*------------------------------------------------------------------*/    #define PIC8259_IMR             0x21   /* Interrupt Mask Register port */
#define PIC8259_ICR             0x20   /* Interrupt Control Port       */    /*------------------------------------------------------------------*
An end of interrupt needs to be sent to the Control Port of
the 8259 when a hardware interrupt ends.
*------------------------------------------------------------------*/    #define PIC8259_EOI            0x20   /* End Of Interrupt */    /*------------------------------------------------------------------*
The (IMR) tells the (PIC) to service an interrupt only if it
is not masked (FALSE).
*------------------------------------------------------------------*/    #define IRQ3            0xF7  /* COM2 */
#define IRQ4            0xEF  /* COM1 */    class serial{
        int  flag;
        int  SetSerial();
        int  SetOthers(int Parity, int Bits, int StopBit);
        int  SetSpeed(int Speed);
        int  SetPort(int Port);
        void init_serial(void);
        void comm_on(void);
        void comm_off(void);
public:
        serial(int Port, int Speed, int Parity, int Bits, int StopBit);
        serial &operator<<( char ch );
        serial &operator<<( char *str );
        serial &operator>>( char &ch );
        ~serial();
};    #define VERSION 0x0101
#define FALSE               0
#define TRUE                1
#define NO_ERROR            0       /* No error               */
#define BUF_OVFL            1       /* Buffer overflowed      */
#define IBUF_LEN            2048    // Incoming buffer
#define OBUF_LEN            1024    // Outgoing buffer    extern int            SError          = NO_ERROR;
extern int            portbase        = 0;
extern void           interrupt(*oldvects[2])(...);    //  char  ccbuf[SBUFSIZ];    unsigned int   startbuf        = 0;
unsigned int   endbuf          = 0;
unsigned int   inhead          = 0;
unsigned int   intail          = 0;
unsigned int   outhead         = 0;
unsigned int   outtail         = 0;
char  inbuf[IBUF_LEN];         // in buffer
char  outbuf[OBUF_LEN];        // out buffer    void           interrupt(*oldvects[2])(...);    /*  get status of the port  */
int read_status_com(int portn)
{
        return(inp(portn 5));
}    /*  send one valid char from the port  */
void send_char_com(int portn,int cc)
{
        while ((read_status_com(portn) & 0x40) == 0);
        outportb(portn,cc);
}    /*  send one string from the port  */    void send_string_com(int portn,int strlen,unsigned char *buf)
{
        int k;  k=0;
        do {
                send_char_com(portn,*(buf   k)); k  ;
        } while ((k < strlen));
}    void interrupt com_int(...)
{
        int temp;
        disable();
        temp = (inportb(portbase IIR)) & IIR_MASK;              // why interrupt was called
        switch(temp)
        {
        case 0x00:  // modem status changed
                inportb(portbase MSR);   // read in useless char
                break;
        case 0x02:  // Request To Send char
                if (outhead != outtail)                         // there's a char to send
                {
                        outportb(portbase TXR,outbuf[outhead  ]);   // send the character
                        if (outhead == OBUF_LEN)
                                outhead=0;                              // if at end of buffer, reset pointer
                }
                break;
        case 0x04:  // character ready to be read in
                inbuf[inhead  ] = inportb(portbase RXR);// read character into inbuffer
                if (inhead == IBUF_LEN) // if at end of buffer
                        inhead=0;           // reset pointer
                break;
        case 0x06:  // line status has changed
                inportb(portbase LSR);     // read in useless char
                break;            default:
                break;
        }
        outportb(PIC8259_ICR, PIC8259_EOI); // Signal end of hardware interrupt
        enable();                           // reenable interrupts at the end of the handler
}    // Inserts the character to be outputted into the output buffer, checking
// for an open slot in the output buffer array.  If there is, insert
// the character, or if there isn't, wait until a slot opens up.    serial& serial::operator<<(char ch )
{
        if (ch)                             // If this is a valid char
        {
                enable();                       // turn on irqs to ensure data output
                //outportb(portbase   MCR,  MCR_INT | MCR_DTR | MCR_RTS);//modem control,
                outportb(portbase   IER,  IER_RX_INT);                    // check buffer, and if full, wait for an available opening
                //  fprintf(stdout,"\n %c is pressed!\n",ch);   //You can use this to verify which key is hit during your test
                while((outhead-1==outtail) ||(outtail==OBUF_LEN-1 && outhead==0));
                disable();                      // make sure nothing happens while changing buffer
                outbuf[outtail  ] = ch;         // insert character into buffer;
                if (outtail == OBUF_LEN)        // if at end of out buffer
                        outtail = 0;                // reset pointer
                if((inportb(portbase IER)&IER_TX_INT) == 0)
                        outportb(portbase IER,IER_TX_INT | IER_RX_INT);
                enable();                       // re-enable interrupts
        }
        return(*this);
}    serial &serial::operator<<(char *str)
// Outputs a string to the serial port
{            while (*str)
        {
                (*this) << (*str);
                str  ;
        }
        return(*this);
}    serial &serial::operator>>( char &ch )
// Returns either the character to be received from modem if there is one
// waiting in the buffer, or returns a 0 if there is no character waiting.
{
        if (inhead != intail)               // there is a character
        {
                disable();                        // disable irqs while getting char
                ch = inbuf[intail  ];             // get character from buffer
                if (intail == IBUF_LEN)         // if at end of in buffer
                        intail=0;                   // reset pointer
                enable();                        // re-enable interrupt
                return(*this);                   // return the char
        }
        ch = -1;
        return(*this);                       // return nothing
}    /* Install our functions to handle communications */    void setvects(void)
{
        oldvects[0] = getvect(0x0B);
        oldvects[1] = getvect(0x0C);
        setvect(0x0B, com_int);
        setvect(0x0C, com_int);
}    /* Uninstall our vectors before exiting the program */
void resvects(void)
{
        setvect(0x0B, oldvects[0]);
        setvect(0x0C, oldvects[1]);
}    /* Tell modem that we're ready to go */
void serial::comm_on(void)    {            int temp, pnum;            disable();
        temp = inportb(portbase   MCR) | 0x0f;//MCR_INT;
        outportb(portbase   MCR, temp);
        temp = (inportb(portbase   IER)) | IER_RX_INT;//|IER_TX_INT;
        outportb(portbase   IER, temp);
        pnum = (portbase == COM1BASE ? COM1 : COM2);
        temp = inportb(PIC8259_IMR) & (pnum == COM1 ? IRQ4 : IRQ3);
        outportb(PIC8259_IMR, temp);
        // temp = inportb(portbase   MCR) | MCR_DTR | MCR_RTS;
        // outportb(portbase   MCR, temp);
        enable();
}    /* Go off-line */    void serial::comm_off(void)
{
        int  temp;            disable();
        temp = inportb(PIC8259_IMR) | ~IRQ3 | ~IRQ4;
        outportb(PIC8259_IMR, temp);
        outportb(portbase   IER, 0);
        outportb(portbase   MCR, 0);
        enable();
}        void serial::init_serial(void)
{
        endbuf = startbuf = 0;
        setvects();
        comm_on();
}    serial::~serial()
{
        comm_off();
        resvects();
}    /* Set the port number to use */
int serial::SetPort(int Port)
{
        int  Offset, far *RS232_Addr;
        switch (Port)
        { /* Sort out the base address */
        case COM1 :
                Offset = 0x0000;
                break;
        case COM2 :
                Offset = 0x0002;
                break;
        default   :
                printf("\ncannot find the serial port.\n");
                return (-1);
        }            RS232_Addr = (int far *)MK_FP(0x0040, Offset);  /* Find out where the port is. */
        if (*RS232_Addr == NULL)
        {
                printf("\ncannot find the serial port.\n");
                return (-1);                     /* If NULL then port not used. */
        }            portbase = *RS232_Addr;              /* Otherwise set portbase      */
        return (0);
}    /* This routine sets the speed; will accept funny baud rates. */
/* Setting the speed requires that the DLAB be set on.        */    int serial::SetSpeed(int Speed)
{
        char    c;
        int     divisor;            if (Speed == 0)            /* Avoid divide by zero */
                return (-1);
        else
                divisor = (int) (115200L/Speed);            if (portbase == 0)
                return (-1);                disable();
        c = inportb(portbase   LCR);
        outportb(portbase   LCR, (c | 0x80)); /* Set DLAB */
        outportb(portbase   DLL, (divisor & 0x00FF));
        outportb(portbase   DLH, ((divisor >> 8) & 0x00FF));
        outportb(portbase   LCR, c);          /* Reset DLAB */
        enable();            return (0);
}    /* Set other communications parameters */    int serial::SetOthers(int Parity, int Bits, int StopBit)
{
        int  setting;            if (portbase == 0)
                return (-1);            if (Bits < 5 || Bits > 8)
                return (-1);            if (StopBit != 1 && StopBit != 2)
                return (-1);            if (Parity != LCR_NO_PARITY && Parity != LCR_ODD_PARITY && Parity != LCR_EVEN_PARITY)
                return (-1);            setting  = Bits-5;
        setting |= ((StopBit == 1) ? 0x00 : 0x04);
        setting |= Parity;            disable();
        outportb(portbase   LCR, setting);
        enable();            return (0);    }    /* Set up the port */    serial::serial(int Port, int Speed, int Parity, int Bits, int StopBit)
{
        flag = 0;            if (SetPort(Port))
                flag = -1;            if (SetSpeed(Speed))
                flag = -1;            if (SetOthers(Parity, Bits, StopBit))
                flag = -1;            if (!flag)
                init_serial();
}    /*  Control-Break interrupt handler */    int c_break(void)
{
        int temp;            disable();            temp = inportb(PIC8259_IMR) | ~IRQ3 | ~IRQ4;            outportb(PIC8259_IMR, temp);
        outportb(portbase   IER, 0);
        outportb(portbase   MCR, 0);            enable();            fprintf(stderr, "\nStill online.\n");
        return(0);
}    
ATEIN
高階會員


發表:105
回覆:320
積分:125
註冊:2002-07-05

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-09-02 19:08:31 IP:203.204.xxx.xxx 未訂閱
.CPP 是告訴你要自已寫程式呼叫.h 的實作處 DHM
------
ATEIN
暗黑破壞神
版主


發表:9
回覆:2301
積分:1627
註冊:2004-10-04

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-09-02 20:21:32 IP:210.64.xxx.xxx 未訂閱
幫你看過了。 你的 .h 中所宣告的 大都在自己裏面就做掉了。 應可以不用 .cpp 了。 不然就是自己把宣告以外的部份 移出去,成為 .cpp 就可以了。 http://www.mcu51.com/list.asp?id=1588 想想別人怎麼學,我們有這麼用心嗎? 憂心啊~~~~~~
系統時間:2024-04-26 18:52:52
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!