AnsweredAssumed Answered

s12g128 MSCAN filter dose not work properly

Question asked by gao qiang on Feb 12, 2020
Latest reply on Feb 17, 2020 by gao qiang

Dear:

Thanks for your attention!

I have set s12g128 MSCAN in filter mode , there are two can id should be received,  id0 = 0x280, id1 = 0x1A0 ,

CAN filter configration as four 16bit mode , filter0 receive 0x280, filter1 receive 0x1A0.

During the test, it was found that only filter0 can receive normally, it could receive 0x280's message, but filter1 does not work. It can be determined that 0x1A0 information on the CAN bus is normaly.

the s12g128 MSCAN configration code as follows:

/* ---------------------------------------------------------------------- */

void mscan_init(uchar BRP_value)
{
    if (CANCTL0_INITRQ == 0// 查询是否进入初始化状态
        CANCTL0_INITRQ = 1;  // 进入初始化状态

    while (CANCTL1_INITAK == 0)
        ; // 等待初始化响应

    CANBTR0_SJW = 0;               // 同步跳跃脉宽设置 1Tq
    CANBTR0_BRP = (BRP_value - 1); // 预分频数设置为BRP_value
    CANBTR1_SAMP = 0;              // 采样数为1
    CANBTR1_TSEG_20 = 2;
    CANBTR1_TSEG_10 = 11// 相位缓冲段SEG1、SEG2长度设置 12,3个Tq
    CANIDAC = 0x10;       /* four 16-bit filters */
    //CANIDAC = 0x00;         /* two 32-bit filters */

    /* filters0 ID = 0x280 Standard Identifier */
    CANIDAR0 = 0x00 | (uint8_t)(0x280 >> 3); //bit 10 ~ bit3
    CANIDMR0 = 0x00;
    CANIDAR1 = 0x00 | (uint8_t)(0x280 << 5); //bit 2 ~ bit0
    CANIDMR1 = 0x07;

    /* filters1 ID = 0x1A0 Standard Identifier */
    CANIDAR2 = 0x00 | (uint8_t)(0x1A0 >> 3); //bit 10 ~ bit3
    CANIDMR2 = 0x00;
    CANIDAR3 = 0x00 | (uint8_t)(0x1A0 << 5); //bit 2 ~ bit0
    CANIDMR3 = 0x07;

    /* filters2 ID = 0x000 Standard Identifier */
    CANIDAR4 = 0x00;
    CANIDMR4 = 0x00;
    CANIDAR5 = 0x00;
    CANIDMR5 = 0x07;

    /* filters3 ID = 0x000 Standard Identifier */
    CANIDAR6 = 0x00;
    CANIDMR6 = 0x00;
    CANIDAR7 = 0x00;
    CANIDMR7 = 0x07;

    CANCTL1 = 0xC0//CAN工作模式的设置 选择24M总线时钟
    //CANCTL1 = 0x80;//使能MSCAN,选择外部晶振为MSCAN时钟源
    //配置工作模式
    CANCTL1_LISTEN = 0//侦听模式禁止
    //设置中断方式
    CANTIER = 0x00//禁止发送中断
    CANRIER = 0x00//禁止接收中断
    CANCTL0 = 0x00//返回一般模式运行

    while (CANCTL1_INITAK)
        ; //等待关闭初始化响应

    while (CANCTL0_SYNCH == 0)
        ; //等待CAN同步(连到总线时需要判断同步)

    CANTFLG_TXE = CANTFLG_TXE_MASK; //清空消息发送缓冲器
    CANRFLG_RXF = 1;                //清空消息接收缓冲器
    CANRIER_RXFIE = 1;              //使能接收消息中断
}
/* and the can receive interrupt code is follows: */
//CAN接收中断函数
interrupt void CAN_Rx_ISR(void)
{
    if (CANRFLG_RXF == 1)
    {
        mscan_receive(canRxMsg);
    }

    CANRFLG_RXF = 1;    /* Clear the interrupt flag */
}
/**CAN接收函数
 * error: return 1,2,3
 * success: return 0 */
static unsigned char mscan_receive(mscan_msg_t msg)
{
    unsigned char i = 0;
    unsigned char temp = 0;

    /*****************************************************************/
    /* Standard formate */
    if (0 == CANRXIDR1_IDE)
    {
        msg->id = ((unsigned int)CANRXIDR0 << 3| (CANRXIDR1 >> 5);
        msg->ide = 0;

        if (0 == CANRXIDR1_SRR) /* 判断是数据帧 or 远程帧 */
        {
            msg->rtr = 0;
        }
        else
        {
            msg->rtr = 1;
        }
    }
    /*****************************************************************/
    /* Extended formate */
    else
    {
        temp = CANRXIDR0;
        msg->id = (((unsigned long)temp) << 21& 0x1FE00000;
        temp = CANRXIDR1;
        (uchar) temp = (((temp & 0xE0>> 2+ (temp & 0x07));
        msg->id = msg->id + ((((unsigned long)temp) << 15& 0x1F8000);
        //temp = 0;
        temp = CANRXIDR2;
        msg->id = msg->id + ((((unsigned long)temp) << 7& 0x7F80);
        temp = CANRXIDR3;
        msg->id = msg->id + ((unsigned long)(temp >> 1& 0x7F);
        msg->ide = 1;

        if (0 == CANRXIDR3_RTR) /* 判断是数据帧 or 远程帧 */
        {
            msg->rtr = 0;
        }
        else
        {
            msg->rtr = 1;
        }
    }

    if (0 == msg->rtr/* 如果是数据帧,则接收数据 */
    {
        /* Receive Data and Datalength */
        msg->len = CANRXDLR;

        if (msg->len > 8)
        {
            msg->len = 8;
        }

        for (i = 0; i < msg->len; i++)
        {
            msg->data[i] = *(&(CANRXDSR0) + i);
        }
    }
    else
    {
        msg->len = 0;
    }

    msg->sta = 1;
}
Thank you for your answer!

Outcomes