TCAN4550-Q1: SPI通信正常,CAN发送数据失败

Part Number: TCAN4550-Q1
Other Parts Discussed in Thread: TCAN4550

我已经调通了SPI通信,可以读到期间ID和寄存器。但是当我发送CAN数据时,发送失败。Error Counter Register (address = h1040)的值为0x000100D8,Protocol Status Register (address = h1044)的值为0x0000076D,即Protocol Status Register的LEC[2:0]值为0x101,我不知道为什么会这样。请帮助我解决CAN发送问题,谢谢。

软件:将sllc469b的demo移植到了stm32f407,mcan初始化即CAN发送部分如下

/*
* Configure the TCAN4550
*/
void TCAN4550_CAN_Init(void)
{
// TCAN4x5x_Device_ClearSPIERR(); // Clear any SPI ERR flags that might be set as a result of our pin mux changing during MCU startup
Tcan_Ir_Err_Clear = 1;
TCAN4550_Interrupt_Clear();

/* Step one attempt to clear all interrupts */
TCAN4x5x_Device_Interrupt_Enable dev_ie = {0}; // Initialize to 0 to all bits are set to 0.
TCAN4x5x_Device_ConfigureInterruptEnable(&dev_ie);

if (dev_ir.PWRON) // If the Power On interrupt flag is set
TCAN4x5x_Device_ClearInterrupts(&dev_ir); // Clear it because if it's not cleared within ~4 minutes, it goes to sleep

/* Configure the CAN bus speeds */
TCAN4x5x_MCAN_Nominal_Timing_Simple TCANNomTiming = {0}; // 1Mbps arbitration with a 40 MHz crystal ((40E6 / 1) / (32 + 8) = 1E6)
TCANNomTiming.NominalBitRatePrescaler = 4;
TCANNomTiming.NominalTqBeforeSamplePoint = 8;

TCAN4x5x_MCAN_Data_Timing_Simple TCANDataTiming = {0}; // 5 Mbps CAN FD with a 40 MHz crystal (40E6 / (6 + 2) = 5E6)
TCANDataTiming.DataBitRatePrescaler = 1;
TCANDataTiming.DataTqBeforeSamplePoint = 6;
TCANDataTiming.DataTqAfterSamplePoint = 2;

/* Configure the MCAN core settings */
TCAN4x5x_MCAN_CCCR_Config cccrConfig = {0}; // Remember to initialize to 0, or you'll get random garbage!
cccrConfig.FDOE = 1; // CAN FD mode enable
cccrConfig.BRSE = 1; // CAN

/* Configure the default CAN packet filtering settings */
TCAN4x5x_MCAN_Global_Filter_Configuration gfc = {0};
gfc.RRFE = 1; // Reject remote frames (TCAN4x5x doesn't support this)
gfc.RRFS = 1; // Reject remote frames (TCAN4x5x doesn't support this)
gfc.ANFE = TCAN4x5x_GFC_REJECT; 

TCAN4x5x_MRAM_Config MRAMConfiguration = {0};
MRAMConfiguration.SIDNumElements = 2;
MRAMConfiguration.XIDNumElements = 1;
MRAMConfiguration.Rx0NumElements = 4;
MRAMConfiguration.Rx0ElementSize = MRAM_64_Byte_Data;
MRAMConfiguration.Rx1NumElements = 2;
MRAMConfiguration.Rx1ElementSize = MRAM_64_Byte_Data;
MRAMConfiguration.RxBufNumElements = 0;
MRAMConfiguration.RxBufElementSize = MRAM_64_Byte_Data;
MRAMConfiguration.TxEventFIFONumElements = 0;
MRAMConfiguration.TxBufferNumElements = 2;
MRAMConfiguration.TxBufferElementSize = MRAM_64_Byte_Data;

Tcan4550_Var.Protect = TCAN4x5x_MCAN_EnableProtectedRegisters();
TCAN4550_Power_Control_Reg_Status = AHB_READ_32(REG_MCAN_CCCR);

TCAN4x5x_MCAN_ConfigureCCCRRegister(&cccrConfig);
TCAN4x5x_MCAN_ConfigureGlobalFilter(&gfc);
TCAN4x5x_MCAN_ConfigureNominalTiming_Simple(&TCANNomTiming);
TCAN4x5x_MCAN_ConfigureDataTiming_Simple(&TCANDataTiming);
TCAN4x5x_MRAM_Clear();
TCAN4x5x_MRAM_Configure(&MRAMConfiguration);
TTCAN4x5x_MCAN_DisableProtectedRegisters();

TCAN4x5x_MCAN_Interrupt_Enable mcan_ie = {0};
mcan_ie.RF0NE = 1;
mcan_ie.RF1NE = 1;

TCAN4x5x_MCAN_ConfigureInterruptEnable(&mcan_ie);

TCAN4x5x_MCAN_SID_Filter SID_ID0 = {0};
SID_ID0.SFT = TCAN4x5x_SID_SFT_CLASSIC;
SID_ID0.SFEC = TCAN4x5x_SID_SFEC_PRIORITYSTORERX0;
SID_ID0.SFID1 = 0x1;
SID_ID0.SFID2 = 0x7FF;
TCAN4x5x_MCAN_WriteSIDFilter(0, &SID_ID0);

TCAN4x5x_MCAN_SID_Filter SID_ID1 = {0};
SID_ID1.SFT = TCAN4x5x_SID_SFT_CLASSIC;
SID_ID1.SFEC = TCAN4x5x_SID_SFEC_PRIORITYSTORERX0;
SID_ID1.SFID1 = 0x7FF;
SID_ID1.SFID2 = 0x7FF;
TCAN4x5x_MCAN_WriteSIDFilter(1, &SID_ID1);

TCAN4x5x_MCAN_XID_Filter XID_ID = {0};
XID_ID.EFT = TCAN4x5x_XID_EFT_CLASSIC;
XID_ID.EFEC = TCAN4x5x_XID_EFEC_PRIORITYSTORERX1;
XID_ID.EFID1 = 0x8080;
XID_ID.EFID2 = 0x1FFFFFFF;
TCAN4x5x_MCAN_WriteXIDFilter(0, &XID_ID);

TCAN4x5x_DEV_CONFIG devConfig = {0};
devConfig.SWE_DIS = 1;
devConfig.DEVICE_RESET = 0;
devConfig.WD_EN = 0;
devConfig.nWKRQ_CONFIG = 0;
devConfig.INH_DIS = 1;
devConfig.GPIO1_GPO_CONFIG = TCAN4x5x_DEV_CONFIG_GPO1_MCAN_INT1;
devConfig.FAIL_SAFE_EN = 0;
devConfig.GPIO1_CONFIG = TCAN4x5x_DEV_CONFIG_GPIO1_CONFIG_GPO;
devConfig.WD_ACTION = TCAN4x5x_DEV_CONFIG_WDT_ACTION_nINT;
devConfig.WD_BIT_RESET = 0;
devConfig.nWKRQ_VOLTAGE = 0;

devConfig.GPO2_CONFIG = TCAN4x5x_DEV_CONFIG_GPO2_MCAN_INT0;
devConfig.CLK_REF = 1;
devConfig.WAKE_CONFIG = TCAN4x5x_DEV_CONFIG_WAKE_BOTH_EDGES;
TCAN4x5x_Device_Configure(&devConfig);

TCAN4x5x_Device_SetMode(TCAN4x5x_DEVICE_MODE_NORMAL);

TCAN4x5x_MCAN_ClearInterruptsAll();

}

