Программирование прерываний

Тема в разделе "Общие вопросы по С и С++", создана пользователем AntonKos, 26 дек 2008.

  1. AntonKos

    AntonKos Гость

    никто не сталкивался с программированием микроконтроллеров.У меня к МК идут 2 датчика.с одним прога работает.с 2-мя начинаются всевозможные зависания...походу дело в прерываниях.вот текст написанной программы для обработки данных.И циклится в прерываниях.
    [codebox]#define IRQ_POLLING 0
    #define NULL 0
    /*--------------------------------------------------------------------------*/
    BYTE gIrq0, gIrq1;
    BYTE old_irq0=IRQ_POLLING;
    BYTE old_irq1=IRQ_POLLING;
    int hw_ok=0;
    extern SrcSeg;
    extern TagSeg;



    void interrupt (*old_isr0)();
    void interrupt (*old_isr1)();

    void interrupt can_isr0();
    void interrupt can_isr1();

    int can_err_no;
    /*------------------------------------------------
    0: no error
    0x01 : hardware not release.
    0x10: seg_addr set error
    0x11: hardware not set successful
    0x12: irq_no set error
    0x20: bus off
    ------------------------------------------------*/
    /*--------------------------------------------------------------------------*/
    void interrupt can_isr0();
    void interrupt can_isr1();
    void can0w(BYTE addr, BYTE v);
    void can1w(BYTE addr, BYTE v);
    BYTE can0r( BYTE addr);
    BYTE can1r( BYTE addr);
    void can_reset( BYTE port );

    /*--------------------------------------------------------------------------*/
    void getIntNo(BYTE irq_no, BYTE * int_no)
    {
    BYTE int_tbl[16]={
    0xff,0xff,0xff,0x0b,0x0c,0x0d,0x0e,0x0f,
    0xff,0x71,0x72,0x73,0x74,0xff,0xff,0x77
    };
    *int_no = int_tbl[irq_no];
    }
    /*--------------------------------------------------------------------------*/
    int canInitHW( UI segment, BYTE irq0, BYTE irq1)
    {
    BYTE data;
    BYTE int_no;

    /*-----------------------
    If app. call this function again, error it.
    --------------------------*/
    /*-----------------------
    if( hw_ok!=0)
    {
    can_err_no=0x1;
    return(0);
    }
    -------------------------*/
    if( segment >0xdf00 || segment <0xc000 ||(segment%0x100))
    {
    can_err_no=0x10;
    return(0);
    }
    data=can0r(0);
    if( data &0x01)
    {
    can0w(0,0x60);
    if(can0r(0) &0x01)
    {
    can_err_no=0x10;
    return(0);
    }
    }
    can_reset(0);
    if(!(can0r(0) &0x01))
    {
    can_err_no=0x10;
    return(0);
    }
    /*----- irq_set error check. ------------------*/
    if( irq0 != 0 && irq0 != 3 && irq0 != 4 && irq0 !=5 && irq0 !=6 && irq0 !=7
    && irq0 !=9 && irq0 !=10 && irq0 !=11 && irq0 !=12 && irq0 != 15)
    {
    can_err_no=0x12;
    return(0);
    }
    if( irq1 != 0 && irq1 != 3 && irq1 != 4 && irq1 !=5 && irq1 !=6 && irq1 !=7
    && irq1 !=9 && irq1 !=10 && irq1 !=11 && irq1 !=12 && irq1 != 15)
    {
    can_err_no=0x12;
    return(0);
    }
    if( irq0 == irq1 && irq0 !=IRQ_POLLING)
    {
    can_err_no=0x12;
    return(0);
    }
    getIntNo(irq0, &data);
    if( data == 0xff && irq0 !=0)
    {
    can_err_no=0x12;
    return(0);
    }
    getIntNo(irq1, &data);
    if( data == 0xff && irq1 !=0)
    {
    can_err_no=0x12;
    return(0);
    }/*..... irq_set error check. ..................*/

    gIrq0=irq0;
    if( gIrq0 != old_irq0)
    {
    /*---- restore old irq int service routine -------*/
    if( old_irq0 !=IRQ_POLLING)
    {
    data=inportb(0x21);
    outportb(0x21,0xff);
    outportb(0xA1,0xff);
    disable();
    getIntNo(old_irq0, &int_no);
    setvect(int_no,old_isr0);

    enable();

    old_irq0 = IRQ_POLLING;
    }/*.... restore old irq int service routine .......*/

    /*---- set new irq int service routine -------*/
    if( gIrq0 != IRQ_POLLING) /* not polling */
    {
    getIntNo(gIrq0,&int_no);
    old_isr0=getvect(int_no);
    old_irq0 = gIrq0;

    data=inportb(0x21);
    outportb(0x21,0xff);
    disable();
    getIntNo(gIrq0,&int_no);
    setvect(int_no,can_isr0);
    outportb(0x20,0x20);
    enable();
    /*outportb(0x21,data);*/
    outportb(0x21,0);
    outportb(0xA1,1);
    }
    }

    gIrq1=irq1;
    if( gIrq1 != old_irq1)
    {
    /*---- restore old irq int service routine -------*/
    if( old_irq1 !=IRQ_POLLING)
    {
    data=inportb(0x21);
    outportb(0x21,0xff);
    disable();
    getIntNo(old_irq1, &int_no);
    setvect(int_no,old_isr1);
    outportb(0x20,0x20);
    enable();
    outportb(0x21,data);

    old_irq1 = IRQ_POLLING;
    }/*.... restore old irq int service routine .......*/

    /*---- set new irq int service routine -------*/
    if( gIrq1 != IRQ_POLLING) /* not polling */
    {
    getIntNo(gIrq1, &int_no);
    old_isr1=getvect(int_no);
    old_irq1 = gIrq1;

    data=inportb(0x21);
    outportb(0x21,0xff);
    outportb(0xA1,0xff);
    disable();

    getIntNo(gIrq1, &int_no);
    setvect(int_no,can_isr1);

    enable();
    /*outportb(0x21,data);*/
    outportb(0x21,0);
    outportb(0xA1,1);
    }
    }

    hw_ok=1;
    return(1);
    }
    /*--------------------------------------------------------------------------*/
    BYTE rBuf0[10], rBuf1[10];
    BYTE gSendFlag0, gSendFlag1;
    BYTE gRecFlag0, gRecFlag1;
    /*--------------------------------------------------------------------------*/
    void interrupt can_isr0()
    {
    unsigned char flag;
    int i;

    disable();
    flag=can0r(3);
    if( flag & 1) /* RIF */
    {
    rBuf0[0]=can0r(20);
    rBuf0[1]=can0r(21);
    for(i=0; i< (rBuf0[1]&0x0f); i++)
    rBuf0[i+2]=can0r(22+i);
    /* release receive buffer*/
    can0w(1,4);
    gRecFlag0=1;
    }
    if( flag & 2) /* TIF */
    {
    gSendFlag0=1;
    }
    outportb(0x20,0x20);
    outportb(0xA0,0x20);
    enable();
    }
    /*--------------------------------------------------------------------------*/
    void interrupt can_isr1()
    {
    unsigned char flag;
    int i;

    disable();
    flag=can1r(3);
    if( flag & 1) /* RIF */
    {
    rBuf1[0]=can1r(20);
    rBuf1[1]=can1r(21);
    for(i=0; i< (rBuf1[1]&0x0f); i++)
    rBuf1[i+2]=can1r(22+i);
    /* release receive buffer*/
    can1w(1,4);
    gRecFlag1=1;
    }
    if( flag & 2) /* TIF */
    {
    gSendFlag1=1;
    }
    outportb(0x20,0x20);
    outportb(0xA0,0x20);
    enable();
    }
    /*--------------------------------------------------------------------------*/
    void can_reset( BYTE port )
    {

    BYTE huge *ptr;
    BYTE a;

    if (port==0) ptr=MK_FP(SrcSeg,0x100);
    else ptr=MK_FP(TagSeg,0x100);
    a=*ptr;
    *ptr=a;
    delay(100);
    }
    /*--------------------------------------------------------------------------*/
    void can0w(BYTE addr, BYTE v)
    {
    BYTE huge *ptr;
    ptr = MK_FP( SrcSeg,addr);
    *ptr=v;
    }
    /*--------------------------------------------------------------------------*/
    void can1w(BYTE addr, BYTE v)
    {
    BYTE huge *ptr;
    ptr = MK_FP( TagSeg,addr);
    *ptr=v;
    }
    /*--------------------------------------------------------------------------*/
    BYTE can0r( BYTE addr)
    {
    BYTE v;
    BYTE huge *ptr;
    ptr = MK_FP( SrcSeg,addr);
    v=*ptr;
    return(v);
    }
    /*--------------------------------------------------------------------------*/
    BYTE can1r( BYTE addr)
    {
    BYTE v;
    BYTE huge *ptr;
    ptr = MK_FP( TagSeg,addr);
    v=*ptr;
    return(v);
    }
    /*--------------------------------------------------------------------------*/
    void canExitHW (void)

    {
    unsigned char d=inportb(0x21);
    BYTE int_no;
    /* reset old isr */
    outportb(0x21,0xff);
    disable();
    if( old_isr0 != NULL )
    {
    getIntNo(old_irq0,&int_no);
    setvect(int_no,old_isr0);
    old_irq0=IRQ_POLLING;
    }
    if( old_isr1 != NULL )
    {
    getIntNo(old_irq0,&int_no);
    setvect(old_irq1,old_isr1);
    old_irq1=IRQ_POLLING;
    }
    enable();
    outportb(0x21,d);
    }
    /*--------------------------------------------------------------------------*/
    void canReset( BYTE port )
    {
    can_reset( port );
    }
    /*--------------------------------------------------------------------------*/
    int canConfig( BYTE port, CAN_STRUCT can)
    {
    BYTE temp;
    canReset( port );
    /////////////////////////////////////
    // can0w(31,can0r(31)|0x40); // set CBP
    // can1w(31,can1r(31)|0x40); // set CBP
    /////////////////////////////////////
    if( port ==0)
    {
    if( gIrq0 == IRQ_POLLING)
    can0w(0,1);
    else
    can0w(0,3);/* reset mode and receive irq */
    }
    else
    {
    if( gIrq1 == IRQ_POLLING)
    can1w(0,1);
    else
    can1w(0,3);/* reset mode and receive irq */
    }
    if( port ==0)
    {
    can0w(6,can.bt0); /* BT0 */
    can0w(7,can.bt1); /* BT1 */
    temp=can0r(6);
    if( temp !=can.bt0)
    return(0);
    temp=can0r(7);
    if( temp !=can.bt1)
    return(0);
    }
    else
    {
    can1w(6,can.bt0); /* BT0 */
    can1w(7,can.bt1); /* BT1 */
    temp=can1r(6);
    if( temp !=can.bt0)
    return(0);
    temp=can1r(7);
    if( temp !=can.bt1)
    return(0);
    }
    if( port ==0)
    {
    can0w(4,can.acc_code);/* accept code */
    can0w(5,can.acc_mask);/* accept code */
    }
    else
    {
    can1w(4,can.acc_code);/* accept code */
    can1w(5,can.acc_mask);/* accept code */
    }
    if( port ==0)
    {
    can0w(8,0xfa);
    }
    else
    {
    can1w(8,0xfa);
    }
    return(1);
    }
    /*--------------------------------------------------------------------------*/
    void canNormalRun( BYTE port )
    {
    BYTE v;
    if( port ==0)
    {
    v=can0r(0);
    if( v & 1)
    can0w(0,v&0xfe);
    }
    else
    {
    v=can1r(0);
    if( v & 1)
    can1w(0,v&0xfe);
    }
    }
    /*--------------------------------------------------------------------------*/
    int canSendMsg( BYTE port, MSG_STRUCT msg)
    {

    BYTE v;
    BYTE i;

    if( port==0)
    {
    v=msg.id>>3;
    can0w(10,v);
    v=msg.id &7;
    v<<=5;
    if( msg.rtr ==1) v|=0x10; //v = v | 0x10;
    v+=msg.dlen;
    can0w(11,v);

    for(i=0;i<msg.dlen; i++) can0w(12+i,msg.data);

    can0w(1,1);
    while(1) {
    v=can0r(2);
    if( v & 0x40) return( 0);
    if( v &0x08) return( 1);
    }
    }
    else {
    v=msg.id>>3;
    can1w(10,v);
    v=msg.id &7;
    v<<=5;
    if( msg.rtr ==1) v|=0x10;
    v+=msg.dlen;
    can1w(11,v);

    for(i=0;i<msg.dlen; i++) can1w(12+i,msg.data);

    can1w(1,1);

    while(1) {
    v=can1r(2);
    if( v & 0x40) return( 0);
    if( v &0x08) return( 1);
    }
    }
    }
    /*--------------------------------------------------------------------------*/
    int canReceMsg( BYTE port, MSG_STRUCT *msg_ptr)
    {
    BYTE i;

    if( port ==0)
    {
    if( gIrq0 == IRQ_POLLING)
    {
    if( can0r(2)&1)
    {
    rBuf0[0]=can0r(20);
    rBuf0[1]=can0r(21);
    for(i=0; i< (rBuf0[1]&0x0f); i++)
    rBuf0[i+2]=can0r(22+i);
    /* release receive buffer*/
    can0w(1,4);
    gRecFlag0=1;
    }
    }
    if( gRecFlag0 == 1)
    {
    gRecFlag0 = 0;
    msg_ptr->id=rBuf0[0];
    msg_ptr->id <<=3;
    msg_ptr->id |=(rBuf0[1] >>5);
    msg_ptr->rtr =(rBuf0[1]>>4)&1;
    msg_ptr->dlen =rBuf0[1]&0x0f;
    for(i=0;i< msg_ptr->dlen; i++)
    msg_ptr->data=rBuf0[2+i];
    return( 1);
    }
    else
    return( 0);
    }
    else if(port ==1)
    {
    if( gIrq1 == IRQ_POLLING)
    {
    if( can1r(2)&1)
    {
    rBuf1[0]=can1r(20);
    rBuf1[1]=can1r(21);
    for(i=0; i< ( rBuf1[1]&0x0f); i++)
    rBuf1[i+2]=can1r(22+i);
    /* release receive buffer*/
    can1w(1,4);
    gRecFlag1=1;
    }
    }
    if( gRecFlag1 == 1)
    {
    gRecFlag1 = 0;
    msg_ptr->id=rBuf1[0];
    msg_ptr->id <<=3;
    msg_ptr->id |=(rBuf1[1] >>5);
    msg_ptr->rtr =(rBuf1[1]>>4)&1;
    msg_ptr->dlen =rBuf1[1]&0x0f;
    for(i=0;i< msg_ptr->dlen; i++)
    msg_ptr->data=rBuf1[2+i];
    return( 1);
    }
    else
    return( 0);
    }
    else
    return( 0);
    }[/codebox]
     
Загрузка...

Поделиться этой страницей