打印
[ARM入门]

can通讯

[复制链接]
1338|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tangsunsun|  楼主 | 2014-8-28 11:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我用2个lpc1758 can通讯,两个设备随机发送,间隔10--20ms ,一个 ID=0x81 另外一个ID=0x82 ,5次收不到数据就认为通讯超时,现在问题是偶尔会出现超时,持续时间几秒左右,是ID=0x82的设备发送不出去,导致ID=0x81收不到信息。

void Can_Init (void)  
{
LPC_SC->PCONP       |=  (1 << 13);           // Enable power to CAN1 block
    LPC_PINCON->PINSEL1 |=  (0x03 <<  10);       // Pin P0.21 used as RD1 (CAN1)
    LPC_PINCON->PINSEL1 |=  (0x03 <<  12);       // Pin P0.22 used as TD1 (CAN1)
   
    NVIC_EnableIRQ(CAN_IRQn);                    /* Enable CAN interrupt */
    NVIC_SetPriority(CAN_IRQn, 4);
  LPC_CANAF->AFMR = 2;                           /* By default filter is not used */
LPC_CAN1->MOD|=0x01;
LPC_CAN1->GSR =0x00;
    LPC_CAN1->CMR|= 0x04;                       //释放接收缓冲区
    LPC_CAN1->IER = 0x00;                     //重新使能中断
    LPC_CAN1->IER = 0x8D;                     //重新使能中断
   LPC_CAN1->BTR = 0x0036C00F;                 //125k
LPC_CAN1->MOD&=0xFE;
Can_Rx.status=OS_FALSE;
Can_Rx.t=0;
// if(Can1RecSem==0)Can1RecSem=OSSemCreate(0);
}

void Can_Send (CAN_msg *msg)  {
  
if((LPC_CAN1->GSR&(1<<3)))msg->t=OSTimeGet();
if((LPC_CAN1->GSR&(1<<2))==0)LPC_CAN1->CMR |= (1<<1);   //如果有数据未发送,则终止发送
LPC_CAN1->TFI1  = 0x00080000;                       
    LPC_CAN1->TID1 = msg->id;                        
    LPC_CAN1->TDA1 = msg->data;   
    LPC_CAN1->TDB1 = msg->datb;   
    LPC_CAN1->CMR  = 0x23;                           //中文资料有误,5 6 7 为控制3个发送缓冲区
}
void CAN_IRQHandler (void)
{
   volatile uint32 icr;
volatile uint32 dat;
   OSIntEnter();
   icr = LPC_CAN1->ICR;                           /* clear interrupts */
   if (icr & 0x01)           //接收中断
{  
  dat=LPC_CAN1->RFS;
  Can_Rx.id= LPC_CAN1->RID;
  Can_Rx.data=LPC_CAN1->RDA;
  Can_Rx.datb=LPC_CAN1->RDB;
  LPC_CAN1->CMR|= 0x04;                    //释放接收缓冲区
  Can_Rx.t=OSTimeGet();
  Can_Rx.status=OS_TRUE;
  if(insignal.Signal.ID==0)
  {
   Can_Tx.id=0x82;
   Can_Tx.data=insignal.dat;
   Can_Tx.datb=OSTimeGet();
   Can_Send(&Can_Tx);
  }

   }
else tx.ptr+=sprintf((char *)&tx.buf[tx.ptr],"icr=%x\r\n",icr);
   if (icr & 0x02)           //发送中断 不处理
{  
   }
   if (icr & 0x80)           //错误处理
{
  LPC_CAN1->MOD|=0x01;
  LPC_CAN1->GSR &=0x00FF;

  LPC_CAN1->MOD&=0xFE;
   }
   if (icr & 0x08)           //数据超载中断
{  
     LPC_CAN1->CMR |= 0x04;                    //释放接收缓冲区
     LPC_CAN1->CMR|= 0x08;                    //释放超载标志
   }
OSIntExit();
}

相关帖子

沙发
阮天宇00| | 2014-8-28 18:47 | 只看该作者
我这里有can的源码,可惜是Linux下面的

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

28

帖子

0

粉丝