牛卧堂MCU技术交流

标题: NUC970 CAN接收任意ID的数据 [打印本页]

作者: 匿名    时间: 2021-3-25 14:48
标题: NUC970 CAN接收任意ID的数据
1、NUC970 裸机程序2、怎样配置CAN的寄存器,使CAN通信能够接收任意ID的数据包。
谢谢!


作者: admin    时间: 2021-3-25 16:48
The Message Objects and Identifier Masks for acceptance filtering of received messaged in the Message RAM.

https://github.com/OpenNuvoton/NUC970_NonOS_BSP/tree/master/SampleCode/CAN

int32_t CAN_SetRxMsgObj(UINT32  uCAN, uint8_t u8MsgObj, uint8_t u8idType, uint32_t u32id, uint8_t u8singleOrFifoLast)
{
    UINT32 uOffset = uCAN * CAN_OFFSET;

    if((inpw(REG_CAN0_IF2_CREQ+uOffset) & CAN_IF_CREQ_BUSY_Msk) != 0)
    {
        return FALSE;
    }

    /* Command Setting */
    outpw((REG_CAN0_IF2_CMASK+uOffset), (CAN_IF_CMASK_WRRD_Msk | CAN_IF_CMASK_MASK_Msk | CAN_IF_CMASK_ARB_Msk |
                                         CAN_IF_CMASK_CONTROL_Msk | CAN_IF_CMASK_DATAA_Msk | CAN_IF_CMASK_DATAB_Msk));

    if (u8idType == CAN_STD_ID)   /* According STD/EXT ID format,Configure Mask and Arbitration register */
    {
        outpw((REG_CAN0_IF2_ARB1+uOffset), 0x0);
        outpw((REG_CAN0_IF2_ARB2+uOffset), (CAN_IF_ARB2_MSGVAL_Msk | (u32id & 0x7FF)<< 2)); /* Identifier Masks */       /*  参考 NUC970 Technical Reference Manual Page 824.  CAN_IFn_ARB2, Bit 15, 0 = The Message Object is ignored by the Message Handler
             当把第15位配置成0,将会忽略指定的消息对象,即所有的CAN消息对象将会被处理! */
    }
    else
    {
        outpw((REG_CAN0_IF2_ARB1+uOffset), (u32id & 0xFFFF));
        outpw((REG_CAN0_IF2_ARB2+uOffset), (CAN_IF_ARB2_MSGVAL_Msk | CAN_IF_ARB2_XTD_Msk | (u32id & 0x1FFF0000)>>16));
    }

    outpw((REG_CAN0_IF2_MCON+uOffset), (inpw(REG_CAN0_IF2_MCON+uOffset) | CAN_IF_MCON_UMASK_Msk | CAN_IF_MCON_RXIE_Msk));

    if(u8singleOrFifoLast)
    {
        outpw((REG_CAN0_IF2_MCON+uOffset), (inpw(REG_CAN0_IF2_MCON+uOffset) | CAN_IF_MCON_EOB_Msk));
    }
    else
    {
        outpw((REG_CAN0_IF2_MCON+uOffset), (inpw(REG_CAN0_IF2_MCON+uOffset) & ~CAN_IF_MCON_EOB_Msk));
    }

    outpw((REG_CAN0_IF2_DAT_A1+uOffset), 0x0);
    outpw((REG_CAN0_IF2_DAT_A2+uOffset), 0x0);
    outpw((REG_CAN0_IF2_DAT_B1+uOffset), 0x0);
    outpw((REG_CAN0_IF2_DAT_B2+uOffset), 0x0);

    outpw((REG_CAN0_IF2_CREQ+uOffset), (1 + u8MsgObj)); /* Message Object */

    return TRUE;
}
作者: 匿名    时间: 2021-3-26 13:58
首先,感谢“admin”给的解答。
我参照例程编写的程序能够接收固定的标识符数据包。我实测发现,将CAN_IFn_ARB2寄存器的Bit15设置成“0”
则接收不到数据包。
程序如下:
int32_t CAN_SetRxMsgObj(UINT32  uCAN, uint8_t u8MsgObj, uint8_t u8idType, uint32_t u32id, uint8_t u8singleOrFifoLast)
{
        UINT32 uOffset = uCAN * CAN_OFFSET;
    UINT32 reg;
       
        if((inpw(REG_CAN0_IF2_CREQ+uOffset) & CAN_IF_CREQ_BUSY_Msk) != 0)
        {
        return FALSE;
        }
       
    /* Command Setting */
        outpw((REG_CAN0_IF2_CMASK+uOffset), (CAN_IF_CMASK_WRRD_Msk | CAN_IF_CMASK_MASK_Msk | CAN_IF_CMASK_ARB_Msk |
                                         CAN_IF_CMASK_CONTROL_Msk | CAN_IF_CMASK_DATAA_Msk | CAN_IF_CMASK_DATAB_Msk));

    if (u8idType == CAN_STD_ID) { /* According STD/EXT ID format,Configure Mask and Arbitration register */
                outpw((REG_CAN0_IF2_ARB1+uOffset), 0x0);
                outpw((REG_CAN0_IF2_ARB2+uOffset), (CAN_IF_ARB2_MSGVAL_Msk | (u32id & 0x7FF)<< 2));
    } else {
                outpw((REG_CAN0_IF2_ARB1+uOffset), (u32id & 0xFFFF));
                outpw((REG_CAN0_IF2_ARB2+uOffset), (CAN_IF_ARB2_MSGVAL_Msk | CAN_IF_ARB2_XTD_Msk | (u32id & 0x1FFF0000)>>16));
    }
    /*********************添加 使Bit15 =0*************************/
    reg = inpw(REG_CAN0_IF2_ARB2+uOffset);
    reg = reg & (UINT32)(~(0x01<<15));
    outpw((REG_CAN0_IF2_ARB2+uOffset),reg);
    /************************************************/
        outpw((REG_CAN0_IF2_MCON+uOffset), (inpw(REG_CAN0_IF2_MCON+uOffset) | CAN_IF_MCON_UMASK_Msk | CAN_IF_MCON_RXIE_Msk));
       
    if(u8singleOrFifoLast)
        {
                outpw((REG_CAN0_IF2_MCON+uOffset), (inpw(REG_CAN0_IF2_MCON+uOffset) | CAN_IF_MCON_EOB_Msk));
        }
    else
        {
                outpw((REG_CAN0_IF2_MCON+uOffset), (inpw(REG_CAN0_IF2_MCON+uOffset) & ~CAN_IF_MCON_EOB_Msk));
        }
       
        outpw((REG_CAN0_IF2_DAT_A1+uOffset), 0x0);
        outpw((REG_CAN0_IF2_DAT_A2+uOffset), 0x0);
        outpw((REG_CAN0_IF2_DAT_B1+uOffset), 0x0);
        outpw((REG_CAN0_IF2_DAT_B2+uOffset), 0x0);
       
        outpw((REG_CAN0_IF2_CREQ+uOffset), (1 + u8MsgObj));
       
    return TRUE;
}

