问答

汇集网友智慧,解决技术难题

21ic问答首页 - 有关HC32F460的CAN通讯问题

有关HC32F460的CAN通讯问题

Wtt小菜鸟2021-10-31
回答 +关注 24
11704人浏览 26人回答问题 分享 举报
26 个回答
  • wubangmi 发表于 2021-11-2 21:07
    CAN时钟只能来自外部高速晶振,不能用内部。
    我看你说用内部回环可以了,那把内部回环改成外部回环的就行 ...

    好的,麻烦您了,最终找到问题所在,其设置没有问题,只不过这款芯片的PB2引脚并无CAN功能的复用,所以将管脚改至PH2后可以正常跑了,十分感谢您的解答
  • Wtt小菜鸟 发表于 2021-11-2 19:59
    您好,我根据您给的建议进行了简单的尝试,但仍然无法实现CAN的外部回环通讯,不仅发送中断没有正常标志 ...

    CAN时钟只能来自外部高速晶振,不能用内部。
    我看你说用内部回环可以了,那把内部回环改成外部回环的就行了,其他的都不用改,我今天特意用例程跑了下,都是通的。
  • wubangmi 发表于 2021-11-2 11:18
    两种方式,按需采用其中的一种:
    1、在例程里屏蔽所有以下等待发送中断的代码
    //    // ...

    您好,我根据您给的建议进行了简单的尝试,但仍然无法实现CAN的外部回环通讯,不仅发送中断没有正常标志,接收中断标志位同样如此,因此怀疑数据根本没有发出去,所以猜想是否是时钟或者波特率设置出现了什么问题,想请教一下您,CAN总线的时钟源是来自外部高速振荡器,那么哪个函数可以具体表示CAN时钟源的选择呢,还有就是,如果我不使用Xtal,采用内部振荡器,那么CAN总线的时钟源又该怎么设置呢
  • Wtt小菜鸟 发表于 2021-11-2 09:53
    别沉呀,有没有哪位比较熟悉华大芯片的或者比较熟悉CAN通讯的大佬,麻烦告知一下小弟哪里出问题了 ...

    两种方式,按需采用其中的一种:
    1、在例程里屏蔽所有以下等待发送中断的代码
    //    //<< Wait transmitting done.
    //    while (false == CAN_Irq**Get(CanTxPrimaryIrq**));
    //    CAN_Irq**Clr(CanTxPrimaryIrq**);

    2、在CAN初始化后增加发送中断使能函数,其他代码不改动
    CAN_IrqCmd(CanTxPrimaryIrqEn, Enable);
  • 别沉呀,有没有哪位比较熟悉华大芯片的或者比较熟悉CAN通讯的大佬,麻烦告知一下小弟哪里出问题了
  • 有没有大哥可以告诉我可能是哪里有问题的呀,找了两天了还是不知道什么问题导致的,自闭了
  • wubangmi 发表于 2021-11-1 16:32
    你是不是搞错了例程啊,用内部回环模式,我没看到下面这个函数啊
    //

    您好,我现在尝试使用内部回环模式的时候,发现可以正常通讯,但是外部回环模式仍然卡在之前那个while循环当中,您知道这可能与什么设置有关系吗。
  • wubangmi 发表于 2021-11-1 16:32
    你是不是搞错了例程啊,用内部回环模式,我没看到下面这个函数啊
    //

    您好,有这个函数,我忘记放上来了,给您看一下完整的有关CAN设置的函数内容:
    static void CanInitConfig(void)
    {
        stc_can_init_config_t stcCanInitCfg;
        stc_can_filter_t astcFilters[CAN_FILTERS_COUNT] = \
        {
            {0x00000000ul, 0x1FFFFFFFul, CanFilterSel1, CanAllFrames}
        };

        //<< Enable can peripheral clock and buffer(ram)
        PWC_RamOpMdConfig(HighSpeedMd);
        PWC_RamPwrdownCmd(PWC_RAMPWRDOWN_CAN, Enable);
        PWC_Fcg1PeriphClockCmd(PWC_FCG1_PERIPH_CAN, Enable);

        //<< CAN GPIO config
        PORT_SetFunc(PortB, Pin02, Func_Can1_Rx, Disable);
        PORT_SetFunc(PortB, Pin10, Func_Can1_Tx, Disable);
        //PORT_ResetBits(PortD, Pin15);
        //PORT_OE(PortD, Pin15, Enable);

        MEM_ZERO_STRUCT(stcCanInitCfg);
        //<< Can bit time config
        stcCanInitCfg.stcCanBt.PRESC = 1u-1u;
        stcCanInitCfg.stcCanBt.SEG_1 = 13u-2u;
        stcCanInitCfg.stcCanBt.SEG_2 = 7u-1u;
        stcCanInitCfg.stcCanBt.SJW   = 3u-1u;

        stcCanInitCfg.stcWarningLimit.CanErrorWarningLimitVal = 10u;
        stcCanInitCfg.stcWarningLimit.CanWarningLimitVal = 16u-1u;

        stcCanInitCfg.enCanRxBufAll  = CanRxAll;
        stcCanInitCfg.enCanRxBufMode = CanRxBufNotStored;
        stcCanInitCfg.enCanSAck      = CanSelfAckEnable;
        stcCanInitCfg.enCanSTBMode   = CanSTBFifoMode;

        stcCanInitCfg.pstcFilter     = astcFilters;
        stcCanInitCfg.u8FilterCount  = CAN_FILTERS_COUNT;

        CAN_Init(&stcCanInitCfg);

        //<< Loop back internal
        CAN_ModeConfig(CanExternalLoopBackMode, Enable);
    }
  • Wtt小菜鸟 发表于 2021-11-1 15:45
    您好,是这样的,因为通讯不成功,所以我现在使用的是有关CAN内部回环通讯的例程来进行内部的通讯尝试。 ...

    你是不是搞错了例程啊,用内部回环模式,我没看到下面这个函数啊
    //<< Loop back internal
        CAN_ModeConfig(CanExternalLoopBackMode, Enable);
  • wubangmi 发表于 2021-11-1 15:14
    从代码里看你XTAL已经使能了,主频倍频也没错,那么CAN的时钟也就已经开了。
    但是CAN还有一个采样点问题, ...

    您好,是这样的,因为通讯不成功,所以我现在使用的是有关CAN内部回环通讯的例程来进行内部的通讯尝试。也就是说我没有接外部设备,然后程序是一直卡在确认发送标志位这一个循环里,也就是while (false == CAN_Irq**Get(CanTxPrimaryIrq**))这一串代码,我点进去之后发现是判断其RTIF寄存器TPIF位的内容,其比较方式如下:
    bool CAN_Irq**Get(en_can_irq_flag_type_t enCanIrq**Type)
    {
        volatile uint32_t *u32pIE = NULL;
        bool bRet = false;
        DDL_ASSERT(IS_CAN_IRQ_FLAG_VALID(enCanIrq**Type));
        u32pIE = (volatile uint32_t*)(&M4_CAN->RTIE);//这里例程是取值RTIE后共32位的值。
        //这里enCanIrq**Type=0x00000800,比较的是RTIF的TPIF位,用于判断是否发送成功。
        if( *u32pIE & enCanIrq**Type)
        {
            bRet = true;
        }
        return bRet;
    }
    这一步始终是return false,就是说我始终没有发送成功。想请问一下这也跟采样点是相关联的是吗,如果采样点不对的话是否也会导致发送未完成呢。

您需要登录后才可以回复 登录 | 注册