打印
[DSP编程]

2812 ecan 有知道这么问题的答案吗,烦请解答一下

[复制链接]
1992|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
raoxianbin|  楼主 | 2013-12-15 13:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 raoxianbin 于 2013-12-15 14:34 编辑

https://bbs.21ic.com/icview-36610-1-1.html   



背景:在ti的测试例程中,采用查询方式发送消息,一次将所有的TRS位置1,采用中断方式接收发送的数据。(所有邮箱中断使能,中断等级0)。主函数中
   for(;;){
      ECannaRegs.CANTRS.all = 0x0000FFFF;  //0——15信箱全部发送
      while(ECanaRegs.CANTA.all != 0x0000FFFF);//等待所有消息发送完毕
      ECanaRegs.CANTA.all = 0x0000FFFF;//清发送响应位
    }
  中断程序中:
  interrupt void ECAN0INTA_ISR(void)  // eCAN-A
  {
      Uint16 j;
      for(j = 16; j < 32; j++){
        mailbox_read(j);
        mailbox_check(TestMbox1,TestMbox2,TestMbox3);
      }
      EINT;
   }
void mailbox_read(int16 MBXnbr)
{
   volatile struct MBOX *Mailbox;
   Mailbox = &ECanaMboxes.MBOX0 + MBXnbr;
   TestMbox1 = Mailbox->MDRL.all; // = 0x9555AAAn (n is the MBX number)
   TestMbox2 = Mailbox->MDRH.all; // = 0x89ABCDEF (a constant)
   TestMbox3 = Mailbox->MID.all;// = 0x9555AAAn (n is the MBX number)

}
我的疑问:手册上明确说明,一个接收邮箱接收到一条消息或者一个发送邮箱成功发送一条消息将产生一个中断,也就是说任何发送和接收完成都会产生一个中断。为便于分析,从第1个消息发送完成开始考虑:
  问题1:第1个消息发送完之后,将会产生一个中断,这时接收有可能还没完成,就不应该在中断程序里读接收邮箱的数据寄存器。更不要说一下子读16个接收邮箱的数据(后面的15个消息都还没开始发呢)。
  问题2:在此后的中断中,应该需要判断是发送中断还是接收中断。如果不判断,怎么样知道发生的是接收中断还是发送中断。
  很奇怪的是,这样的程序没有问题。在第一次发生中断后读出的16个数据全都正确!











对于这个问题,还有一个疑问