/****************************************************************
;函数名称: void InitControlCan0(void)
;函数功能:初始化CAN0
;输入参数:无
;返回参数:无
;版本:1.0
;编制日期:
;编写:
****************************************************************/
void InitControlCan0(void)
{
    outpw(REG_SYS_GPH_MFPL, (inpw(REG_SYS_GPH_MFPL) & 0xffff00ff) | 0xCC00 ); // GPH_2,GPH_3 // RX, TX
    outpw(REG_CLK_PCLKEN1, (inpw(REG_CLK_PCLKEN1) | (1 << 8) ));                 //开CAN0时钟
    CAN_Open(CAN0,  125000, CAN_NORMAL_MODE);
   
    CAN_SetRxMsg(CAN0, MSG(0),CAN_EXT_ID,(CAN_ID_RX_1));//0);//(unsigned int)(0x05<<26))
    //CAN_SetRxMsg(CAN0, MSG(1),CAN_EXT_ID,(unsigned int)((0x05<<26)|0x16));
    //CAN_SetRxMsg(CAN0, MSG(2),CAN_EXT_ID,(unsigned int)(0x05));
   
   
    CAN_EnableInt(CAN0, CAN_CON_IE_Msk);
    sysInstallISR((IRQ_LEVEL_6 | HIGH_LEVEL_SENSITIVE), CAN0_IRQn, (PVOID)CAN0_IRQHandler);
        sysSetLocalInterrupt(ENABLE_IRQ);                                                         /* enable CPSR I bit */
        sysEnableInterrupt(CAN0_IRQn);

    sysprintf("Wait Msg\n");
   
}


作者: 匿名    时间: 2021-3-26 14:05
我认为例程和底层的驱动均是基于标识符列表模式,没有屏蔽位模式。因英语水平所限,不知怎样设置成屏蔽位模式,请各位指教,谢谢!
作者: arthur    时间: 2021-3-26 17:22
Reference: NUC970 Technical Reference Manual Page 822,  (CAN_IFn_MASK2), Msk[28:16] = 0 即可。

以下表述有误:
/*  参考 NUC970 Technical Reference Manual Page 824.  CAN_IFn_ARB2, Bit 15, 0 = The Message Object is ignored by the Message Handler
             当把第15位配置成0,将会忽略指定的消息对象,即所有的CAN消息对象将会被处理! */
