This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TM4C1294NCPDT:CAN 总线发送未发送(未产生对象中断标志)

Guru**** 2616675 points

Other Parts Discussed in Thread: SN65HVD1050, TM4C1294NCPDT

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/781895/tm4c1294ncpdt-can-bus-transmission-not-sending-object-interrupt-flag-not-raised

器件型号:TM4C1294NCPDT
主题中讨论的其他器件:SN65HVD1050TM4C123

您好!

我使用 SN65HVD1050在 TM4C1294NCPDT 上与 CANbus 配合使用。

这是我在 Tiva 上的代码

volatile uint32_t g_ui32IntCount = 0;

//用于计算所用三条消息中每个消息的消息数的计数器。
volatile uint32_t g_ui32Msg1Count = 0;
volatile uint32_t g_ui32Msg2Count = 0;
volatile uint32_t g_ui32Msg3Count = 0;

//指示消息对象3已发送消息
的标志 volatile bool g_bMsgObj3Sent = 0;

//
指示发生了 volatile bfrag 错误标志;//指示发生了传输错误

//保存单独 CAN 消息
的 CAN 对象 tCANMsgObject g_sCANMsgObject1;
tCANMsgObject g_sCANMsgObject2;
tCANMsgObject g_sCANMsgObject3;

//保存正在传输的4个差分消息内容的消息缓冲器。
uint8_t g_pui8Msg1[4]={0、0、0、0};
uint8_t g_pui8Msg2[5]={2、2、2、2};
uint8_t g_pui8Msg3[6]={3、3、3、3、3、3、 3};
uint8_t g_pui8Msg4[8]={4、4、4、5、 5、5、5};


void init_canbustest (uint32_t sysClock){

SysCtlPeripheralEnable (SYSCTL_Periph_GPIOB);
GPIOPinConfigure (GPIO_PB0_CAN1RX);
GPIOPinConfigure (GPIO_PB1_CAN1TX);
GPIOPinTypeCAN (GPIO_PORTB_BASE、GPIO_PIN_0 | GPIO_PIN_1);

/*启用 CAN 外设*/
SysCtlPeripheralDisable (SYSCTL_Periph_CAN1);
SysCtlPeripheralReset (SYSCTL_Periph_CAN1);
SysCtlPeripheralEnable (SYSCTL_Periph_CAN1);


/*初始化 CAN 控制器*/
CANInit (CAN1_base);

/*设置 CAN 控制器*/
CANBitRateSet (CAN1_base、sysClock、50000);

/*启用 CAN 外设的中断*/
// CANIntRegister (CAN1_base、CAN_IRQ);
CANIntEnable (CAN1_base、CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);


IntEnable (INT_CAN1);
CANEnable (CAN1_base);

G_sCANMsgObject1.ui32MsgID = 0x1001;
G_sCANMsgObject1.ui32MsgIDMask = 0;
G_sCANMsgObject1.ui32Flags = MSG_OBJ_TX_INT_ENABLE;
G_sCANMsgObject1.ui32MsgLen = sizeof (g_pui8Msg1);
G_sCANMsgObject1.pui8MsgData = g_pui8Msg1;

G_sCANMsgObject2.ui32MsgID = 0x2001;
G_sCANMsgObject2.ui32MsgIDMask = 0;
G_sCANMsgObject2.ui32Flags = MSG_OBJ_TX_INT_ENABLE;
G_sCANMsgObject2.ui32MsgLen = sizeof (g_pui8Msg2);
G_sCANMsgObject2.pui8MsgData = g_pui8Msg2;

}

void CAN1IntHandler (){
uint32_t ui32Status;

ui32Status = CANIntStatus (CAN1_base、CAN_INT_STS_CAUST);
UARTprintf ("[CAN1IntHandler]2ndcaus:%x\n"、ui32Status);

if (ui32Status = CAN_INT_INTID_STATUS){
ui32Status = CANStatusGet (CAN1_base、CAN_STS_CONTROL);
UARTprintf ("[CAN_INT_INTID_STATUS]状态:%x\n"、ui32Status);

G_bErrFlag = 1;
} 否则、如果(ui32Status = 1){
CANIntClear (CAN1_base、1);
UARTprintf ("[MsgObj1]状态:%x\n"、ui32Status);

G_ui32Msg1Count++;
G_bErrFlag = 0;
} 否则、如果(ui32Status = 2){
CANIntClear (CAN1_base、2);
UARTprintf ("[MsgObj2]状态:%x\n"、ui32Status);

G_ui32Msg2Count++;
G_bErrFlag = 0;
} 否则{
UARTprintf ("不应打印任何内容\n");
}
}

void send_CAN_msg_test(){
PrintCANMessageInfo (&g_sCANMsgObject1、1);
CANMessageSet (CAN1_base、1、&g_sCANMsgObject1、MSG_OBJ_TYPE_TX);

if (g_bErrFlag) UARTprintf ("总线错误\n");

}

void PrintCANMessageInfo (tCANMsgObject * psCANMsg、uint32_t ui32MsgObj)
{
unsigned int uIdx;

UARTprintf ("发送 msg:obj=%d Id=0x%04X msg=0x"、ui32MsgObj、
psCANMsg->ui32MsgID);
for (uIdx = 0;uIdx < psCANMsg->ui32MsgLen;uIdx++)
{
UARTprintf ("%02x "、psCANMsg->pui8MsgData[uIdx]);
}
UARTprintf ("\n");
}

这是我的串行 COM 端口的一个片段。

这是我的设置图片(我使用的是一个 SN65HVD1050和一个 MCP2551)


 


从 COM 端口可以看到、当发送消息对象1时、中断永远不会发生。 因此它会导致总线错误。

如何解决 CAN 总线的这个问题?

谢谢、

Alex

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    状态0xE5的'5'表示一个位'0'错误。 这意味着 TM4C CANTX 引脚驱动0 (显性状态)、但 CANRX 引脚仍然看到高电平(隐性状态)。 这意味着您连接到 CAN 收发器或总线本身存在问题。 使用示波器或逻辑分析仪将 CANTX 引脚与 CAN 总线的状态进行比较。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Bob、您好!

    感谢您的快速响应。 不过,有几个进展,我仍有一些关切需要澄清。

    以下是对上一帖子的更改

    我使用了另一个 TM4C129、而不是 TM4C123和简单的 RX 代码。  

    接收器侧的代码  

    //
    //
    //// simple_rx.c -演示简单 CAN 消息接收的示例。
    //
    //版权所有(c) 2010-2017 Texas Instruments Incorporated。 保留所有权利。
    //软件许可协议
    //
    以源代码和二进制形式重新分发和使用,无论是否
    进行//修改,只要
    满足以下条件//:
    //
    重新分发源代码必须保留上述版权
    //声明、此条件列表和以下免责声明。
    //
    //二进制形式的再发行必须复制上述版权
    //声明、此条件列表和//
    
    分发随附的//文档和/或其他材料中的以下免责声明。
    ////
    未经
    
    事先书面许可,不能使用德州仪器公司的名称或//其贡献者的名称来认可或推广源自此软件的产品//。
    ////
    本软件由版权所有者和贡献者提供
    //“按原样”,不
    
    承认任何明示或暗示的保证,包括但不限于//适销性和对//特定用途适用性的暗示保证。 在任何情况下、版权
    //所有者或贡献者都不对任何直接、间接、偶然、
    //特殊、模范、 或相应的损害(包括但不
    限于采购替代产品或服务;丧失使用、
    //数据或利润; 或业务中断)、无论
    
    出于何种原因使用
    本软件(即使被告知可能会造成此类损坏)、还是出于任何原因而产生的任何//责任理论(无论是合同、严格责任还是侵权行为)//(包括疏忽或其他)。
    //
    //这是 Tiva 固件开发包的修订版2.1.4.178的一部分。
    ////
    *****************
    
    #include 
    #include 
    #include "inc/hw_ca.h"
    #include "include/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "driverlib/ca.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/driverlib.idio.h"#include "driverlib/driverlib"#include "driverlib.udio.idio.h
    
    
    
    
    
    //
    //! \addtogroup CAN_examples_list
    //! 

    简单 CAN RX (simple_Rx)

    //! //! 此示例显示了 CAN 的基本设置、以便接收消息 //! 总线的电流。 CAN 外设配置为接收消息 //! 使用任何 CAN ID、然后将消息内容打印到控制台。 //! //! 此示例使用以下外设和 I/O 信号。 您必须 //! 查看这些内容并根据您自己的董事会需要进行更改: //! - CAN0外设 //! - GPIO 端口 B 外设(用于 CAN0引脚) //! - CAN0RX - PB4 //! - CAN0TX - PB5 //! //! 以下 UART 信号仅配置为显示控制台 //! 消息。 CAN 的运行不需要这些参数。 //! - GPIO 端口 A 外设(用于 UART0引脚) //! - UART0RX - PA0 //! - UART0TX - PA1 //! //! 此示例使用以下中断处理程序。 要使用此示例 //! 在您自己的应用程序中、您必须将这些中断处理程序添加到 您的//! 矢量表。 //! - INT_CAN0 - CANIntHandler // /********* // // //跟踪 RX 中断次数 的计数器//发生,该计数器应与接收到的消息数匹配。 //// ***************** 易失性 uint32_t g_ui32MsgCount = 0; //********* // //中断处理程序的标志,指示已收到消息。 //// ***************** 易失性 bool g_BRXFlag = 0; //********* // //指示发生了一些接收错误的标志。 //// ***************** volatile bool g_BErrFlag = 0; //********* // //此函数将 UART0设置为用于控制台,以便 在示例运行时显示信息//。 //// ***************** void InitConsole (void) { // //启用用于 UART0引脚的 GPIO 端口 A。 // TODO:将其更改为您正在使用的 GPIO 端口。 // SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA); // //为端口 A0和 A1上的 UART0功能配置引脚复用。 //如果您的器件不支持引脚复用、则无需执行此步骤。 // TODO:更改此选项以选择您正在使用的端口/引脚。 // GPIOPinConfigure (GPIO_PA0_U0RX); GPIOPinConfigure (GPIO_PA1_U0TX); // //启用 UART0以便我们可以配置时钟。 // SysCtlPeripheralEnable (SYSCTL_Periph_UART0); // //使用内部16MHz 振荡器作为 UART 时钟源。 // UARTClockSourceSet (UART0_BASE、UART_CLOCK_PIOSC); // //为这些引脚选择替代(UART)功能。 // TODO:更改此选项以选择您正在使用的端口/引脚。 // GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1); // //初始化控制台 I/O 的 UART // UARTStdioConfig (0、115200、16000000); } //********* // //此函数是 CAN 外设的中断处理程序。 它会检查 //中断原因,并对 所有已接收到的消息进行计数。 //// ***************** void CANIntHandler (void) { uint32_t ui32Status; // //读取 CAN 中断状态以查找中断原因 // ui32Status = CANIntStatus (CAN1_base、CAN_INT_STS_CAUST); UARTprintf ("[CAN1IntHandler]原因:%x\n"、ui32Status); // //如果原因是控制器状态中断,则获取状态 // if (ui32Status = CAN_INT_INTID_STATUS) { // //读取控制器状态。 这将返回状态字段 //可以指示各种错误的错误位。 错误处理 //本示例中不是为了简单起见。 请参阅 // API 文档,了解有关错误状态位的详细信息。 //读取此状态的操作将清除中断。 // ui32Status = CANStatusGet (CAN1_base、CAN_STS_CONTROL); UARTprintf ("[INT STATUS]:%x\n"、ui32Status); // //设置一个标志来指示可能发生的某些错误。 // G_bErrFlag = 1; } // //检查原因是否是我们正在使用的消息对象1 //接收消息。 // 否则、如果(ui32Status = 1) { // //到达这一点意味着 RX 中断发生在上 //消息对象1,消息接收完成。 清除 //消息目标中断。 // CANIntClear (CAN1_base、1); UARTprintf ("[MsgReceived Interrupt]:%x\n"、ui32Status); // //递增计数器以跟踪已有多少消息 //已收到。 在实际应用中、这可用于将标志设置为 //指示何时接收到消息。 // G_ui32MsgCount++; // //设置标志以指示接收到的消息正暂挂。 // G_bRXFlag = 1; // //由于接收到消息,因此清除所有错误标志。 // G_bErrFlag = 0; } // //否则,发生意外导致中断的情况。 这应该是 //永远不会发生。 // 其他 { // //可以在此处执行伪中断处理。 // } } //********* // //配置 CAN 并输入一个循环来接收 CAN 消息。 //// ***************** int main (void) { uint32_t ui32SysClock; tCANMsgObject sCANMessage; uint8_t pui8MsgData[8]; // //将时钟设置为直接从外部晶振/振荡器运行。 // TODO:必须更改 SYSCTL_XTAL_VALUE 以匹配的值 //您的板上使用的晶体。 // ui32SysClock = SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480)、120000000);// //设置用于显示消息的串行控制台。 这是 //仅针对此示例程序,CAN 操作不需要。 // InitConsole(); // //对于此示例、CAN0与端口 B4和 B5上的 RX 和 TX 引脚一起使用。 //您使用的实际端口和引脚可能有所不同,请参阅 //数据表以了解更多信息。 // GPIO 端口 B 需要启用、以便可以使用这些引脚。 // TODO:将其更改为您正在使用的 GPIO 端口 // SysCtlPeripheralEnable (SYSCTL_Periph_GPIOB); // //配置 GPIO 引脚复用以选择这些引脚的 CAN0功能。 //此步骤选择可用于这些引脚的替代功能。 //如果您的器件支持 GPIO 引脚功能多路复用、这是必需的。 //请查阅数据表以查看每个引脚分配的函数。 // TODO:更改此选项以选择您正在使用的端口/引脚 // GPIOPinConfigure (GPIO_PB0_CAN1RX); GPIOPinConfigure (GPIO_PB1_CAN1TX); // //启用 GPIO 引脚上的复用功能。 以上步骤选择 //可用的备用功能。 此步骤实际上启用 //这些引脚的替代功能、而不是 GPIO。 //待办事项:更改此项以匹配您正在使用的端口/引脚 // GPIOPinTypeCAN (GPIO_PORTB_BASE、GPIO_PIN_0 | GPIO_PIN_1); // //已为 CAN 设置 GPIO 端口和引脚。 CAN 外设 //必须启用。 // SysCtlPeripheralEnable (SYSCTL_Periph_CAN1); // //初始化 CAN 控制器 // CANInit (CAN1_base); // //设置 CAN 总线的比特率。 此函数设置 CAN 针对标称配置的//总线时序。 您可以实现更多控制 //使用函数 CANBitTimingSet()代替 CAN 总线时序 //如果需要。 //在此示例中、CAN 总线设置为500kHz。 在以下函数中、 // SysCtlClockGet ()或 ui32SysClock 的调用被用来确定 //用于为 CAN 外设计时的时钟速率。 这是可以的 //如果您知道系统时钟的值,则替换为固定值, //保存额外的函数调用。 对于某些器件、CAN 外设是 //使用固定的8MHz 时钟进行计时,而不管在哪种情况下是系统时钟 //对 SysCtlClockGet()或 ui32SysClock 的调用应替换为 // 80000。 有关 CAN 的更多信息、请参阅数据表 //外设时钟。 // #if defined (target_IS_TM4C129_RA0)|| \ 已定义(TARGET_IS_TM4C129_RA1)|| \ 已定义(TARGET_IS_TM4C129_RA2) CANBitRateSet (CAN1_base、ui32SysClock、50000); #else CANBitRateSet (CAN1_base、SysCtlClockGet ()、50000); #endif // //在 CAN 外设上启用中断。 此示例使用静态 //分配中断处理程序,表示处理程序的名称 //位于启动代码的矢量表中。 如果您想使用动态的 //分配矢量表,然后还必须调用 CANIntRegister() //此处。 // // CANIntRegister (CAN1_base、CANIntHandler);// if using dynamic vectors CANIntEnable (CAN1_base、CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS); // //在处理器(NVIC)上启用 CAN 中断。 // IntEnable (INT_CAN0); // //启用 CAN 以进行操作。 // CANEnable (CAN1_base); // //初始化用于接收 CAN 消息的消息对象 //任何 CAN ID。 为了接收任何 CAN ID、ID 和掩码必须同时存在 //设置为0,并启用 ID 过滤器。 // sCANMessage.ui32MsgID = 0; sCANMessage.ui32MsgIDMask = 0; sCANMessage.ui32Flags = MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER; sCANMessage.ui32MsgLen = 8; // //现在将消息对象加载到 CAN 外设中。 加载后 // CAN 将在总线上接收任何消息,并将发生中断。 //使用消息对象1接收消息(与不同) //此示例中可以是任何值的 CAN ID)。 // CANMessageSet (CAN1_base、1、&sCANMessage、MSG_OBJ_TYPE_RX); UARTprintf ("CAN 设置完成\n"); // //输入循环以处理收到的消息。 该循环仅检查一个标志 //由中断处理程序设置,如果该位置位,则读取 //消息并显示内容。 这不是一种稳健的方法 //处理传入的 CAN 数据,并且一次只能处理一条消息。 //如果多条消息一起接收,则会收到一些消息 //可能被丢弃。 在实际应用中、应使用其他一些方法 //对收到的消息进行排队,以确保它们不会丢失。 您 //也可以使用 CAN FIFO 模式,允许消息为 //在处理前进行缓冲。 // for (;;) { unsigned int uIdx; // //如果该标志被置位、则表示发生了 RX 中断、然后 //有一条消息可以从 CAN 读取 // if (g_bRXFlag) { // //重复使用之前用于配置的同一消息对象 //用于接收消息的 CAN。 用于存储的缓冲器 //还必须提供接收到的数据,所以设置缓冲区指针 //在消息对象中。 // sCANMessage.pui8MsgData = pui8MsgData; // //从 CAN 读取消息。 使用1号报文对象 //(与 CAN ID 不相同)。 中断清除 //标志未设置、因为中已清除此中断 //中断处理程序。 // CANMessageGet (CAN1_base、1、&sCANMessage、0); // //清除挂起的消息标志,以便中断处理程序可以 //在下一条消息到达时再次设置它。 // G_bRXFlag = 0; // //检查是否有某些消息的指示 //丢失。 // if (sCANMessage.ui32Flags & MSG_OBJ_DATA_LOST) { UARTprintf ("检测到 CAN 消息丢失\n"); } // //打印接收到的消息的内容。 // UARTprintf ("Msg ID=0x%08X len=%u data=0x"、 sCANMessage.ui32MsgID、sCANMessage.ui32MsgLen); for (uIdx = 0;uIdx < sCANMessage.ui32MsgLen;uIdx++) { UARTprintf ("%02x "、pui8MsgData[uIdx]); } UARTprintf ("total count=%u\n"、g_ui32MsgCount); } } // //返回无错误 // 返回(0); }

    发送器侧的代码

    volatile uint32_t g_ui32IntCount = 0;
    
    //用于计算所用三条消息中每个消息的消息数的计数器。
    volatile uint32_t g_ui32Msg1Count = 0;
    volatile uint32_t g_ui32Msg2Count = 0;
    volatile uint32_t g_ui32Msg3Count = 0;
    
    //指示消息对象3已发送消息
    的标志 volatile bool g_bMsgObj3Sent = 0;
    
    //
    指示发生了 volatile bfrag 错误标志;//指示发生了传输错误
    
    //保存单独 CAN 消息
    的 CAN 对象 tCANMsgObject g_sCANMsgObject1;
    tCANMsgObject g_sCANMsgObject2;
    tCANMsgObject g_sCANMsgObject3;
    
    //保存正在传输的4个差分消息内容的消息缓冲器。
    uint8_t g_pui8Msg1[4]={1、2、3、4};
    uint8_t g_pui8Msg2[5]={2、2、2、2};
    uint8_t g_pui8Msg3[6]={3、3、3、3、3、3、 3};
    uint8_t g_pui8Msg4[8]={4、4、4、5、 5、5、5};
    
    
    void init_canbustest (uint32_t sysClock){
    
    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOB);
    GPIOPinConfigure (GPIO_PB0_CAN1RX);
    GPIOPinConfigure (GPIO_PB1_CAN1TX);
    GPIOPinTypeCAN (GPIO_PORTB_BASE、GPIO_PIN_0 | GPIO_PIN_1);
    
    /*启用 CAN 外设*/
    SysCtlPeripheralDisable (SYSCTL_Periph_CAN1);
    SysCtlPeripheralReset (SYSCTL_Periph_CAN1);
    SysCtlPeripheralEnable (SYSCTL_Periph_CAN1);
    
    
    /*初始化 CAN 控制器*/
    CANInit (CAN1_base);
    
    /*设置 CAN 控制器*/
    CANBitRateSet (CAN1_base、sysClock、50000);
    
    /*启用 CAN 外设的中断*/
    CANIntEnable (CAN1_base、CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);
    IntEnable (INT_CAN1);
    
    CANEnable (CAN1_base);
    
    G_sCANMsgObject1.ui32MsgID = 1;
    G_sCANMsgObject1.ui32MsgIDMask = 0;
    G_sCANMsgObject1.ui32Flags = MSG_OBJ_TX_INT_ENABLE;
    G_sCANMsgObject1.ui32MsgLen = sizeof (g_pui8Msg1);
    G_sCANMsgObject1.pui8MsgData = g_pui8Msg1;
    
    }
    
    void CAN1IntHandler (){
    uint32_t ui32Status;
    
    ui32Status = CANIntStatus (CAN1_base、CAN_INT_STS_CAUST);
    UARTprintf ("[CAN1IntHandler]原因:%x\n"、ui32Status);
    
    if (ui32Status = CAN_INT_INTID_STATUS){
    ui32Status = CANStatusGet (CAN1_base、CAN_STS_CONTROL);
    UARTprintf ("[INT STATUS]:%x\n"、ui32Status);
    G_bErrFlag = 1;
    } 否则、如果(ui32Status = 1){
    CANIntClear (CAN1_base、1);
    UARTprintf ("[MsgObj1]状态:%x\n"、ui32Status);
    G_bErrFlag = 0;
    } 否则{
    UARTprintf ("不应打印任何内容\n");
    }
    }
    
    void send_CAN_msg_test(){
    PrintCANMessageInfo (&g_sCANMsgObject1、1);
    CANMessageSet (CAN1_base、1、&g_sCANMsgObject1、MSG_OBJ_TYPE_TX);
    
    if (g_bErrFlag) UARTprintf ("总线错误\n");
    (*(uint32_t *) g_pui8Msg1)++;
    }
    
    void PrintCANMessageInfo (tCANMsgObject * psCANMsg、uint32_t ui32MsgObj)
    {
    unsigned int uIdx;
    
    UARTprintf ("发送 msg:obj=%d Id=0x%04X msg=0x"、ui32MsgObj、
    psCANMsg->ui32MsgID);
    for (uIdx = 0;uIdx < psCANMsg->ui32MsgLen;uIdx++)
    {
    UARTprintf ("%02x "、psCANMsg->pui8MsgData[uIdx]);
    }
    UARTprintf ("\n");
    } 

    2.我必须 显式调用 CANIntRegister (CAN1_base、CANIntHandler)、并在 startup_css.c 文件内创建该函数的原型。

    这是我的示波器图像

    由于某些原因、CANBUS 现在可以正常工作。 在接收器端、中断永远不会达到发送的完成状态、也不会在0xE5旁边显示任何错误。  现在、如果总线上没有接收器模块、它会将错误消息显示为0x63。  

    现在、我有一些问题/疑问

    错误代码0x63是什么? 在总线上未接收到错误代码时、是否为预期错误代码?

    2.当我每500ms 触发一次发送消息时、我看到中断的状态代码从0x48变为0x08。  在我的研究中、我认为0x08意味 着 CAN_STATUS_TXOK。  Correspondly、在接收器侧、我看到中断状态为0x10、 即 CAN_STATUS_RXOK。 什么是0x48

    3.当我没有在 while 循环中放置任何延迟时、我收到了"CAN 消息丢失检测到"。  这在 CAN 通信中是正常的吗? 我将延迟推至50ms、那么消息很少发生。 如何最好地处理 CAN 通信以确保数据良好?

    4.您推荐的 CAN 分析仪是什么?

    谢谢、

    Alex

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    数据表的第1381页描述了状态寄存器位。 0x63的状态表示(LEC = 3)没有接收到应答。 如果 CAN 总线上没有其他节点、这是预期的结果。 0x48的0x40是警告标志。

    [引用用户="Hau Tran]3. 当我没有在 while 环路中放置任何延迟时、我收到了"CAN 消息丢失检测到"。  这在 CAN 通信中是正常的吗? 我将延迟推至50ms、那么消息很少发生。 如何最好地处理 CAN 通信以确保数据良好?

    您可能正在尝试在上一条消息完成之前传输新消息。 使用参数 CAN_STS_TXREQUEST 调用 CANStatusGet (),以查看特定报文对象是否尚未完成其报文的传输。

    [引用 user="Hau Tran]4. 您推荐的 CAN 分析器是什么?[/quot]

    我只使用具有 CAN 总线解释器的 USB 逻辑分析仪。 我的旧款、但 有许多新的便宜款。