void InitECan(void)
{
struct ECAN_REGS ECanaShadow;
DINT;
EALLOW;//asm("  EALLOW");
GpioMuxRegs.GPFMUX.bit.CANTXA_GPIOF6 = 1;//选择相应的功能位
GpioMuxRegs.GPFMUX.bit.CANRXA_GPIOF7 = 1;
     ECanaShadow.CANTIOC.all = ECanaRegs.CANTIOC.all;
    ECanaShadow.CANTIOC.bit.TXFUNC = 1;//设置为can发送操作
    ECanaRegs.CANTIOC.all = ECanaShadow.CANTIOC.all;
    ECanaShadow.CANRIOC.all = ECanaRegs.CANRIOC.all;
    ECanaShadow.CANRIOC.bit.RXFUNC = 1;//接受操作
    ECanaRegs.CANRIOC.all = ECanaShadow.CANRIOC.all;

ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;//can主控寄存器
ECanaShadow.CANMC.bit.SCB = 1;              //=1,ECAN模式;=0正常模式
ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
/* Initialize all bits of 'Master Control Field' to zero */
    ECanaMboxes.MBOX0.MSGCTRL.all = 0x00000000;//对控制寄存器进行初始化
    ECanaMboxes.MBOX1.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX2.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX3.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX4.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX5.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX6.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX7.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX8.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX9.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX10.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX11.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX12.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX13.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX14.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX15.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX16.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX17.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX18.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX19.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX20.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX21.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX22.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX23.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX24.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX25.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX26.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX27.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX28.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX29.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX30.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX31.MSGCTRL.all = 0x00000000;
// TAn, RMPn, GIFn bits are all zero upon reset and are cleared again
// as a matter of precaution.
/* Clear all TAn bits ,发送响应寄存器,清除*/
ECanaRegs.CANTA.all = 0xFFFFFFFF;
/* Clear all RMPn bits,接收消息挂起寄存器 */
ECanaRegs.CANRMP.all = 0xFFFFFFFF;
/* Clear all interrupt flag bits,全局中断标志寄存器0,1 */
ECanaRegs.CANGIF0.all = 0xFFFFFFFF;//清除所有的中断标志位
ECanaRegs.CANGIF1.all = 0xFFFFFFFF;
/* Configure bit timing parameters,NMC=主控寄存器,CCR=改变配置请求 */
ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
ECanaShadow.CANMC.bit.CCR = 1 ;              // Set CCR = 1
    ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
    ECanaShadow.CANES.all = ECanaRegs.CANES.all;
// Wait until the CPU has been granted permission to change the configuration registers
    CAN_Loop_Num=0;
    do
    {
      ECanaShadow.CANES.all = ECanaRegs.CANES.all;
   CAN_Loop_Num++;
    }
    while((ECanaShadow.CANES.bit.CCE != 1 )&&(CAN_Loop_Num<20));    // 与CCR呼应,必须等CCE,Wait for CCE bit to be set..
    ECanaShadow.CANBTC.all = 0;      //位时序配置寄存器   赋初值
    ECanaShadow.CANBTC.bit.BRPREG = 39;    //0.25 Mbps @ 120 MHz SYSCLKOUT,通信波特率预设置  通信频率为0.25MHZ
    ECanaShadow.CANBTC.bit.TSEG2REG = 3;            //设置波特率,120MHz
    ECanaShadow.CANBTC.bit.TSEG1REG = 6;           //Baud rate=SYSCLKOUT/BRP*Bit_time
    ECanaShadow.CANBTC.bit.SAM = 1;     //Bit_time=(TSEG1reg+1)+(TSEG2reg+1)+1,SAM=1,CAN模块采样三次,BRP>4
    ECanaRegs.CANBTC.all = ECanaShadow.CANBTC.all;  //TSEG1(1~16)>=TSEG2;BRP=(BRPreg+1):1~256
    ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
ECanaShadow.CANMC.bit.CCR = 0 ;              // Set CCR = 0,配置波特率完成
    ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
    ECanaShadow.CANES.all = ECanaRegs.CANES.all;
// Wait until the CPU no longer has permission to change the configuration registers
    CAN_Loop_Num=0;
    do
    {
      ECanaShadow.CANES.all = ECanaRegs.CANES.all;
   CAN_Loop_Num++;
    }
    while((ECanaShadow.CANES.bit.CCE != 0 )&&(CAN_Loop_Num<20));   // Wait for CCE bit to be  cleared..
/* Disable all Mailboxes */
    // Since this write is to the entire register (instead of a bit
    // field) a shadow register is not required.
  ECanaRegs.CANME.all = 0;  // Required before writing the MSGIDs,相关邮箱被屏蔽
EDIS;
EINT;
}
// This function reads out the contents of the indicated
// by the Mailbox number (MBXnbr).
void mailbox_read(int16 MBXnbr)
{
   volatile struct MBOX *Mailbox;
   Mailbox = &ECanaMboxes.MBOX16 + MBXnbr;//也可以通过做逻辑或运算,实现加上相应的偏移地址
   TestMbox1 = Mailbox->MDL.all; // = 0x9555AAAn (n is the MBX number)
   TestMbox2 = Mailbox->MDH.all; // = 0x89ABCDEF (a constant)
   TestMbox3 = Mailbox->MSGID.all;// = 0x9555AAAn (n is the MBX number)
} // MSGID of a rcv MBX is transmitted as the MDL data.

void mailbox_check(int32 T1, int32 T2, int32 T3)
{
    if((T1 != T3) || ( T2 != 0x89ABCDEF))
    {
       ErrorCount++;
    }
}


   
   
interrupt void ECAN0_ISR(void) // eCAN-A
{
   
DINT;
PieCtrl.PIEACK.bit.ACK9 = 1;
for(Ecan_num=0; Ecan_num<16; Ecan_num++)         // Read & check 16 mailboxes
    {
          mailbox_read(Ecan_num);         // This func reads the indicated mailbox data
          RX_eCAN_buffer[Ecan_num]=TestMbox1;
    RX_eCAN_buffer[Ecan_num+1]=TestMbox2;
  
         mailbox_check(TestMbox1,TestMbox2,TestMbox3); // Checks the received data
    }
  
   
    ECanaRegs.CANRMP.bit.RMP16=1;//
EINT;
//发送
ECanaMboxes.MBOX15.MDL.all = TestMbox1;
    ECanaMboxes.MBOX15.MDH.all = TestMbox2;
ECanaRegs.CANTRS.all = 0x0000FFFF;  // Set TRS for all transmit mailboxes
CAN_Loop_Num=0;
    while((ECanaRegs.CANTA.all != 0x0000FFFF )&&(CAN_Loop_Num<20))
    {
     CAN_Loop_Num++;
    }  // Wait for all TAn bits to be set..
    ECanaRegs.CANTA.all = 0x0000FFFF;   // Clear all TAn
EINT;
   

}