作者: 匿名    时间: 2021-3-27 15:46
我将底层的驱动做如下改动,想配置成屏蔽模式,但是依然接收不到数据,不知问题出在何处?
int32_t CAN_SetRxMsgObj(UINT32  uCAN, uint8_t u8MsgObj, uint8_t u8idType, uint32_t u32id, uint8_t u8singleOrFifoLast)
{
        UINT32 uOffset = uCAN * CAN_OFFSET;
    UINT32 reg;
       
        if((inpw(REG_CAN0_IF2_CREQ+uOffset) & CAN_IF_CREQ_BUSY_Msk) != 0)
        {
        return FALSE;
        }
          
//    /* Command Setting */
//        outpw((REG_CAN0_IF2_CMASK+uOffset), (CAN_IF_CMASK_WRRD_Msk | CAN_IF_CMASK_MASK_Msk | CAN_IF_CMASK_ARB_Msk |
//                                         CAN_IF_CMASK_CONTROL_Msk | CAN_IF_CMASK_DATAA_Msk | CAN_IF_CMASK_DATAB_Msk));

//    if (u8idType == CAN_STD_ID) { /* According STD/EXT ID format,Configure Mask and Arbitration register */
//                outpw((REG_CAN0_IF2_ARB1+uOffset), 0x0);
//                outpw((REG_CAN0_IF2_ARB2+uOffset), (CAN_IF_ARB2_MSGVAL_Msk | (u32id & 0x7FF)<< 2));
//    } else {
//                outpw((REG_CAN0_IF2_ARB1+uOffset), (u32id & 0xFFFF));
//                outpw((REG_CAN0_IF2_ARB2+uOffset), (CAN_IF_ARB2_MSGVAL_Msk | CAN_IF_ARB2_XTD_Msk | (u32id & 0x1FFF0000)>>16));
//    }
   
   
    /************************改写成掩码模式****************/
    outpw((REG_CAN0_IF2_CMASK+uOffset), (CAN_IF_CMASK_WRRD_Msk | CAN_IF_CMASK_MASK_Msk |CAN_IF_CMASK_TXRQSTNEWDAT_Msk|
                                         CAN_IF_CMASK_CONTROL_Msk | CAN_IF_CMASK_DATAA_Msk | CAN_IF_CMASK_DATAB_Msk));

        outpw((REG_CAN0_IF1_MASK1+uOffset),0);
    //outpw((REG_CAN0_IF1_MASK2+uOffset),0x03<<15);
    outpw((REG_CAN0_IF1_MASK2+uOffset),0);
   
        outpw((REG_CNA0_IF2_MASK1+uOffset),0);
    //outpw((REG_CAN0_IF2_MASK2+uOffset),0x03<<14);
    outpw((REG_CAN0_IF2_MASK2+uOffset),0);
   
    outpw((REG_CAN0_IF2_MCON+uOffset),  (CAN_IF_MCON_UMASK_Msk | CAN_IF_MCON_RXIE_Msk));
    //outpw((REG_CAN0_IF2_MCON+uOffset), (inpw(REG_CAN0_IF2_MCON+uOffset) | CAN_IF_MCON_UMASK_Msk | CAN_IF_MCON_RXIE_Msk));
    //outpw((REG_CAN0_IF2_MCON+uOffset), (inpw(REG_CAN0_IF2_MCON+uOffset) | CAN_IF_MCON_RXIE_Msk));
   /***************************结束******************************/
   
   
    if(u8singleOrFifoLast)
        {
                outpw((REG_CAN0_IF2_MCON+uOffset), (inpw(REG_CAN0_IF2_MCON+uOffset) | CAN_IF_MCON_EOB_Msk));
        }
    else
        {
                outpw((REG_CAN0_IF2_MCON+uOffset), (inpw(REG_CAN0_IF2_MCON+uOffset) & ~CAN_IF_MCON_EOB_Msk));
        }
       
        outpw((REG_CAN0_IF2_DAT_A1+uOffset), 0x0);
        outpw((REG_CAN0_IF2_DAT_A2+uOffset), 0x0);
        outpw((REG_CAN0_IF2_DAT_B1+uOffset), 0x0);
        outpw((REG_CAN0_IF2_DAT_B2+uOffset), 0x0);
       
        outpw((REG_CAN0_IF2_CREQ+uOffset), (1 + u8MsgObj));
       
    return TRUE;
}





欢迎光临 牛卧堂MCU技术交流 (http://nuvoton-mcu.com/) Powered by Discuz! X3.2