24小时热门版块排行榜    

查看: 337  |  回复: 0

AH_Shyun

新虫 (初入文坛)

[交流] 【求助】求达人解读一串口调试程序

下面是老师给的一个嵌入式系统中串口调试程序,但是我看不大懂,求高手将程序划分功能模块,并对每个模块中的程序做尽量详细一点的注释,有金币奖励,酌情加赏
#include "serial.h"
#include
#include

//long int test_gnd_status=0;
//long int test_rem_status=0;

extern        void        SBC_SetBitInIMR  (unsigned char idx);
extern        void        SBC_ClearBitInIMR(unsigned char idx);
unsigned char   Status;
//Define Register ID
#define        THR                0                //transmit
#define        RDR                0                //receive
#define        BAUD_L        0                //baud rate low
#define        BAUD_H        1                //baud rate high
#define        IER                1                //Interrupt enable register
#define        IIR                2                //Interrupt index reg. (read)
#define        LCR                3                //Line control register(write)
#define        MCR                4                //Modem control reg. (write)
#define        LSR                5                //Line status(read)
#define        MSR                6                //Modem status(read)

struct        CPARAM        {
        unsigned                                base;
        volatile unsigned char        Rxhead,Rxtail,RxBuf[256];
        volatile unsigned char        Txhead,Txtail,TxBuf[256];
} SIO[8];

static        int                ComSum = 0;                //Serial ports total numbers
static        int                ISR_ComSum = 0;        //ISR vector numbers
static        int                id[4];
static        void _interrupt _far isr_com1(void);
static        void _interrupt _far isr_com2(void);
static        void _interrupt _far isr_com3(void);
static        void _interrupt _far isr_com4(void);
//
//int        Com4_Open( int com, unsigned baud, unsigned char mode )
//
//Return: 0=success; -1=fail
//
int                Com_Open(int base, int baud, unsigned char mode, char isr_num)
{
        unsigned char        B, LSB, MSB;
        int                                com;
       
//--[1]--Set Baud Rate
        B = _inp(base+LCR);        B = B | 0x80;        //Set B7
        _outp(base+LCR, B );
       
        LSB = baud & 0x00FF;        MSB = (baud & 0xFF00) / 256;
        _outp( base+BAUD_L, LSB );
        _outp( base+BAUD_H, MSB );
       
//--[2]--Set Line Control Register (LCR)
        B = inp( base+LCR );        B = B & 0x7F;                //Clear B7
        _outp( base+LCR, B );
    _outp( base+LCR, mode );
   
//--[3]--Set Interrupt Enable Register (IER)
        if (isr_num<0) {
            _outp(base+IER, 0x0); //关中断
            _outp(base+MCR, 0x0); //不用的MODEM控制寄存器清零
    }
    else {
            _outp( base+IER, 0x1 );        //Rx Enabled
                _outp( base+MCR, 0x0B );        //ISR enabled
        }

//--[4]--检查port是否存在
        B = _inp(base+LCR);
        if (B!=mode)        com = -1;
        else {
                com = ComSum ++;                SIO[com].base   = base;
                SIO[com].Txhead = 0;        SIO[com].Txtail = 0;
                SIO[com].Rxhead = 0;        SIO[com].Rxtail = 0;
                if (isr_num>=0) {
                        id[ISR_ComSum] = com;
                        SBC_SetBitInIMR(isr_num);
                        switch (ISR_ComSum) {
                                case 0:        if (isr_num<8)        _dos_setvect(isr_num+8,    isr_com1);
                                                else                        _dos_setvect(isr_num+0x68, isr_com1);
                                                break;
                                case 1:        if (isr_num<8)        _dos_setvect(isr_num+8,    isr_com2);
                                                else                        _dos_setvect(isr_num+0x68, isr_com2);
                                                break;
                                case 2:        if (isr_num<8)        _dos_setvect(isr_num+8,    isr_com3);
                                                else                        _dos_setvect(isr_num+0x68, isr_com3);
                                                break;
                                case 3:        if (isr_num<8)        _dos_setvect(isr_num+8,    isr_com4);
                                                else                        _dos_setvect(isr_num+0x68, isr_com4);
                                                break;
                        }
                        SBC_ClearBitInIMR(isr_num);
                        ISR_ComSum ++;
                }
        }
        //printf("ComSum=%d ISR_ComSum=%d com=%d\n", ComSum,ISR_ComSum,com);
        //printf("SIO[com].base=%x\n", SIO[com].base);
        return (com);
}