void TCAN4550_Communication_Test(void)
{
if(TCAN_Send)
{
/* Define the CAN message we want to send*/
TCAN4x5x_MCAN_TX_Header header = {0};
uint8_t data[4] = {0x55, 0x66, 0x77, 0x88};
header.DLC = MCAN_DLC_8B;
header.ID = 0x144;
header.FDF = 0;
header.BRS = 1;
header.EFC = 0;
header.MM = 0;
header.RTR = 0;
header.XTD = 0;
header.ESI = 0;
TCAN4x5x_MCAN_WriteTXBuffer(0, &header, data);
TCAN4x5x_MCAN_TransmitBufferContents(0);
TCAN_Send = 0;
}
}

硬件部分:OSC1的时钟源为定时器PWM波

  • 您好,

    已经收到了您的案例,调查需要些时间,感谢您的耐心等待。

  • 好的,谢谢,麻烦尽量快一点

  • 您好

    Error Counter Register (address = h1040)的值为0x000100D8,Protocol Status Register (address = h1044)的值为0x0000076D,即Protocol Status Register的LEC[2:0]值为0x101,我不知道为什么会这样。请帮助我解决CAN发送问题,谢谢。

    5–Bit0Error:在消息(或确认位、活动错误标志或过载标志)传输期间、器件想要发送一个显性电平(数据或标识符位逻辑值‘0')、但监测到的总线值为隐性。 在 Bus_Off 恢复期间、每次监测到11个隐性位序列时都会设置此状态。 这使得 CPU 能够监测 Bus_Off 恢复序列的进程(表明总线并未卡在显性状态或持续受到干扰)。 0x5的 LEC 错误是位0错误、这意味着它检测到隐性总线电平、而不是显性总线电平。 造成该问题的可能原因包括信号路径中接线、收发器或其他器件的物理故障、从而防止出现显性值、例如 CANH 和 CANL 之间短路。 采样点不正确或不同 CAN 节点之间不同位时序配置的时序问题可能会导致错误地对位进行采样。 此外、采样点本身可能在位周期内不处于良好位置、并且太接近位周期的开始或结束。 总线上不正确的终端或信号反射可能会导致振铃、并且这些位可能在采样点处不稳定。

    硬件部分:OSC1的时钟源为定时器PWM波

    CAN_CLKIN的时钟频率和电压电平是多少?

    检查您的设置是否存在物理问题,验证总线上所有CAN节点的位定时是否具有完全相同的设置和采样点,并使用示波器检查总线是否存在噪声和信号完整性差的问题。

  • CAN_CLKIN的时钟为定时器输出的PWM1波,时钟频率为40MHZ,占空比50%

  • 好的,我们在查查硬件,谢谢

  • 您好

    好吧,这并没有真正回答我的问题,所以我会详细说明。

    对于电压水平,当VIO=3.3V时,CAN_CLKIN必须满足VIL/VIH要求。

    VIH>2.805V

    电压小于0.99V

    请确保连接到OSC1引脚的正确单端时钟信号满足VIH和VIL电平。

    频率还必须满足CAN ISO 11898-1标准中定义的振荡器容差要求,该标准基于其比特定时配置和数据速率。

    我不知道PWM计数器的精度有多高,也不知道总线上其他CAN节点的时钟源是什么,但如果不满足时钟频率容差,那么CAN通信错误中可能会出现错误,因为所有节点的时钟频率在频率上不够接近,无法相互正确同步并在不引起错误的情况下对比特进行采样。

  • 总线节点只有TCAN4550和CANFD分析仪,时钟频率:仲裁段1MHz,采样率80%,数据段5MHz,采样率75%;VIH电压为3.3V,VIL为0V;PWM频率为40MHz。

  • 您好

    If you have a Bit 0 Error, then you either have signal integrity issues, or some form of clock or timing related error.

    I tried to verify your timing parameters were 1M and 5M and I noticed your missing a line of code that assigns the number of time quanta (tq) after the sample point.  So you need to verify your timing settings are complete and correct with the same number of tq are allocated before and after the sample point for both the nominal and data bit rates for both the TCAN4550 and CANFD analyzer tool you are using.

    As reference, the default code has an additional line that appears to have been deleted.

  • Hi, Daniel

    I compared it and found that the demo did not remove any of the key lines of code. Perhaps I accidentally deleted the comments when I asked the question before.I'll resend my configuration again.

    ------------------------------------------------------

    void TCAN4550_CAN_Init(void)
    {

    Tcan_Ir_Err_Clear = 1;
    TCAN4550_Interrupt_Clear();

    /* Step one attempt to clear all interrupts */
    TCAN4x5x_Device_Interrupt_Enable dev_ie = {0};
    TCAN4x5x_Device_ConfigureInterruptEnable(&dev_ie);

    TCAN4x5x_Device_Interrupts dev_ir = {0};
    TCAN4x5x_Device_ReadInterrupts(&dev_ir);

    if (dev_ir.PWRON)
    TCAN4x5x_Device_ClearInterrupts(&dev_ir);

    /* Configure the CAN bus speeds */
    TCAN4x5x_MCAN_Nominal_Timing_Simple TCANNomTiming = {0};
    TCANNomTiming.NominalBitRatePrescaler = 4;
    TCANNomTiming.NominalTqBeforeSamplePoint = 8;
    TCANNomTiming.NominalTqAfterSamplePoint = 2;

    TCAN4x5x_MCAN_Data_Timing_Simple TCANDataTiming = {0};
    TCANDataTiming.DataBitRatePrescaler = 1;
    TCANDataTiming.DataTqBeforeSamplePoint = 6;
    TCANDataTiming.DataTqAfterSamplePoint = 2;

    /* Configure the MCAN core settings */
    TCAN4x5x_MCAN_CCCR_Config cccrConfig = {0};
    cccrConfig.FDOE = 1;
    cccrConfig.BRSE = 1;
    cccrConfig.DAR = 1;

    /* Configure the default CAN packet filtering settings */
    TCAN4x5x_MCAN_Global_Filter_Configuration gfc = {0};
    gfc.RRFE = 1;
    gfc.RRFS = 1;
    gfc.ANFE = TCAN4x5x_GFC_REJECT;
    gfc.ANFS = TCAN4x5x_GFC_REJECT;

    TCAN4x5x_MRAM_Config MRAMConfiguration = {0};
    MRAMConfiguration.SIDNumElements = 2;
    MRAMConfiguration.XIDNumElements = 1;
    MRAMConfiguration.Rx0NumElements = 4;
    MRAMConfiguration.Rx0ElementSize = MRAM_64_Byte_Data;
    MRAMConfiguration.Rx1NumElements = 2;
    MRAMConfiguration.Rx1ElementSize = MRAM_64_Byte_Data;
    MRAMConfiguration.RxBufNumElements = 0;
    MRAMConfiguration.RxBufElementSize = MRAM_64_Byte_Data;
    MRAMConfiguration.TxEventFIFONumElements = 0;
    MRAMConfiguration.TxBufferNumElements = 2;
    MRAMConfiguration.TxBufferElementSize = MRAM_64_Byte_Data;

    Tcan4550_Var.Protect = TCAN4x5x_MCAN_EnableProtectedRegisters();
    TCAN4550_Power_Control_Reg_Status = AHB_READ_32(REG_MCAN_CCCR);

    TCAN4x5x_MCAN_EnableProtectedRegisters();
    TCAN4x5x_MCAN_ConfigureCCCRRegister(&cccrConfig);
    TCAN4x5x_MCAN_ConfigureGlobalFilter(&gfc);
    TCAN4x5x_MCAN_ConfigureNominalTiming_Simple(&TCANNomTiming);
    TCAN4x5x_MCAN_ConfigureDataTiming_Simple(&TCANDataTiming);
    TCAN4x5x_MRAM_Clear();
    TCAN4x5x_MRAM_Configure(&MRAMConfiguration);
    TCAN4x5x_MCAN_DisableProtectedRegisters();

    /* Set the interrupts we want to enable for MCAN */
    TCAN4x5x_MCAN_Interrupt_Enable mcan_ie = {0};
    mcan_ie.RF0NE = 1;
    mcan_ie.RF1NE = 1;

    TCAN4x5x_MCAN_ConfigureInterruptEnable(&mcan_ie);

    /* Setup filters, this filter will mark any message with ID 0x055 as a priority message */
    TCAN4x5x_MCAN_SID_Filter SID_ID0 = {0};
    SID_ID0.SFT = TCAN4x5x_SID_SFT_CLASSIC;
    SID_ID0.SFEC = TCAN4x5x_SID_SFEC_PRIORITYSTORERX0;
    SID_ID0.SFID1 = 0x1;
    SID_ID0.SFID2 = 0x7FF;
    TCAN4x5x_MCAN_WriteSIDFilter(0, &SID_ID0);

    /* Setup filters, this filter will mark any message with ID 0x7FF as a priority message wyw */
    TCAN4x5x_MCAN_SID_Filter SID_ID1 = {0};
    SID_ID1.SFT = TCAN4x5x_SID_SFT_CLASSIC;
    SID_ID1.SFEC = TCAN4x5x_SID_SFEC_PRIORITYSTORERX0;
    SID_ID1.SFID1 = 0x7FF;
    SID_ID1.SFID2 = 0x7FF;
    TCAN4x5x_MCAN_WriteSIDFilter(1, &SID_ID1);

    /* Store ID 0x8080 as a priority message */
    TCAN4x5x_MCAN_XID_Filter XID_ID = {0};
    XID_ID.EFT = TCAN4x5x_XID_EFT_CLASSIC;
    XID_ID.EFEC = TCAN4x5x_XID_EFEC_PRIORITYSTORERX1;
    XID_ID.EFID1 = 0x8080;
    XID_ID.EFID2 = 0x1FFFFFFF;
    TCAN4x5x_MCAN_WriteXIDFilter(0, &XID_ID);

    /* Configure the TCAN4550 Non-CAN-related functions */
    TCAN4x5x_DEV_CONFIG devConfig = {0};
    devConfig.SWE_DIS = 1;
    devConfig.DEVICE_RESET = 0;
    devConfig.WD_EN = 0;
    devConfig.nWKRQ_CONFIG = 0;
    devConfig.INH_DIS = 1;
    devConfig.GPIO1_GPO_CONFIG = TCAN4x5x_DEV_CONFIG_GPO1_MCAN_INT1;
    devConfig.FAIL_SAFE_EN = 0;
    devConfig.GPIO1_CONFIG = TCAN4x5x_DEV_CONFIG_GPIO1_CONFIG_GPO;
    devConfig.WD_ACTION = TCAN4x5x_DEV_CONFIG_WDT_ACTION_nINT;
    devConfig.WD_BIT_RESET = 0;
    devConfig.nWKRQ_VOLTAGE = 0;
    devConfig.GPO2_CONFIG = TCAN4x5x_DEV_CONFIG_GPO2_MCAN_INT0;
    devConfig.CLK_REF = 1;
    devConfig.WAKE_CONFIG = TCAN4x5x_DEV_CONFIG_WAKE_BOTH_EDGES;
    TCAN4550_Mode_Pin_Cfg0x0800 = AHB_READ_32(REG_DEV_MODES_AND_PINS);
    TCAN4x5x_Device_Configure(&devConfig);

    TCAN4x5x_Device_SetMode(TCAN4x5x_DEVICE_MODE_NORMAL);

    TCAN4x5x_MCAN_ClearInterruptsAll();

    }

    ------------------------------------------------------

    Additionally, I am unable to view the pictures you sent.

  • HI, Daniel.

    Parameter settings are in the code above, and function calls are in the code below.

  • 您好

    感谢您验证位定时码。如果您认为CANFD分析仪的定时设置相同,则需要检查CANH和CANL信号是否有错误。

  • HI,Daniel

    When I send a frame of CAN data, I can capture the SPI waveform, but there is no voltage change in the CAN bus waveform. How can we troubleshoot CANH and CANL?
    I believe the timing of the CANFD analyzer is the same. The timing configuration of CANFD is as follows:

  • 您好

    如果CAN信号上没有电压变化,则设备可能仍处于初始化模式或待机模式,控制寄存器0x1018[0]的INIT位=1。此位必须设置为0,以便设备在CAN总线上通信。

    你能读取设备寄存器并提供所有寄存器值的列表吗?如果是这样,我可以查看最终的设备配置是否有错误。如果您可以在尝试发送消息后进行此读取,则状态和中断寄存器还应显示在can传输过程中发生错误时可能设置的任何中断位。

  • 您好

    我读取了一些寄存器,第一张图片为上电后配置完成后的数据,第二张图片是发送一次CAN数据后读寄存器值的图片。

    上电后读寄存器图片:

    发送一次CAN数据寄存器图片:

  • 您好

    MCAN中断寄存器0x1050设置了EP、EW和PEA位。这意味着该设备有足够的传输错误达到错误警告(96)和错误被动(127)级别。仲裁中的协议错误位表示错误发生在消息传输的仲裁阶段。

    设备中断寄存器0x0820显示CANSLNT位已设置,这意味着设备在大约1秒内没有检测到显性和隐性状态之间的转换。在开发阶段,当没有正常的总线通信活动并且CAN消息活动可能稀疏时,这通常会被忽略。但是,如果存在正常的CAN通信活动,则这可能是物理故障的指示,设备无法正确检测CAN总线电压电平。

    我建议他们使用示波器监控CAN总线,并捕获CAN波形,以检查问题并验证寄存器报告的CAN位定时和错误标志。

    如果CAN总线上没有物理故障,则协议错误的最可能原因是CAN总线上节点之间的高速时钟容差或位定时不匹配。他们需要验证高速时钟的精确频率(即40MHz)是否在所需的容差范围内,并与CAN总线上的所有其他节点相匹配。CAN时间量基于时钟周期,因此频率需要准确,以便时间量具有正确的持续时间。

    之前为其CAN FD分析仪工具提供的位定时设置配置没有显示详细的时间量设置,只显示采样点%,因此位定时配置也可能需要一些调整。我还建议尝试调整标称和数据比特定时配置设置,以使用更多的每比特时间量(即使用较小的比特率预分频器)。

    TX缓冲器添加请求挂起寄存器0x10C没有设置任何位,因此TX队列中的消息似乎已被传输。不提供TX FIFO/队列状态寄存器0x10C,因此您可能也想读取该寄存器,以查看TX FIFO/排队的状态,如自由级别和获取与放置索引。

    我不知道正在尝试发送哪种类型的消息,它是经典CAN还是CAN FD消息,如果是CAN FD,它是否在设置比特率开关的情况下发送。我建议尝试不同的CAN消息,从经典CAN消息开始,如果成功,尝试将其作为CAN FD发送,不使用BRS,看看是否成功。然后尝试将其作为CAN FD与BRS一起发送,如果失败,那么您将确定问题出在比特定时上,并且BRS是由于时钟或采样点问题造成的。

  • 您好,我将按照您提供的方法去排查。之前发送数据是发送的CANFD数据,只使用了Tx_Buffer.

  • 您好

    我会等待你的更新。