LPC2294-CAN状态寄存器
[ 2007-5-9 15:30:00 | By: CANopen ]
 

LPC2294 CAN Module状态寄存器:

1、每个CAN控制器均带有两个在操作状态下(Normal Operation Mode)只读状态寄存器:CANGSR和CANSR;

2、CANGSR包含全局状态包括每个CAN控制器的发送(TBS、TCS、TS)、接收(RBS、RS)、接收过载(DOS)、错误(ES)及CAN-Bus状态(BS),另外有两个8Bits的Rx/Tx错误计数器;
      CANSR中的RBS、DOS、RS、ES、BS位与CANGSR中的相同,由于每个CAN控制器带三个发送缓冲区,因此CANSR对每个缓存的状态作出更为细致的反馈:
         TBS(发送缓冲区状态)被肢解成三:TBS1,TBS2,TBS3
         TCS(发送完成)被肢解成三:TCS1,TCS2,TCS3
         TS(正在发送)被肢解成三:TS1,TS2,TS3

2、CANGSR与CANSR中寄存器位之间的关系:
         TBS = TBS1 & TBS2 & TBS3 (与操作)
         TCS = TCS1 & TCS2 & TCS3 (与操作)
         TS  = TS1  | TS2  | TS3  (或操作)

3、发送函数中一般应对CANSR查询以决定向某一个空闲的缓冲区写入发送数据;接收函数若采用中断方式应在服务例程末对CANCMR进行操作,以释放接收缓冲区单元同时RBS位清零;

4、发送、接收例程(本例程已通过测试可用):
/*
***************************************************************************************************
*** 函 数 名:CAN_PushMsg
*** 功能描述:CAN数据发送
*** 输入输出:
*** 创建日期:2007-5-7 2:18  by:CANopen
*** 修改日期:2007-5-7 2:18  by:
***************************************************************************************************
*/
void CAN_PushMsg(int8u can_port,CAN_MSG* pTxBuf)
{
 int32u* pAddr=0;
 int8u  tBuf=0;
 if(can_port < 1 || can_port > 2) return;
 
 switch(can_port)
 {
  case 1:
   if(CAN1SR & (__1 << 2))
    {
     pAddr = (int32u *) &(CAN1TFI1);
     tBuf = 1;
     }
   else // tBuf 1 不可用
    {
     if(CAN1SR & (__1 << 10))
      {
       pAddr = (int32u *) &(CAN1TFI2);
       tBuf = 2;
       }
     else // tBuf 2 不可用
      {
       if(CAN1SR & (__1 << 18))
        {
         pAddr = (int32u *) &(CAN1TFI3);
         tBuf = 3;
         }
       else  // tBuf 3 不可用
        return;  // 所有的tBuf都不可用,则返回
       } 
     }
   *pAddr = pTxBuf->Frame;
   
   pAddr++;
   *pAddr = pTxBuf->MsgID;
   
   pAddr++;
   *pAddr = pTxBuf->DatA;
   
   pAddr++;
   *pAddr = pTxBuf->DatB;
   
   switch(tBuf)
   {
    case 1:
     CAN1CMR = 0x21; // 选择tBuf1发送
     break;
    case 2:
     CAN1CMR = 0x41; // 选择tBuf2发送
     break;
    case 3:
     CAN1CMR = 0x81; // 选择tBuf3发送
     break;
    default :
     break;   
    }
   break;
  
  case 2:
   if(CAN2SR & (__1 << 2))
    {
     pAddr = (int32u *) &(CAN2TFI1);
     tBuf = 1;
     }
   else
    {
     if(CAN2SR & (__1 << 10))
      {
       pAddr = (int32u *) &(CAN2TFI2);
       tBuf = 2;
       }
     else
      {
       if(CAN2SR & (__1 << 18))
        {
         pAddr = (int32u *) &(CAN2TFI3);
         tBuf = 3;
         }
       else
        return; 
       } 
     }
   *pAddr = pTxBuf->Frame;  // 相应寄存器装入发送数据Msg
   
   pAddr++;
   *pAddr = pTxBuf->MsgID;
   
   pAddr++;
   *pAddr = pTxBuf->DatA;
   
   pAddr++;
   *pAddr = pTxBuf->DatB;
   
   switch(tBuf)  // 置位发送请求
   {
    case 1:
     CAN2CMR = 0x21;
     break;
    case 2:
     CAN2CMR = 0x41;
     break;
    case 3:
     CAN2CMR = 0x81;
     break;
    default :
     break;   
    }
   break;
   
  default :
   break;  
  }
 }
/*
***************************************************************************************************
*** 函 数 名:CAN2_Rx_ISR
*** 功能描述:CAN数据接收,中断服务例程,将接收数据装入数据队列,同时Led3闪烁
*** 输入输出:
*** 创建日期:2007-5-7 2:19  by:CANopen
*** 修改日期:2007-5-7 2:19  by:
***************************************************************************************************
*/
__irq void CAN2_Rx_ISR(void)
{
 int32u *pAddr;
 if(CAN2RFS & 0x00000400) // 查询BP位,1标识该数据为BypassMode下接收
 {
  pAddr = (int32u *) &(gCAN_RxQ[1][gRxQ_In[1]]);
  *pAddr++ = CAN2RFS;   // Frame
  
  *pAddr++ = CAN2RID;  // ID
  
  *pAddr++ = CAN2RDA;  // Data A
  
  *pAddr++ = CAN2RDB;  // Data B
  
  gRxQ_In[1]++;    // 数据队列指针调整
  if (gRxQ_In[1] >= MAX_Q)
  {
   gRxQ_In[1] = 0;
   }
  }
 CAN2CMR = 0x04;    // 释放接收寄存器,同时RBS位清零
 VICVectAddr = 0x00U;   // acknowledge Interrupt
 LedFlash(Led3);
 }
 
5、CANGSR、CANSR寄存器截图:
<<-------CANGSR
 
<<---------CANSR(1)
<<--------CANSR(2)
 

发表评论:

    大名:
    密码: (游客无须输入密码)
    主页:
    标题:

时 间 记 忆
最 新 评 论

专 题 分 类
最 新 日 志
最 新 留 言
搜 索
用 户 登 录
友 情 连 接
博 客 信 息


Powered by Oblog.