问答

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

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

有关HC32F460的CAN通讯问题

Wtt小菜鸟2021-10-31
回答 +关注 24
11707人浏览 26人回答问题 分享 举报
26 个回答
  • 本帖最后由 wubangmi 于 2021-11-1 15:16 编辑
    Wtt小菜鸟 发表于 2021-11-1 14:37
    您好,我根据您的建议对CAN时钟的进行重新的分配,其配置如下:
    stcCanInitCfg.stcCanBt.PRESC = 1u-1u;
    ...

    从代码里看你XTAL已经使能了,主频倍频也没错,那么CAN的时钟也就已经开了。
    但是CAN还有一个采样点问题,就是SEG_1和SEG_2,你时钟对了,但是采样点不对,你还是通信不成功
    你现在的采样点是(1+16)/(1+16+4)=80.95%,例程里的采样点是(1+5)/(1+5+3)=66.67%。你可能需要匹配采样点的问题跟你的那个通信设备



  • Wtt小菜鸟 发表于 2021-11-1 14:00
    哦哦,就是说实际上CAN的时钟采用的也就是我的外部20MHz的晶振是吗,好的谢谢大佬,十分感谢解惑,我再去 ...

    您好,我根据您的建议对CAN时钟的进行重新的分配,其配置如下:
    stcCanInitCfg.stcCanBt.PRESC = 1u-1u;
    stcCanInitCfg.stcCanBt.SEG_1 = 16u-2u;
    stcCanInitCfg.stcCanBt.SEG_2 = 4u-1u;
    stcCanInitCfg.stcCanBt.SJW   = 3u-1u;
    将其配置成了1MHz的波特率进行传输,但仍然卡在while (false == CAN_Irq**Get(CanTxPrimaryIrq**));这条语句,想知道是这样配置会有什么其他问题吗,还是说有其他地方也配置错误的,为了便于查找,我把我的系统时钟初始化配置放置如下:
    void BSP_CLK_Init(void)
    {
        stc_clk_sysclk_cfg_t    stcSysClkCfg;
        stc_clk_xtal_cfg_t      stcXtalCfg;
        stc_clk_mpll_cfg_t      stcMpllCfg;
        stc_sram_config_t       stcSramConfig;

        MEM_ZERO_STRUCT(stcSysClkCfg);
        MEM_ZERO_STRUCT(stcXtalCfg);
        MEM_ZERO_STRUCT(stcMpllCfg);
        MEM_ZERO_STRUCT(stcSramConfig);

        /* Set bus clk div. */
        stcSysClkCfg.enHclkDiv  = ClkSysclkDiv1;
        stcSysClkCfg.enExclkDiv = ClkSysclkDiv2;
        stcSysClkCfg.enPclk0Div = ClkSysclkDiv1;
        stcSysClkCfg.enPclk1Div = ClkSysclkDiv2;
        stcSysClkCfg.enPclk2Div = ClkSysclkDiv4;
        stcSysClkCfg.enPclk3Div = ClkSysclkDiv4;
        stcSysClkCfg.enPclk4Div = ClkSysclkDiv2;
        CLK_SysClkConfig(&stcSysClkCfg);

        /* Config Xtal and Enable Xtal */
        stcXtalCfg.enMode = ClkXtalModeOsc;
        stcXtalCfg.enDrv = ClkXtalLowDrv;
        stcXtalCfg.enFastStartup = Enable;
        CLK_XtalConfig(&stcXtalCfg);
        CLK_XtalCmd(Enable);

        /* sram init include read/write wait cycle setting */
        stcSramConfig.u8SramIdx = Sram12Idx | Sram3Idx | SramHsIdx | SramRetIdx;
        stcSramConfig.enSramRC = SramCycle2;
        stcSramConfig.enSramWC = SramCycle2;
        SRAM_Init(&stcSramConfig);

        /* flash read wait cycle setting */
        EFM_Unlock();
        EFM_SetLatency(EFM_LATENCY_5);
        EFM_Lock();

        /* MPLL config (XTAL / pllmDiv * plln / PllpDiv = 200M). */
        stcMpllCfg.pllmDiv = 5ul;
        stcMpllCfg.plln    = 100ul;
        stcMpllCfg.PllpDiv = 2ul;
        stcMpllCfg.PllqDiv = 2ul;
        stcMpllCfg.PllrDiv = 2ul;
        CLK_SetPllSource(ClkPllSrcXTAL);
        CLK_MpllConfig(&stcMpllCfg);

        /* Enable MPLL. */
        CLK_MpllCmd(Enable);
        /* Wait MPLL ready. */
        while(Set != CLK_GetFlagStatus(ClkFlagMPLLRdy))
        {
            ;
        }
        /* Switch driver ability */
        PWC_HS2HP();
        /* Switch system clock source to MPLL. */
        CLK_SetSysClkSource(CLKSysSrcMPLL);
    }

    请问一下可能是哪里出了什么问题吗
  • wubangmi 发表于 2021-11-1 13:38
    F460的CAN时钟来自外部高频晶振,CAN的最大波特率只支持1MHZ,你外部晶振用的是20MHZ,代码里CAN的时钟分频 ...

    还有个问题想请教一下您,这个F460的CAN时钟配置具体是在哪的呢,还是说PWC_Fcg1PeriphClockCmd(PWC_FCG1_PERIPH_CAN, Enable)这条语句开启外围时钟就表示使用了外部的来自Xtal(我之前配的就是Xtal时钟)的时钟源是吗。
  • wubangmi 发表于 2021-11-1 13:38
    F460的CAN时钟来自外部高频晶振,CAN的最大波特率只支持1MHZ,你外部晶振用的是20MHZ,代码里CAN的时钟分频 ...

    哦哦,就是说实际上CAN的时钟采用的也就是我的外部20MHz的晶振是吗,好的谢谢大佬,十分感谢解惑,我再去尝试一下
  • F460的CAN时钟来自外部高频晶振,CAN的最大波特率只支持1MHZ,你外部晶振用的是20MHZ,代码里CAN的时钟分频是1,所以在时钟源这部分你搞错了。
  • 有没有大佬可以告知一下,可能是哪些地方没有配置正确呢
  • 下面是有关通讯部分的函数,主要就是卡在while (false == CAN_Irq**Get(CanTxPrimaryIrq**));这一句,好像无法发送出去
    static void CanTxRx(void)
    {
        stc_can_txframe_t stcTxFrame;
        stc_can_rxframe_t stcRxFrame;
        uint8_t u8Idx = 0u;

        MEM_ZERO_STRUCT(stcTxFrame);
        MEM_ZERO_STRUCT(stcRxFrame);

        //<<Can Tx 1st
        stcTxFrame.StdID = 0x123ul;
        for(u8Idx = 0u; u8Idx < 0x08u; u8Idx++)
        {
            stcTxFrame.Data[u8Idx] = u8Idx;
        }

        stcTxFrame.Control_f.DLC = 0x08ul;
        stcTxFrame.Control_f.IDE = 0x00ul;
        CAN_SetFrame(&stcTxFrame);
        CAN_TransmitCmd(CanPTBTxCmd);
        //<< Wait transmitting done.
        while (false == CAN_Irq**Get(CanTxPrimaryIrq**));
        CAN_Irq**Clr(CanTxPrimaryIrq**);

        while(1)
        {
            if(true == CAN_Irq**Get(CanRxIrq**))
            {
                CAN_Irq**Clr(CanRxIrq**);
                //<< Rx
                CAN_Receive(&stcRxFrame);
                //<< Tx
                CAN_SetFrame(&stcTxFrame);
                CAN_TransmitCmd(CanPTBTxCmd);
                //<< Wait transmitting done.
                while (false == CAN_Irq**Get(CanTxPrimaryIrq**));
                CAN_Irq**Clr(CanTxPrimaryIrq**);
            }
        }
    }
123

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