对于这个中断中的数据读取,也即中断子函数中的mailbox_read()  不是说在读数据之前必须把标志位RMP进行复位吗,不复位能读取数据吗,麻烦各位解答一下。。

相关帖子

沙发
raoxianbin|  楼主 | 2013-12-15 20:05 | 只看该作者
求大神解答一下。。

使用特权

评论回复
板凳
zhangmangui| | 2013-12-17 09:33 | 只看该作者
DSP can有经验的进来帮忙解答一下

使用特权

评论回复
地板
kingzlt| | 2013-12-17 10:53 | 只看该作者
个人经验,仅供参考
CAN中断只需要使能接收中断即可,接收中断中,先读取中断RMP码,以判断中断邮箱,然后读取数据,最后清中断码

temp1 = ECanaRegs.CANRMP.all;
   
    if (temp1 & 0x80000000)   //邮箱31
    {
            CommRecBuf[0] = ECanaMboxes.MBOX31.MDL.all;  //0Byte~3Byte
            CommRecBuf[1] = ECanaMboxes.MBOX31.MDH.all;  //4Byte~7Byte
            Flag_CanRx = 1;
    }
/*   if (temp1 & 0x40000000)   //邮箱30
    {
            CommRecBuf[0] = ECanaMboxes.MBOX30.MDL.all;  //0Byte~3Byte
            CommRecBuf[1] = ECanaMboxes.MBOX30.MDH.all;  //4Byte~7Byte
            Flag_CanRx = 2;
    }*/
   
   
    ECanaRegs.CANTA.all    = 0xFFFFFFFF;         // Clear all TAn bits
    ECanaRegs.CANRMP.all   = 0xFFFFFFFF;         // Clear all RMPn bits
    ECanaRegs.CANGIF0.all  = 0xFFFFFFFF;         // Clear all interrupt flag bits
    ECanaRegs.CANGIF1.all  = 0xFFFFFFFF;


发送不需开中断,可随主程序进行

使用特权

评论回复
5
raoxianbin|  楼主 | 2013-12-17 21:43 | 只看该作者
本帖最后由 raoxianbin 于 2013-12-17 21:50 编辑
kingzlt 发表于 2013-12-17 10:53
个人经验,仅供参考
CAN中断只需要使能接收中断即可,接收中断中,先读取中断RMP码,以判断中断邮箱,然后 ...


你好,我看资料说读取数据之前不是要将RMP进行复位吗?   我现在发现一个问题


在中断中
运行了这个函数

void mailbox_read(int16 MBXnbr)
{
   volatile struct MBOX *Mailbox;
   Mailbox = &ECanaMboxes.MBOX16 + MBXnbr;//也可以通过做逻辑或运算,实现加上相应的偏移地址
   TestMbox1 = Mailbox->MDL.all; // = 0x9555AAAn (n is the MBX number)
   TestMbox2 = Mailbox->MDH.all; // = 0x89ABCDEF (a constant)
   TestMbox3 = Mailbox->MSGID.all;// = 0x9555AAAn (n is the MBX number)
} // MSGID of a rcv MBX is transmitted as the MDL data.

但是我用单步调试的时候发现, TestMbox1中的值在不清清除相应的标志位,它读取数值也是没用问题的,不知道这是什么原因

使用特权

评论回复
6
kingzlt| | 2013-12-18 09:06 | 只看该作者
raoxianbin 发表于 2013-12-17 21:43
你好,我看资料说读取数据之前不是要将RMP进行复位吗?   我现在发现一个问题

所谓的     
读取数据之前不是要将RMP进行复位吗?   我现在发现一个问题

我的理解应该是  先读取RMP中断码,判断好事哪个邮箱中断,然后读取邮箱接收内容,再复位RMP,以便下一次接收中断,楼主,你怎么看?

使用特权

评论回复
7
raoxianbin|  楼主 | 2013-12-18 09:13 | 只看该作者
kingzlt 发表于 2013-12-18 09:06
所谓的      
我的理解应该是  先读取RMP中断码,判断好事哪个邮箱中断,然后读取邮箱接收内容,再复位RM ...

我现在也不知道怎么判断,反正我之前还用过TI的测试程序,在不清除RMP标志位的情况下,确实不影响读取数据,但是我看一下资料说是 在读取数据之前要将相应的RMP标志进行复位,谢谢你的解答

使用特权

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

本版积分规则

36

主题

244

帖子

1

粉丝