int                Com_IsRxOK(int com)
{
        unsigned char        B;
       
        if ((com<0) || (com>(ComSum-1)))        return(0);
       
        B = _inp( SIO[com].base+LSR );
        return( B & 0x01 );
}

int         Com_IsTxOK(int com)
{
        unsigned char        B;
       
        if ((com<0) || (com>(ComSum-1)))        return(0);
       
        B = _inp( SIO[com].base+LSR ); Status = B;
        return ((B&0x20)/0x20);
}

//
//int        Com4_LenRx(int com)
//
//Return: -1=fail; other=success
//
/*int         Com_LenRx(int com)
{
        int        len;
       
        if ((com<0) || (com>(ComSum-1)))        return (0);
       
        if ( SIO[com].Rxhead >= SIO[com].Rxtail )
                len = SIO[com].Rxhead - SIO[com].Rxtail;
        else
                len = 256 + SIO[com].Rxhead - SIO[com].Rxtail;
        return (len);
}*/

BYTE         Com_LenRx(int com)
{
        BYTE        len;
       
        if ((com<0) || (com>(ComSum-1)))        return (0);
       
        len = SIO[com].Rxhead - SIO[com].Rxtail;
        return (len);
}

/*int         Com_LenTx(int com)
{
        int        len;
       
        if ((com<0) || (com>(ComSum-1)))        return (0);

        if ( SIO[com].Txhead >= SIO[com].Txtail )
                len = SIO[com].Txhead - SIO[com].Txtail;
        else
                len = 256 + SIO[com].Txhead - SIO[com].Txtail;
        return (len);
}*/

BYTE         Com_LenTx(int com)
{
        BYTE        len;
       
        if ((com<0) || (com>(ComSum-1)))        return (0);

        len = SIO[com].Txhead - SIO[com].Txtail;
        return (len);
}

