⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 can841.c

📁 PCL的一个原代码,工业控制和数据处理,自控方面的一个小东东.
💻 C
📖 第 1 页 / 共 2 页
字号:

/*--------------------------------------
FILE NAME       : can841.C
VERSION         : V1.0
--------------------------------------*/
#include "can841.h"
#include <dos.h>

#define IRQ_POLLING     0
#define NULL            0
/*--------------------------------------------------------------------------*/
BYTE gIrq0, gIrq1;
BYTE old_irq0=IRQ_POLLING;
BYTE old_irq1=IRQ_POLLING;
UI   gSeg;
int hw_ok=0;
BYTE protocol1=CANBUS_PROTOCOL_20A;/*add by jinzhong*/
BYTE protocol2=CANBUS_PROTOCOL_20A;/*add by jinzhong*/

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];
}
BYTE g_Data1=0,g_Data2=0;
/*--------------------------------------------------------------------------*/
int canInitHW( UI segment, BYTE irq0, BYTE irq1)
{
  BYTE data=0, data2=0;
  BYTE int_no;

  /*-----------------------
  If app. call this function again, error it.
  --------------------------*/
  /*-----------------------
  if( hw_ok!=0)
  {
    can_err_no=0x1;
    return(0);
  }
  -------------------------*/
  if( segment >0xef00 || segment <0xc800 ||(segment%0x100))
  {
    can_err_no=0x10;
    return(0);
  }
  gSeg=segment;
  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);
  }

  data=can1r(0);
  if( data &0x01)
  {
	  can1w(0,0x60);
	  if(can1r(0) &0x01)
	  {
		  can_err_no=0x10;
		  return(0);
	  }
  }
  can_reset(1);
  if(!(can1r(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)
    {
      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);
      data2=inportb(0xA1);
      g_Data1 = data;
      g_Data2 = data2;
      disable();
      getIntNo(gIrq0,&int_no);
      setvect(int_no,can_isr0);

      if(gIrq0 < 8 )
      {
	 outportb(0x21,data&(~(1<<gIrq0)));
         outportb(0xA1,data2);
      }
      else
      {
         outportb(0x21,data);
	 outportb(0xA1,data2&(~(1<<(gIrq0-8))));
      }
      enable();
      outportb(0x20,0x20);
      outportb(0xA0,0x20);
    }
  }

  gIrq1=irq1;
  if( gIrq1 != old_irq1)
  {
    /*---- restore old irq int service routine -------*/
    if( old_irq1 !=IRQ_POLLING)
    {
      disable();
      getIntNo(old_irq1, &int_no);
      setvect(int_no,old_isr1);
      enable();
      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);
      data2=inportb(0xA1);
      g_Data1=data;
      g_Data2=data2;
      disable();
      getIntNo(gIrq1, &int_no);
      setvect(int_no,can_isr1);
      if(gIrq1 < 8 )
      {
	 outportb(0x21,data&(~(1<<gIrq1)));
         outportb(0xA1,data2);
      }
      else
      {
         outportb(0x21,data);
	 outportb(0xA1,data2&(~(1<<(gIrq1-8))));
      }
      enable();
      outportb(0x20,0x20);
      outportb(0xA0,0x20);
    }
  }

  hw_ok=1;
  return(1);
}
/*--------------------------------------------------------------------------*/
BYTE rBuf0[10], rBuf1[10];
BYTE rBufex0[13];
BYTE rBufex1[13];
CAN_RD_FIFO_T READ_FIFO0,READ_FIFO1;
CAN_RD_FIFO_EX_T  READ_FIFO_EX0,READ_FIFO_EX1;
BYTE gSendFlag0, gSendFlag1;
/*--------------------------------------------------------------------------*/
void interrupt can_isr0()
{
   unsigned char flag;
   long head,temp1,temp2;
   int i;
   pMSG_STRUCT pcan_msg;
   PCAN_MSG_T_EX pcan_msgex;
   disable();
   if(protocol1==CANBUS_PROTOCOL_20A)
   {

	   flag=can0r(3);
	   if( flag & 1) /* RIF */
	   {
		  head = READ_FIFO0.head;
		  pcan_msg= (MSG_STRUCT *)&READ_FIFO0.buffer[head];
		  temp1=can0r(20);
		  temp2=can0r(21);
		  pcan_msg->id = temp1;
		  pcan_msg->id <<= 3;
		  pcan_msg->id |= temp2>>5;
		  pcan_msg->rtr = (temp2>>4)&1;
		  pcan_msg->dlen = temp2&0x0f;
		  for(i=0; i< pcan_msg->dlen; i++)
			 pcan_msg->data[i]=can0r(22+i);
		  for(i=pcan_msg->dlen; i < 8; i++ )
			 pcan_msg->data[i] = 0;
		  READ_FIFO0.head += CAN_MSG_LEN;
		  if(READ_FIFO0.head == RD_FIFO_LEN )
		  {
			 READ_FIFO0.status = FIFO_FULL;
			 READ_FIFO0.head %= RD_FIFO_LEN;
		  }
		  if(READ_FIFO0.status == FIFO_FULL )
		  {
			 if(READ_FIFO0.head == READ_FIFO0.tail )
			 {
				READ_FIFO0.tail += CAN_MSG_LEN;
				if(READ_FIFO0.tail == RD_FIFO_LEN)
				{
				   READ_FIFO0.status = FIFO_OK;
				   READ_FIFO0.tail %= RD_FIFO_LEN;
				}
			 }
		  }
		  /* release receive buffer*/
		  can0w(1,4);
	   }
	   if( flag & 2) /* TIF */
	   {
		  gSendFlag0=1;
	   }
	   outportb(0x20,0x20);
	   outportb(0xA0,0x20);
	   enable();
   }
   /*add by jinzhong*/
   if(protocol1==CANBUS_PROTOCOL_20B) 
   {
  
	   flag=can0r(3);
	   if( flag & 1) /* RIF */
	   {
		   head = READ_FIFO_EX0.head;
		   pcan_msgex= (CAN_MSG_T_EX *)&READ_FIFO_EX0.buffer[head];
		   temp1=can0r(16);
		   pcan_msgex->ff   = ( temp1 & 0x80 );
		   pcan_msgex->dlen = ( temp1 & 0x0f );
		   pcan_msgex->rtr  = ( temp1 >> 6) & 1;
		   if ( pcan_msgex->ff == PELICAN_SFF )
		   {
			   temp2 = can0r(17);
			   pcan_msgex->id = temp2 << 3;
			   temp2 = can0r(18);
			   pcan_msgex->id |= temp2 >> 5;
			   for ( i = 0; i < pcan_msgex->dlen; i++ )
			  	   pcan_msgex->data[i] =  can0r(19+i);
					   
		   }
		   else
		   {
			   temp2 = can0r(17);
			   pcan_msgex->id = temp2 << 21;
			   temp2 = can0r(18);
			   pcan_msgex->id |= temp2 << 13;
			   temp2 = can0r(19);
			   pcan_msgex->id |= temp2 << 5;
			   temp2 = can0r(20);
			   pcan_msgex->id |= temp2 >> 3;
			   for ( i = 0; i < pcan_msgex->dlen; i++ )
				   pcan_msgex->data[i] =  can0r(21+i);
		   }
		   
		   READ_FIFO_EX0.head += CAN_MSG_EX_LEN;
		   if(READ_FIFO_EX0.head == RD_FIFO_EX_LEN )
		   {
			   READ_FIFO_EX0.status = FIFO_FULL;
			   READ_FIFO_EX0.head %= RD_FIFO_EX_LEN;
		   }
		   if(READ_FIFO_EX0.status == FIFO_FULL )
		   {
			   if(READ_FIFO_EX0.head == READ_FIFO_EX0.tail )
			   {
				   READ_FIFO_EX0.tail += CAN_MSG_EX_LEN;
				   if(READ_FIFO_EX0.tail == RD_FIFO_EX_LEN)
				   {
					   READ_FIFO_EX0.status = FIFO_OK;
					   READ_FIFO_EX0.tail %= RD_FIFO_EX_LEN;
				   }
			   }
		   }
		   /* release receive buffer*/
		   can0w(1,4);
	   }
	   if( flag & 2) /* TIF */
	   {
		   gSendFlag0=1;
	   }
	   outportb(0x20,0x20);
	   outportb(0xA0,0x20);
	   enable();
   }
   /*end added*/
}
/*--------------------------------------------------------------------------*/
void interrupt can_isr1()
{
   unsigned char flag;
   int i=0;
   long head,temp1,temp2;
   pMSG_STRUCT pcan_msg;
   PCAN_MSG_T_EX pcan_msgex;
   disable();
   if(protocol2==CANBUS_PROTOCOL_20A)
   {

	   flag=can1r(3);
	   if( flag & 1) /* RIF */
	   {
		  head = READ_FIFO1.head;
		  pcan_msg= (MSG_STRUCT *)&READ_FIFO1.buffer[head];
		  temp1=can1r(20);
		  temp2=can1r(21);
		  pcan_msg->id = temp1;
		  pcan_msg->id <<= 3;
		  pcan_msg->id |= temp2>>5;
		  pcan_msg->rtr = (temp2>>4)&1;
		  pcan_msg->dlen = temp2&0x0f;
		  for(i=0; i< pcan_msg->dlen; i++)
			 pcan_msg->data[i]=can1r(22+i);
		  for(i=pcan_msg->dlen; i < 8; i++ )
			 pcan_msg->data[i] = 0;
		  READ_FIFO1.head += CAN_MSG_LEN;
		  if(READ_FIFO1.head == RD_FIFO_LEN )
		  {
			 READ_FIFO1.status = FIFO_FULL;
			 READ_FIFO1.head %= RD_FIFO_LEN;
		  }
		  if(READ_FIFO1.status == FIFO_FULL )
		  {
			 if(READ_FIFO1.head == READ_FIFO1.tail )
			 {
				READ_FIFO1.tail += CAN_MSG_LEN;
				if(READ_FIFO1.tail == RD_FIFO_LEN)
				{
				   READ_FIFO1.status = FIFO_OK;
				   READ_FIFO1.tail %= RD_FIFO_LEN;
				}
			 }
		  }
		  /* release receive buffer*/
		  can1w(1,4);
	   }
	   if( flag & 2) /* TIF */
	   {
		  gSendFlag1=1;
	   }
	   outportb(0x20,0x20);
	   outportb(0xA0,0x20);
	   enable();
   }
   /*add by jinzhong*/
   if(protocol2==CANBUS_PROTOCOL_20B)
   {
  
	   flag=can1r(3);
	   if( flag & 1) /* RIF */
	   {
		   head = READ_FIFO_EX1.head;
		   pcan_msgex= (CAN_MSG_T_EX *)&READ_FIFO_EX1.buffer[head];
		   temp1=can1r(16);
		   pcan_msgex->ff   = ( temp1 & 0x80 );
		   pcan_msgex->dlen = ( temp1 & 0x0f );
		   pcan_msgex->rtr  = ( temp1 >> 6) & 1;
		   if ( pcan_msgex->ff == PELICAN_SFF )
		   {
			   temp2 = can1r(17);
			   pcan_msgex->id = temp2 << 3;
			   temp2 = can1r(18);
			   pcan_msgex->id |= temp2 >> 5;
			   for ( i = 0; i < pcan_msgex->dlen; i++ )
				   pcan_msgex->data[i] =  can1r(19+i);
			   
		   }
		   else
		   {
			   temp2 = can1r(17);
			   pcan_msgex->id = temp2 << 21;
			   temp2 = can1r(18);
			   pcan_msgex->id |= temp2 << 13;
			   temp2 = can1r(19);
			   pcan_msgex->id |= temp2 << 5;
			   temp2 = can1r(20);
			   pcan_msgex->id |= temp2 >> 3;
			   for ( i = 0; i < pcan_msgex->dlen; i++ )
				   pcan_msgex->data[i] =  can1r(21+i);
		   }
		   
		   READ_FIFO_EX1.head += CAN_MSG_EX_LEN;
		   if(READ_FIFO_EX1.head == RD_FIFO_EX_LEN )
		   {
			   READ_FIFO_EX1.status = FIFO_FULL;
			   READ_FIFO_EX1.head %= RD_FIFO_EX_LEN;
		   }
		   if(READ_FIFO_EX1.status == FIFO_FULL )
		   {
			   if(READ_FIFO_EX1.head == READ_FIFO_EX1.tail )
			   {
				   READ_FIFO_EX1.tail += CAN_MSG_EX_LEN;
				   if(READ_FIFO_EX1.tail == RD_FIFO_EX_LEN)
				   {
					   READ_FIFO_EX1.status = FIFO_OK;
					   READ_FIFO_EX1.tail %= RD_FIFO_EX_LEN;
				   }
			   }
		   }
		   /* release receive buffer*/
		   can1w(1,4);
	   }
	   if( flag & 2) /* TIF */
	   {
		   gSendFlag1=1;
	   }
	   outportb(0x20,0x20);
	   outportb(0xA0,0x20);
	   enable();
   }
   /*end added*/
}
/*--------------------------------------------------------------------------*/
void  can_reset( BYTE port )
{

	BYTE huge *ptr=MK_FP(gSeg,0x100+0x200*port);
	BYTE a;

	a=*ptr;
	*ptr=a;
	if(port==0)
	{
	   READ_FIFO0.head = READ_FIFO0.tail = 0;
	   READ_FIFO0.status = FIFO_OK;
	   READ_FIFO_EX0.head=READ_FIFO_EX0.tail = 0;
	   READ_FIFO_EX0.status = FIFO_OK;
	}
	else
	{
	   READ_FIFO1.head = READ_FIFO1.tail = 0;
	   READ_FIFO1.status = FIFO_OK;
	   READ_FIFO_EX1.head=READ_FIFO_EX1.tail = 0;
	   READ_FIFO_EX1.status = FIFO_OK;
	}
	delay(100);
}
/*--------------------------------------------------------------------------*/
void can0w(BYTE addr, BYTE v)
{
	BYTE huge *ptr;
	ptr = MK_FP( gSeg,addr);
	*ptr=v;
}
/*--------------------------------------------------------------------------*/
void can1w(BYTE addr, BYTE v)
{
	BYTE huge *ptr;
	ptr = MK_FP( gSeg,addr+0x200);
	*ptr=v;
}
/*--------------------------------------------------------------------------*/
BYTE can0r( BYTE addr)
{
  BYTE v;
  BYTE huge *ptr;
	ptr = MK_FP(gSeg,addr);
	v=*ptr;
	return(v);
}
/*--------------------------------------------------------------------------*/
BYTE can1r( BYTE addr)
{
  BYTE v;
  BYTE huge *ptr;
	ptr = MK_FP(gSeg,addr+0x200);
	v=*ptr;
	return(v);
}
/*--------------------------------------------------------------------------*/
BYTE canExitHW()
{
  BYTE b1=inportb(0x21);
  BYTE b2=inportb(0xA1);
  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_irq1,&int_no);
       setvect(int_no,old_isr1);
       old_irq1=IRQ_POLLING;
  }
  if(gIrq0!= IRQ_POLLING || gIrq1 != IRQ_POLLING )
  {
	outportb(0x21,g_Data1);
	outportb(0xA1,g_Data2);
  }
  else
  {
	outportb(0x21,b1);
	outportb(0xA1,b2);
  }
  enable();
  return(1);
}
/*--------------------------------------------------------------------------*/
int  canReset( BYTE port )
{
  can_reset( port );
  return(1);
}
/*--------------------------------------------------------------------------*/
int  canConfig( BYTE port, CAN_STRUCT can)
{
  BYTE temp=0;
  BYTE v=0;
  unsigned int tag;
  canReset( port );
  if( port ==0)
	can.protocoltype=protocol1;
  else can.protocoltype=protocol2;
  if(can.protocoltype==CANBUS_PROTOCOL_20A)
  {
	  	  /*add by jinzhong*/
	  if( port==0)
	  {
		  can0w(0,1);
		  v=can0r(0x100);
		  can0w(0x100,v);
		  can0w(0,1);
		  delay(800);
		  v=can0r(31);
		  v &=0x7f;
		  can0w(31,v);
		  delay(800);
	  }
	  else
	  {
		  can1w(0,1);
		  v=can1r(0x100);
		  can1w(0x100,v);
		  can1w(0,1);
		  delay(800);
		  v=can1r(31);
		  v &=0x7f;
		  can1w(31,v);
		  delay(800);
	  }
	  /*end added*/
	  if( port ==0)
	  {
		if( gIrq0 == IRQ_POLLING)
		 can0w(0,1);
		else
		 can0w(0,3);/* reset mode and receive irq */
		delay(800);
	  }
	  else
	  {
		if( gIrq1 == IRQ_POLLING)
		  can1w(0,1);
		else
		 can1w(0,3);/* reset mode and receive irq */
		delay(800);
	  }

	  if( port ==0)
	  {
		 can0w(6,can.bt0); /* BT0 */
		 can0w(7,can.bt1); /* BT1 */
		 delay(500);
		 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 */
		 delay(500);
		 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);
  }
  /*add by jinzhong*/
  if(can.protocoltype==CANBUS_PROTOCOL_20B)
  {
	  if (port==0)
	  {
		  can0w(0,1);
		  v=can0r(0x100);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -