主题中讨论的其他器件:TCAN4550
工具与软件:
团队成员、您好!
我们正在开发 TCAN4551、并使用了以下链接中的 CAN 堆栈:
https://github.com/TexasInstruments/CC26XX-TCAN4550-EXAMPLES/tree/master/source/ti/can/tcan4x5x
我们使用了水线功能、其中配置了水线位60、并且在接收到60个数据包并进行以下配置时得到水线中断:
静态空 TCAN4550_SetConfiguration (void)
{
uint8_t TX_param_size;
uint8_t rx_param_size;
//清除由于 MCU 启动期间引脚多路复用发生变化而可能设置的任何 SPI ERR 标志
TCAN4x5x_IERR Device_Clear ();
/*第一步尝试清除所有中断*/
/*初始化为0以使所有位都设置为0 */
TCAN4x5x_TCANDEV_IE Device_Interrupt_Enable ={0};
/*为简单起见、禁用所有非 MCAN 相关中断*/
TCAN4x5x_TCAN74ruptEnable Device_Configure (&DEV_ie);
/*设置一个新的 MCAN IR 对象以便轻松执行中断检查*/
TCAN4x5x_TCANDev_ir Device_Interrupts ={0};
/*请求使用当前器件(非 MCAN)中断值更新结构*/
TCAN4x5x_TCAN45nrupts Device_Read (&DEV_ir);
/*如果设置了上电中断标志*/
if (dev_ir.PWRON)
{
/*清除它,因为如果它没有在~4分钟内清除,它进入睡眠*/
TCAN4x5x_TCAN45nrupts Device_Clear (&DEV_ir);
}
/*配置 CAN 总线速度*/
/*采用40 MHz 晶振的500k 仲裁(40E6 /(57 + 22 + 1 (同步))=)*/
/* TCAN_Timing =((40E6 / BitRatePrescaler)/(TqBeforeSamplePoint + TqAfterSamplePoint)*/
/*配置 CAN 总线速度*/
/*采用40 MHz 晶振的500k 仲裁(40E6 /(57 + 22 + 1 (同步))= 500E3)*/
TCAN4x5x_MCAN_TCANNomTiming Nominal_Timing_Simple ={0};
TCANNomTiming.NominalBitRatePrescaler = 2;
TCANNomTiming.NominalTqBeforeSamplePoint = 32;
TCANNomTiming.NominalTqAfterSamplePoint = 8;
//带有40 MHz 晶体的2Mbps CAN FD (40E6/(15 + 5)= 2E6)*
TCAN4x5x_MCAN_TCANDataTiming Data_Timing_Simple ={0};
TCANDataTiming.DataBitRatePrescaler = 1;
TCANDataTiming.DataTqBeforeSamplePoint = 15;
TCANDataTiming.DataTqAfterSamplePoint = 5;
/*配置 MCAN 内核设置*/
/*记住要初始化为0,否则你会得到随机的垃圾! */
TCAN4x5x_MCAN_CCCR_Config cccrConfig ={0};
/* CAN FD 模式启用*/
// cccrConfig.FDOE = 0;
cccrConfig.FDOE = 0;
/* CAN FD 比特率切换启用*/
cccrConfig.BRSE = 1;
/*配置默认的 CAN 数据包过滤设置*/
TCAN4x5x_MCAN_GFC Global_Filter_Configuration ={0};
/*拒绝远程帧(TCAN4x5x 不支持此功能)*/
GFC.RRFE = 1;
/*拒绝远程帧(TCAN4x5x 不支持此功能)*/
GFC.RRFS = 1;
/*传入消息与过滤器不匹配时的默认行为是接受 RXFIO0以接收扩展 ID 消息(29位 ID)*/
GFC.ANFE = TCAN4x5x_GFC_REJECT;//TCAN4x5x_GFC_ACCEP_INTO_RXFIFO0;
/*传入消息与标准 ID 消息(11位 ID)的 RXFIO0接收过滤器时的默认行为*/
GFC.ANFS = TCAN4x5x_GFC_REJECT;//TCAN4x5x_GFC_ACCEP_INTO_RXFIFO0;
RX_PARAM_SIZE = 60;
TX_PARAM_SIZE = 0;
TCAN4x5x_MRAM_Config MRAMConfiguration ={0};
//标准 ID 元素数量、必须为定义的每个元素向 MRAM 写入过滤器
MRAMConfiguration.SIDNumElements = 3;
//扩展 ID 元素数量、必须为定义的每个元素向 MRAM 写入过滤器
MRAMConfiguration.XIDNumElements = 16;
// RX0元素数量
MRAMConfiguration.Rx0NumElements = Rx_PARAM_SIZE;
// RX0数据有效载荷大小(使用定义)
MRAMConfiguration.Rx0ElementSize = MRAM_8_MRAM Byte_Data;
// MRAMConfiguration.Rx0ElementSize = MRAM_64_MRAM Byte_Data;
// Rx1单元数
MRAMConfiguration.Rx1NumElements = 0;
// Rx1数据有效载荷大小(使用定义)
MRAMConfiguration.Rx1ElementSize = MRAM_64_MRAM Byte_Data;
// RX 缓冲区元素数量
MRAMConfiguration.RxBufNumElements = 0;
// RX 缓冲区数据有效载荷大小(使用定义)
MRAMConfiguration.RxBufElementSize = MRAM_64_MRAM Byte_Data;
// TX 事件 FIFO 元素数量
MRAMConfiguration.TxEventFIFONumElements = 0;
// TX 缓冲区元素数量
MRAMConfiguration.TxBufferNumElements = TX_PARAM_SIZE;
// TX 缓冲区数据有效载荷大小(使用定义)
MRAMConfiguration.TxBufferElementSize = MRAM_64_MRAM Byte_Data;
/*使用上述设置配置 MCAN 内核、该块中的更改是写保护寄存器、
*因此,一次性完成这些任务最有意义,因此我们只需解锁和锁定一次*/
//开始访问受保护的寄存器
TCAN4x5x_MCAN_EnableProtectedRegisters ();
//启用 FD 模式和比特率切换
TCAN4x5x_MCAN_ConfigureCCCRRegister (&cccrConfig);
//配置全局过滤器配置(默认 CAN 消息行为)
TCAN4x5x_MCAN_ConfigureGlobalFilter (&GFC);
//设置标称/仲裁位时序
TCAN4x5x_MCAN_ConfigureNomin52I Timing_Simple (&TCANNomTiming);
//设置 CAN FD 时序
TCAN4x5x_MCAN_ConfigureCLA Timing_Simple (&TCANDataTiming);
//清除全部 MRAM (将0写入全部 MRAM)
TCAN4x5x_MRAM_CLEAR ();
//设置与 MRAM 配置相关的适用寄存器
TCAN4x5x_MRAM_Configure (&MRAMConfiguration);
//禁用受保护的写入并使器件退出 INIT 模式
TCAN4x5x_MCAN_DisableProtectedRegisters ();
/*为 MCAN 设置我们要启用的中断*/
/*记住要初始化为0,否则你会得到随机的垃圾! */
TCAN4x5x_MCAN_TCAN_IE Interrupt_Enable mcan_ie ={0};
/* RX FIFO 0新水印中断启用*/
mcan_ie.RF0WE = 1;
/*启用适当的寄存器*/
TCAN4x5x_MCAN_ConfigureInterruptEnable (&mcan_ie);
//初始化接收和发送缓冲区
TCAN4550_SetRxTxMessageBuffers (CAN_RX_ID_MSG、CAN_RX_ID_MSG_TYPE);
/*配置 TCAN4550非 CAN 相关功能*/
///记住要初始化为0,否则你会得到随机的垃圾!
TCAN4x5x_DEV_CONFIG devConfig ={0};
//保持启用睡眠唤醒错误(它是禁用位、而不是启用位)
devConfig.SWE_DIS = 0;
//不请求软件复位
devConfig.device_reset = 0;
//禁用看门狗
devConfig.WD_EN = 0;
//镜像 INH 功能(默认)
devConfig.nWKRQ_CONFIG = 0;
//已启用 INH (默认)
devConfig.INH_DIS = 0;
// MCAN nINT 1 (默认值)
devConfig.GPIO1_GPO_CONFIG = TCAN4x5x_DEV_CONFIG_GPO1_MCAN_INT1;
//失效防护已禁用(默认)
devConfig.FAIL_SAFE_EN = 0;
// GPIO 设置为 GPO (默认)
devConfig.GPIO1_CONFIG = TCAN4x5x_DEV_CONFIG_GPIO1_CONFIG_GPO;
//看门狗设置中断(默认)
devConfig.WD_ACTION = TCAN4x5x_DEV_CONFIG_WDT_ACTION_nINT;
//不要重置看门狗
devConfig.WD_BIT_RESET = 0;
//将 nWKRQ 设置为内部电压轨(默认值)
devConfig.nWKRQ_voltage = 0;
// GPO2没有行为(默认)
devConfig.GPO2_CONFIG = TCAN4x5x_DEV_CONFIG_GPO2_NO_ACTION;
//输入晶体为40 MHz 晶体(默认)
devConfig.CLK_REF = 0;
// Wake 引脚可由任一边沿触发(默认)
devConfig.WAKE_CONFIG = TCAN4x5x_DEV_CONFIG_WAKE_Both_EDGE;
//使用上述配置配置设备
TCAN4x5x_TCAN1042 Device_Configure (&devConfig);
}
以下是接收中断函数:
void hw_isr_Rx (uint32_t * msg_ID、uint8_t * msg_Payload、uint8_t * msg_dlc)
{
//设置一个新的 MCAN IR 对象、以便于进行中断检查
TCAN4x5x_MCAN_INTERRUPT mcan_ir ={0};
//读取中断寄存器
TCAN4x5x_MCAN_ReadInterrupts (&M);
//如果 RX FIFO 0中有一条新的消息
// if (mcan_ir.RF0N){//新消息中断
中频(mcan_ir.RF0W)
{
TCAN4x5x_MCAN_ClearInterrupts (&M);
/*设置接收标志*/
rxrcvd = true;
}
}
在下面的函数中、我们检查是否设置了接收标志、如果设置了、则我们将从 FIFO 读取数据。
void execute()
{
if (rxrcvd == true)
{
rxrcvd = false;
uint32_t RF1W_reg_1 = AHB_READ_32 (0x10A4);
cntlp = RF1W_reg_1;
for (uint8_t i = 0;i<cntlp;i++)
{
numBytes = TCAN4x5x_MCAN_ReadNextFIFO (RXFIFO0、&MsgHeader、dataPayload);
tcan_store_data_q[i].canId = MsgHeader.ID;
memcpy (tcan_store_data_q[i].dataBytes、dataPayload、sizeof (tcan_store_data_q[i].dataBytes));
tcan_store_data_q[i].dlc = MsgHeader.dlc;
}
}
在上述配置中、我们观察到接收数据时出现数据包丢失、即接收到的数据包数比发送的数据包少。
您能指导我们解决这个问题吗?