int         Com_Out(int com, unsigned char *abyte, int nbyte)
{
        int                idx, len, num_out;
       
        if ((com<0) || (com>(ComSum-1)))        return (0);

        len = Com_LenTx(com);
        if ((len+nbyte) <= 256)        num_out = nbyte;
        else                                        num_out = 256 - len;

        for (idx=0; idx                 SIO[com].TxBuf[SIO[com].Txhead++] = *(abyte+idx);

        if (Com_LenTx(com)) {
            _outp( SIO[com].base+IER, 0x3 );        //Rx | Tx Enabled
                for (idx=0;idx<500;idx++);                        //delay for settle down
        }
    return(num_out);
}

               
int          Com_In(int com,  unsigned char *abyte, int nbyte)
{
        int                idx, len, num_in;
       
        if ((com<0) || (com>(ComSum-1)))        return (0);

        len = Com_LenRx(com);
        if (len >= nbyte)        num_in = nbyte;
        else                                num_in = len;

        for (idx=0; idx                  *(abyte+idx) = SIO[com].RxBuf[SIO[com].Rxtail++];
        return (num_in);
}

unsigned char        Com_GetChar(int com)
{
        if ((com<0) || (com>(ComSum-1)))        return (0);
       
        return (_inp(SIO[com].base+RDR));  
}

static        void _interrupt _far isr_com1(void)
{
        static        unsigned char         status;
    static        int        com;
       
        com = id[0];
        status = _inp(SIO[com].base+IIR);
        //test_gnd_status++;
/////////////////////////////////////////////////////////////
       
//        SIO[com].TxBuf[SIO[com].Txtail]=SIO[com].TxBuf[SIO[com].Txhead];
       
//        SIO[com].RxBuf[SIO[com].Rxhead++] = Com_GetChar(com);
//        _outp(SIO[com].base+IER, 0x1); //[make Tx/Rx disabled]
/////////////////////////////////////////////////////////////                               

        do {
                switch (status & 0x06) {
                        case 4:        //[Rx ready]
                                while (Com_IsRxOK(com))
                                        SIO[com].RxBuf[SIO[com].Rxhead++] = Com_GetChar(com);
                                break;
                        case 2:        //[Tx ready]
                                while (Com_IsTxOK(com)) {
                                        _outp(SIO[com].base, SIO[com].TxBuf[SIO[com].Txtail++]);
                                        if (!Com_LenTx(com))         _outp(SIO[com].base+IER, 0x1);
                                                                                        //[make Tx disabled]
                                }
                                break;
                }
                     status = _inp(SIO[com].base+IIR);
    } while ((status & 0x1)==0);
        _outp(0x20,0x20);
}

static        void _interrupt _far isr_com2(void)
{
        static        unsigned char         status;
    static        int        com;
       
        //test_rem_status++;
       
        com = id[1];
        status = _inp(SIO[com].base+IIR);
        do {
                switch (status & 0x06) {
                        case 4:        //[Rx ready]
                                while (Com_IsRxOK(com))
                                        SIO[com].RxBuf[SIO[com].Rxhead++] = Com_GetChar(com);
                                break;
                        case 2:        //[Tx ready]
                                while (Com_IsTxOK(com)) {
                                        _outp(SIO[com].base, SIO[com].TxBuf[SIO[com].Txtail++]);
                                        if (!Com_LenTx(com))         _outp(SIO[com].base+IER, 0x1);
                                                                                        //[make Tx disabled]
                                }
                                break;
                }
                     status = _inp(SIO[com].base+IIR);
    } while ((status & 0x1)==0);
        _outp(0x20,0x20);
}

static        void _interrupt _far isr_com3(void)
{
        static        unsigned char         status;
    static        int        com;
       
        com = id[2];
        status = _inp(SIO[com].base+IIR);
        do {
                switch (status & 0x06) {
                        case 4:        //[Rx ready]
                                while (Com_IsRxOK(com))
                                        SIO[com].RxBuf[SIO[com].Rxhead++] = Com_GetChar(com);
                                break;
                        case 2:        //[Tx ready]
                                while (Com_IsTxOK(com)) {
                                        _outp(SIO[com].base, SIO[com].TxBuf[SIO[com].Txtail++]);
                                        if (!Com_LenTx(com))         _outp(SIO[com].base+IER, 0x1);
                                                                                        //[make Tx disabled]
                                }
                                break;
                }
                     status = _inp(SIO[com].base+IIR);
    } while ((status & 0x1)==0);
        _outp(0x20,0x20);
}

static        void _interrupt _far isr_com4(void)
{
        static        unsigned char         status;
    static        int        com;
       
        com = id[3];
        status = _inp(SIO[com].base+IIR);
        do {
                switch (status & 0x06) {
                        case 4:        //[Rx ready]
                                while (Com_IsRxOK(com))
                                        SIO[com].RxBuf[SIO[com].Rxhead++] = Com_GetChar(com);
                                break;
                        case 2:        //[Tx ready]
                                while (Com_IsTxOK(com)) {
                                        _outp(SIO[com].base, SIO[com].TxBuf[SIO[com].Txtail++]);
                                        if (!Com_LenTx(com))         _outp(SIO[com].base+IER, 0x1);
                                                                                        //[make Tx disabled]
                                }
                                break;
                }
                     status = _inp(SIO[com].base+IIR);
    } while ((status & 0x1)==0);
        _outp(0x20,0x20);
}

//
//void    Com4_NS550(int com, int trigger)
//
void    Com_NS550(int com, int trigger)
{
        if ((com<0) || (com>(ComSum-1)))        return;
        _outp(SIO[com].base+2, trigger+1);
}

void        Com_SetRTS(int com)
{
        unsigned char        B;
       
        if ((com<0) || (com>(ComSum-1)))        return;
       
        B = _inp(SIO[com].base+MCR);
        B = B | 0x02;
        _outp(SIO[com].base+MCR, B);
                       
}

void        Com_ClearRTS(int com)
{
        unsigned char        B;

        if ((com<0) || (com>(ComSum-1)))        return;
       
        B = _inp(SIO[com].base+MCR);
        B = B & 0xFD;
        _outp(SIO[com].base+MCR, B);
}

void         Com_Refresh(int com)
{
        if ((com<0) || (com>(ComSum-1)))        return;

        while (Com_IsRxOK(com))
                SIO[com].RxBuf[SIO[com].Rxhead++] = Com_GetChar(com);
}

int         Com_Out2(int com, unsigned char *abyte, int nbyte)
{
        int                idx;
       
        if ((com<0) || (com>(ComSum-1)))        return (0);

        for (idx=0; idx                 //while ( (_inp(SIO[com].base+LSR) & 0x20)==0 )
                while (!Com_IsTxOK(com));        //waiting for Tx Ready
                _outp( SIO[com].base, *(abyte+idx) );
        }
        return (nbyte);
}

void        Com_PutChar(int com, BYTE Char )
{
        if ((com<0) || (com>(ComSum-1)))        return;
       
        _outp(SIO[com].base+THR, Char);
}

[ Last edited by AH_Shyun on 2010-10-17 at 16:43 ]
回复此楼

» 猜你喜欢

已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
相关版块跳转 我要订阅楼主 AH_Shyun 的主题更新
普通表情 高级回复 (可上传附件)
信息提示
请填处理意见