您好!
我目前在调试C2000 + TCAN4550-Q1实现SPI转CANFD.现在我遇到了一些困难,想请求下你们的帮助!
TCAN4550-Q1 data sheet, product information and support | TI.com
我下载了产品页面的示例代码,经过调试SPI读取与写入寄存器没有问题,但当进行CAN通信的时候出现了问题,出现了CAN总线错误
用示波器查看CANH波形发现,CAN波特率为1/6us = 166.6K,与demo上显示的500K不相符合
/* Configure the CAN bus speeds */ TCAN4x5x_MCAN_Nominal_Timing_Simple TCANNomTiming = {0}; // 500k arbitration with a 40 MHz crystal ((40E6 / 2) / (32 + 8) = 500E3) TCANNomTiming.NominalBitRatePrescaler = 2; TCANNomTiming.NominalTqBeforeSamplePoint = 32; TCANNomTiming.NominalTqAfterSamplePoint = 8; TCAN4x5x_MCAN_Data_Timing_Simple TCANDataTiming = {0}; // 2 Mbps CAN FD with a 40 MHz crystal (40E6 / (15 + 5) = 2E6) TCANDataTiming.DataBitRatePrescaler = 1; TCANDataTiming.DataTqBeforeSamplePoint = 15; TCANDataTiming.DataTqAfterSamplePoint = 5; /* Configure the TCAN4550 Non-CAN-related functions */ TCAN4x5x_DEV_CONFIG devConfig = {0}; // Remember to initialize to 0, or you'll get random garbage! devConfig.SWE_DIS = 0; // Keep Sleep Wake Error Enabled (it's a disable bit, not an enable) devConfig.DEVICE_RESET = 0; // Not requesting a software reset devConfig.WD_EN = 0; // Watchdog disabled devConfig.nWKRQ_CONFIG = 0; // Mirror INH function (default) devConfig.INH_DIS = 0; // INH enabled (default) devConfig.GPIO1_GPO_CONFIG = TCAN4x5x_DEV_CONFIG_GPO1_MCAN_INT1; // MCAN nINT 1 (default) devConfig.FAIL_SAFE_EN = 0; // Failsafe disabled (default) devConfig.GPIO1_CONFIG = TCAN4x5x_DEV_CONFIG_GPIO1_CONFIG_GPO; // GPIO set as GPO (Default) devConfig.WD_ACTION = TCAN4x5x_DEV_CONFIG_WDT_ACTION_nINT; // Watchdog set an interrupt (default) devConfig.WD_BIT_RESET = 0; // Don't reset the watchdog devConfig.nWKRQ_VOLTAGE = 0; // Set nWKRQ to internal voltage rail (default) devConfig.GPO2_CONFIG = TCAN4x5x_DEV_CONFIG_GPO2_NO_ACTION; // GPO2 has no behavior (default) devConfig.CLK_REF = 1; // Input crystal is a 40 MHz crystal (default) devConfig.WAKE_CONFIG = TCAN4x5x_DEV_CONFIG_WAKE_DISABLED;// Wake pin can be triggered by either edge (default) TCAN4x5x_Device_Configure(&devConfig); // Configure the device with the above configuration TCAN4x5x_Device_SetMode(TCAN4x5x_DEVICE_MODE_NORMAL); // Set to normal mode, since configuration is done. This line turns on the transceiver TCAN4x5x_MCAN_ClearInterruptsAll(); bool TCAN4x5x_Device_Configure(TCAN4x5x_DEV_CONFIG *devCfg) { // First we must read the register Uint32 readDevice = AHB_READ_32(REG_DEV_MODES_AND_PINS); // Then mask the bits that will be set by the struct readDevice &= ~(REG_BITS_DEVICE_MODE_SWE_MASK | REG_BITS_DEVICE_MODE_DEVICE_RESET | REG_BITS_DEVICE_MODE_WDT_MASK | REG_BITS_DEVICE_MODE_NWKRQ_CONFIG_MASK | REG_BITS_DEVICE_MODE_INH_MASK | REG_BITS_DEVICE_MODE_GPO1_FUNC_MASK | REG_BITS_DEVICE_MODE_FAIL_SAFE_MASK | REG_BITS_DEVICE_MODE_GPO1_MODE_MASK | REG_BITS_DEVICE_MODE_WDT_ACTION_MASK | REG_BITS_DEVICE_MODE_WDT_RESET_BIT | REG_BITS_DEVICE_MODE_NWKRQ_VOLT_MASK | REG_BITS_DEVICE_MODE_TESTMODE_ENMASK | REG_BITS_DEVICE_MODE_GPO2_MASK | REG_BITS_DEVICE_MODE_WD_CLK_MASK | REG_BITS_DEVICE_MODE_WAKE_PIN_MASK); // Copy to a temporary location in memory, so we don't modify the incoming struct TCAN4x5x_DEV_CONFIG tempCfg; tempCfg.word = devCfg->word; // Clear the reserved flags. tempCfg.RESERVED0 = 0; tempCfg.RESERVED1 = 0; tempCfg.RESERVED2 = 0; tempCfg.RESERVED3 = 0; tempCfg.RESERVED4 = 0; tempCfg.RESERVED5 = 0; // Set the bits according to the incoming struct readDevice |= (REG_BITS_DEVICE_MODE_FORCED_SET_BITS | tempCfg.word); AHB_WRITE_32(REG_DEV_MODES_AND_PINS, readDevice); #ifdef TCAN4x5x_DEVICE_VERIFY_CONFIGURATION_WRITES // Check to see if the write was successful. Uint32 readValue = AHB_READ_32(REG_DEV_MODES_AND_PINS); // Read value if (readValue != readDevice) return false; #endif return true; }
CAN波特率设置与demo一致,时钟频率设置的40Mhz, 已确认。
当修改TCANNOTIMING的是配置如下时,成功实现通讯
/* Configure the CAN bus speeds */ TCAN4x5x_MCAN_Nominal_Timing_Simple TCANNomTiming = {0}; // 500k arbitration with a 40 MHz crystal ((40E6 / 2) / (32 + 8) = 500E3) TCANNomTiming.NominalBitRatePrescaler = 2; TCANNomTiming.NominalTqBeforeSamplePoint = 10; TCANNomTiming.NominalTqAfterSamplePoint = 3;
如果我有任何问题,请联系我,谢谢!