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.

[参考译文] CCS/EK-TM4C123GXL:simple_TX simple_Rx CAN 总线困难

Guru**** 2482105 points
Other Parts Discussed in Thread: SN65HVD232

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/710711/ccs-ek-tm4c123gxl-simple_tx-simple_rx-can-bus-difficulties

器件型号:EK-TM4C123GXL
主题中讨论的其他器件:SN65HVD232TM4C123

工具/软件:Code Composer Studio

我一直致力于获取外设库中包含的 simple_tx 和 simple_Rx 的示例代码并使其正常运行、并遇到了阻碍。 毫无疑问,我做了一些错误的事情,但我不能为我的生活弄清楚它是什么。

硬件:

2个 TM4C123GXL LaunchPad

- 2个 SN65HVD232具有120 Ω 终端电阻器的 CAN 收发器。

代码:

在外设库中提供的 simple_tx 和 simple_Rx。

IDE 是 Code Composer Studio V7.4、使用 TI v16.9.8.LTS 编译器

最初、我运行代码块库而不进行任何修改、保存了将 TX/Rx 更新为 PE4和 PE5、并动态分配中断。 这导致同一消息的持续传输。 中断将持续触发、与程序顶部指示的行为不同、"消息数据"和"总计数"将异步递增。

*讯息传输在第一个结束后立即开始。

我找到了一种解决方法。 在 中断结束时插入 CANMessageClear (CAN0_BASE、1);命令。 这可防止在 主 while 循环中再次调用 CANMessageSet 之前重新发送消息。 我必须修改供应商示例代码以使其工作、而不仅仅是为硬件配置端口、这似乎很奇怪。 我在这里缺少什么吗?

PRObelm 2我没有找到解决方法。

simple_Rx、此代码触发消息对象中断、因此它确认已收到消息。 但是,它打印出来的消息 ID 始终与装载到 msgid 的消息对象中的内容完全相同。

IE:如果我将 msgid 设置为0,以便它接收任何消息,它将在收到消息时始终打印 ID 0。 如果我加载0x0002 (但将掩码保留为0)、那么它始终打印 ID 0x00000002、而不管它应该接收到的消息 ID 是什么。

无论我如何配置 ID 和消息数据、它始终返回0作为消息长度和数据。

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

    我已经将代码从第一个帖子中退出、以尽可能保持整洁、我将在这里添加代码。  请注意、它本质上是来自外设库的 bone 库存代码。

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

    简单 CAN TX (simple_tx)

    //! //! 此示例显示了 CAN 的基本设置、以便传输消息 //! 总线上的电流。 CAN 外设配置为发送消息 //! 具有特定的 CAN ID。 然后每秒传输一条消息 、//! 使用简单的延迟环路进行计时。 发送的消息是4 //! 包含递增模式的字节消息。 A CAN 中断 //! 处理程序用于确认消息传输并计数 //! 已发送的消息。 //! //! 此示例使用以下外设和 I/O 信号。 您必须 //! 查看这些内容并根据您自己的董事会需要进行更改: //! - CAN0外设 //! - GPIO 端口 E 外设(用于 CAN0引脚) //! - CAN0RX - PE4 //! - CAN0TX - PE5 //! //! 以下 UART 信号仅配置为显示控制台 //! 消息。 CAN 的运行不需要这些参数。 //! - GPIO 端口 A 外设(用于 UART0引脚) //! - UART0RX - PA0 //! - UART0TX - PA1 //! //! 此示例使用以下中断处理程序。 要使用此示例 //! 在您自己的应用程序中、您必须将这些中断处理程序添加到 您的//! 矢量表。 //! - INT_CAN0 - CANIntHandler // /********* // // //跟踪 TX 中断次数 的计数器//发生,该计数器应与发送的 TX 消息数匹配。 //// ***************** 易失性 uint32_t g_ui32MsgCount = 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); } //********* // //此函数使用简单的轮询方法提供1秒延迟。 //// ***************** void SimpleDelay (void) { // //延迟周期1秒 // SysCtlDelay (16000000 / 3); } //********* // //此函数是 CAN 外设的中断处理程序。 它会检查 //中断原因,并保持 //已传输的所有消息的计数。 //// ***************** void CANIntHandler (void) { uint32_t ui32Status; // //读取 CAN 中断状态以查找中断原因 // ui32Status = CANIntStatus (CAN0_BASE、CAN_INT_STS_CAUST); // //如果原因是控制器状态中断,则获取状态 // if (ui32Status = CAN_INT_INTID_STATUS) { // //读取控制器状态。 这将返回状态字段 //可以指示各种错误的错误位。 错误处理 //本示例中不是为了简单起见。 请参阅 // API 文档,了解有关错误状态位的详细信息。 //读取此状态的操作将清除中断。 如果 // CAN 外设未与其它 CAN 器件连接到 CAN 总线 //存在,则会发生错误,并在中指示 //控制器状态。 // ui32Status = CANStatusGet (CAN0_BASE、CAN_STS_CONTROL); // //设置一个标志来指示可能发生的某些错误。 // G_bErrFlag = 1; } // //检查原因是否是我们正在使用的消息对象1 //发送消息。 // 否则、如果(ui32Status = 1) { // //到达这一点意味着 TX 中断发生在上 //消息对象1、消息 TX 完成。 清除 //消息目标中断。 // CANIntClear (CAN0_BASE、1); // //递增计数器以跟踪已有多少消息 //已发送。 在实际应用中、这可用于将标志设置为 //指示何时发送消息。 // G_ui32MsgCount++; // //由于消息已发送,请清除所有错误标志。 // G_bErrFlag = 0; //CANMessageClear (CAN0_BASE、1);//*** 添加了行:取消注释以防止重复传输 // //否则,发生意外导致中断的情况。 这应该是 //永远不会发生。 // 其他 { // //可以在此处执行伪中断处理。 // } } //********* // //配置 CAN 并输入循环以传输周期性 CAN 消息。 //// ***************** int main (void) { #if defined (target_IS_TM4C129_RA0)|| \ 已定义(TARGET_IS_TM4C129_RA1)|| \ 已定义(TARGET_IS_TM4C129_RA2) uint32_t ui32SysClock; #endif tCANMsgObject sCANMessage; uint32_t ui32MsgData; uint8_t * pui8MsgData; pui8MsgData =(uint8_t *) ui32MsgData; // //将时钟设置为直接从外部晶振/振荡器运行。 // TODO:必须更改 SYSCTL_XTAL_VALUE 以匹配的值 板上的//晶体。 // #if defined (target_IS_TM4C129_RA0)|| \ 已定义(TARGET_IS_TM4C129_RA1)|| \ 已定义(TARGET_IS_TM4C129_RA2) ui32SysClock = SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz | SYSCTL_OSC_MAIN | SYSCTL_USE_OSC) 25000000); #else SysCtlClockSet (SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHz); #endif // //设置用于显示消息的串行控制台。 这是 //仅针对此示例程序,CAN 操作不需要。 // InitConsole(); // //对于此示例、CAN0与端口 B4和 B5上的 RX 和 TX 引脚一起使用。 //您使用的实际端口和引脚可能有所不同,请参阅 //数据表以了解更多信息。 //需要启用 GPIO 端口 E,以便可以使用这些引脚。 // TODO:将其更改为您正在使用的 GPIO 端口 // SysCtlPeripheralEnable (SYSCTL_Periph_GPIOE); // //配置 GPIO 引脚复用以选择这些引脚的 CAN0功能。 //此步骤选择可用于这些引脚的替代功能。 //如果您的器件支持 GPIO 引脚功能多路复用、这是必需的。 //请查阅数据表以查看每个引脚分配的函数。 // TODO:更改此选项以选择您正在使用的端口/引脚 // GPIOPinConfigure (GPIO_PE4_CAN0RX); GPIOPinConfigure (GPIO_PE5_CAN0TX); // //启用 GPIO 引脚上的复用功能。 以上步骤选择 //可用的备用功能。 此步骤实际上启用 //这些引脚的替代功能、而不是 GPIO。 //待办事项:更改此项以匹配您正在使用的端口/引脚 // GPIOPinTypeCAN (GPIO_Porte _BASE、GPIO_PIN_4 | GPIO_PIN_5); // //已为 CAN 设置 GPIO 端口和引脚。 CAN 外设 //必须启用。 // SysCtlPeripheralEnable (SYSCTL_Periph_CAN0); // //初始化 CAN 控制器 // CANInit (CAN0_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 (CAN0_BASE、ui32SysClock、50000); #else CANBitRateSet (CAN0_BASE、SysCtlClockGet ()、50000); #endif // //在 CAN 外设上启用中断。 此示例使用静态 //分配中断处理程序,表示处理程序的名称 //位于启动代码的矢量表中。 如果您想使用动态的 //分配矢量表,然后还必须调用 CANIntRegister() //此处。 // CANIntRegister (CAN0_BASE、CANIntHandler);// if using dynamic vectors // CANIntEnable (CAN0_BASE、CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS); // //在处理器(NVIC)上启用 CAN 中断。 // IntEnable (INT_CAN0); // //启用 CAN 以进行操作。 // CANEnable (CAN0_BASE); // //初始化将用于发送 CAN 的消息对象 //消息。 消息将是包含一个递增的4个字节 //值。 最初它将设置为0。 // ui32MsgData = 0; sCANMessage.ui32MsgID = 0x1001; sCANMessage.ui32MsgIDMask = 0; sCANMessage.ui32Flags = MSG_OBJ_TX_INT_ENABLE; sCANMessage.ui32MsgLen = sizeof (pui8MsgData); sCANMessage.pui8MsgData = pui8MsgData; // //输入循环以发送消息。 根据、将发送一条新消息 //秒。 4字节的消息内容将被视为 uint32_t //并每次递增1。 // while (1) { // //将显示消息计数和的消息打印到控制台 //正在发送的消息的内容。 // UARTprintf ("发送消息:0x%02x %02x %02x %02x %02x"、 pui8MsgData[0]、pui8MsgData[1]、pui8MsgData[2]、 pui8MsgData[3]); // //使用对象1发送 CAN 消息(与不一样 // CAN ID、在本例中也是1)。 此函数将导致 //要立即传输的消息。 // CANMessageSet (CAN0_BASE、1、&sCANMessage、MSG_OBJ_TYPE_TX); CANIntDisable (CAN0_BASE、CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS); // //现在等待1秒后再继续 // SimpleDelay(); CANIntEnable (CAN0_BASE、CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS); // //检查错误标志以查看是否发生错误 // if (g_bErrFlag) { UARTprintf ("错误-电缆已连接?\n"); } 其他 { // //如果没有错误,则打印已发送消息的计数 // UARTprintf ("总数=%X\n"、g_ui32MsgCount); } // //递增消息数据中的值。 // ui32MsgData++; } // //返回无错误 // 返回(0); }

    接收代码

     

    //
    //
    //// simple_rx.c -演示简单 CAN 消息接收的示例。
    //
    //版权所有(c) 2010-2016 Texas Instruments Incorporated。 保留所有权利。
    //软件许可协议
    //
    以源代码和二进制形式重新分发和使用,无论是否
    进行//修改,只要
    满足以下条件//:
    //
    重新分发源代码必须保留上述版权
    //声明、此条件列表和以下免责声明。
    //
    //二进制形式的再发行必须复制上述版权
    //声明、此条件列表和//
    
    分发随附的//文档和/或其他材料中的以下免责声明。
    ////
    未经
    
    事先书面许可,不能使用德州仪器公司的名称或//其贡献者的名称来认可或推广源自此软件的产品//。
    ////
    本软件由版权所有者和贡献者提供
    //“按原样”,不
    
    承认任何明示或暗示的保证,包括但不限于//适销性和对//特定用途适用性的暗示保证。 在任何情况下、版权
    //所有者或贡献者都不对任何直接、间接、偶然、
    //特殊、模范、 或相应的损害(包括但不
    限于采购替代产品或服务;丧失使用、
    //数据或利润; 或业务中断)、无论
    
    出于何种原因使用
    本软件(即使被告知可能会造成此类损坏)、还是出于任何原因而产生的任何//责任理论(无论是合同、严格责任还是侵权行为)//(包括疏忽或其他)。
    //
    //这是 Tiva 固件开发包版本2.1.3.156的一部分。
    ////
    *****************
    
    #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 - PE4 //! - UART0TX - PE5 //! //! 此示例使用以下中断处理程序。 要使用此示例 //! 在您自己的应用程序中、您必须将这些中断处理程序添加到 您的//! 矢量表。 //! - 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 (CAN0_BASE、CAN_INT_STS_CAUST); // //如果原因是控制器状态中断,则获取状态 // if (ui32Status = CAN_INT_INTID_STATUS) { // //读取控制器状态。 这将返回状态字段 //可以指示各种错误的错误位。 错误处理 //本示例中不是为了简单起见。 请参阅 // API 文档,了解有关错误状态位的详细信息。 //读取此状态的操作将清除中断。 // ui32Status = CANStatusGet (CAN0_BASE、CAN_STS_CONTROL); // //设置一个标志来指示可能发生的某些错误。 // G_bErrFlag = 1; } // //检查原因是否是我们正在使用的消息对象1 //接收消息。 // 否则、如果(ui32Status = 1) { // //到达这一点意味着 RX 中断发生在上 //消息对象1,消息接收完成。 清除 //消息目标中断。 // CANIntClear (CAN0_BASE、1); // //递增计数器以跟踪已有多少消息 //已收到。 在实际应用中、这可用于将标志设置为 //指示何时接收到消息。 // G_ui32MsgCount++; // //设置标志以指示接收到的消息正暂挂。 // G_bRXFlag = 1; // //由于接收到消息,因此清除所有错误标志。 // G_bErrFlag = 0; } // //否则,发生意外导致中断的情况。 这应该是 //永远不会发生。 // 其他 { // //可以在此处执行伪中断处理。 // } //CANIntClear (CAN0_BASE、1); } //********* // //配置 CAN 并输入一个循环来接收 CAN 消息。 //// ***************** int main (void) { #if defined (target_IS_TM4C129_RA0)|| \ 已定义(TARGET_IS_TM4C129_RA1)|| \ 已定义(TARGET_IS_TM4C129_RA2) uint32_t ui32SysClock; #endif tCANMsgObject sCANMessage; uint8_t pui8MsgData[8]; // //将时钟设置为直接从外部晶振/振荡器运行。 // TODO:必须更改 SYSCTL_XTAL_VALUE 以匹配的值 //您的板上使用的晶体。 // #if defined (target_IS_TM4C129_RA0)|| \ 已定义(TARGET_IS_TM4C129_RA1)|| \ 已定义(TARGET_IS_TM4C129_RA2) ui32SysClock = SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz | SYSCTL_OSC_MAIN | SYSCTL_USE_OSC) 25000000); #else SysCtlClockSet (SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHz); #endif // //设置用于显示消息的串行控制台。 这是 //仅针对此示例程序,CAN 操作不需要。 // InitConsole(); // //对于此示例、CAN0与端口 B4和 B5上的 RX 和 TX 引脚一起使用。 //您使用的实际端口和引脚可能有所不同,请参阅 //数据表以了解更多信息。 //需要启用 GPIO 端口 E,以便可以使用这些引脚。 // TODO:将其更改为您正在使用的 GPIO 端口 // SysCtlPeripheralEnable (SYSCTL_Periph_GPIOE); // //配置 GPIO 引脚复用以选择这些引脚的 CAN0功能。 //此步骤选择可用于这些引脚的替代功能。 //如果您的器件支持 GPIO 引脚功能多路复用、这是必需的。 //请查阅数据表以查看每个引脚分配的函数。 // TODO:更改此选项以选择您正在使用的端口/引脚 // GPIOPinConfigure (GPIO_PE4_CAN0RX); GPIOPinConfigure (GPIO_PE5_CAN0TX); // //启用 GPIO 引脚上的复用功能。 以上步骤选择 //可用的备用功能。 此步骤实际上启用 //这些引脚的替代功能、而不是 GPIO。 //待办事项:更改此项以匹配您正在使用的端口/引脚 // GPIOPinTypeCAN (GPIO_Porte _BASE、GPIO_PIN_4 | GPIO_PIN_5); // //已为 CAN 设置 GPIO 端口和引脚。 CAN 外设 //必须启用。 // SysCtlPeripheralEnable (SYSCTL_Periph_CAN0); // //初始化 CAN 控制器 // CANInit (CAN0_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 (CAN0_BASE、ui32SysClock、50000); #else CANBitRateSet (CAN0_BASE、SysCtlClockGet ()、50000); #endif // //在 CAN 外设上启用中断。 此示例使用静态 //分配中断处理程序,表示处理程序的名称 //位于启动代码的矢量表中。 如果您想使用动态的 //分配矢量表,然后还必须调用 CANIntRegister() //此处。 // CANIntRegister (CAN0_BASE、CANIntHandler);// if using dynamic vectors // CANIntEnable (CAN0_BASE、CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS); // //在处理器(NVIC)上启用 CAN 中断。 // IntEnable (INT_CAN0); // //启用 CAN 以进行操作。 // CANEnable (CAN0_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 (CAN0_BASE、1、&sCANMessage、MSG_OBJ_TYPE_RX); // //输入循环以处理收到的消息。 该循环仅检查一个标志 //由中断处理程序设置,如果该位置位,则读取 //消息并显示内容。 这不是一种稳健的方法 //处理传入的 CAN 数据,并且一次只能处理一条消息。 //如果多条消息一起接收,则会收到一些消息 //可能被丢弃。 在实际应用中、应使用其他一些方法 //对收到的消息进行排队,以确保它们不会丢失。 您 //也可以使用 CAN FIFO 模式,允许消息为 //在处理前进行缓冲。 // for (;;) { unsigned int uIdx; // //如果该标志被置位、则表示发生了 RX 中断、然后 //有一条消息可以从 CAN 读取 // if (g_bRXFlag) { // //重复使用之前用于配置的同一消息对象 //用于接收消息的 CAN。 用于存储的缓冲器 //还必须提供接收到的数据,所以设置缓冲区指针 //在消息对象中。 // sCANMessage.pui8MsgData = pui8MsgData; // //从 CAN 读取消息。 使用1号报文对象 //(与 CAN ID 不相同)。 中断清除 //标志未设置、因为中已清除此中断 //中断处理程序。 // CANMessageGet (CAN0_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 ("总数=%u\n"、g_ui32MsgCount); } } // //返回无错误 // 返回(0); }

     

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

    您是否正在使用 最新版本的 TivaWare? 我注意到示例代码来自之前的版本。 当前版本为2.1.4.178。

    //这是 Tiva 固件开发包的版本2.1.3.156的一部分。
    

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

    我是否可以注意到(任何/所有偏差)与"几乎骨库存"的距离-证明(极其) 难以检测!   尤其是当代码转储量很大时、"moDS"就很少!
    您 的-此类"建议"的颜色编码以及有组织的"模板列表"将极大地帮助您的助手"查找"您的模板!"   

    这样的"添加明确性"、"表达、简化和增强" (您)代码的审核-所有这些都有利于您-您是否同意?

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

    大约3个月前、我直接从 TI 网站下载了 CCS 和 TIvaware 软件包 Bob、我将在今晚回家后验证我是否已获得最新版本。

    我只是尝试为 CB1的代码添加颜色、但是在代码标签中、它无法按我所能说的那样正确突出显示。 只需在该行前面添加更多代码。 抱歉、我不熟悉论坛。

    simple_tx 的第225行是我在这里添加的唯一代码行。 它被注释为在我的第一个帖子中生成输出(连续中断生成)。 取消注释后、每条消息产生一个中断。 否则、我只需按照文件中的"TODO "消息的指定、将 CAN Tx/Rx 更新为 PE4和 PE5。

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

    谢谢您-很少回应/快速和平稳-正如您刚才所说的。

    由于原因不明-当我公司的 PC 检查标签时、这些"代码标签"会导致不必要的"行偏移"。   (最近供应商的'Bob'和我-回复了一张海报-并且'line offset'得到了很好的记录-最令人不安!

    六年多过去-我的公司采用了'Simple_TX & simple_RX' (一个早期版本)、我们'印象深刻!'   我们是强大(非常强大)的 Kiss 倡导者、从坚实的基础和/或基金会开始、我们已经证明、"SAFEST -最成功的-最快的"-可以构建成功(甚至是后来扩展的)解决方案!

    如果您的困难仍然存在、并且您愿意使用(很久以前)代码版本(即"多人"版本)、我可以提供该版本。   (客户要求我们长期保持我们的来源!)

    遗憾的是、"代码标签"破坏 了"颜色编码!"的诸多优势   我们公司每天都采用这种颜色编码-它证明是理想的:  

    • 跟踪代码源
    • 和版本
    • 和"候选(通常相互竞争)方法" ...   用于对比、"测试和评估"。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢 CB1、我一定会感谢您尝试更多代码。

    我花了惊人的大量时间到达这一点,所以任何时候你都可以花帮助你,这是非常感激的!

    我目前最大的顾虑是 Rx 部分、因此如果您有一些旧的已知工作。 我怀疑它的工作方式可能与此完全相同、因为核心概念非常简单-

    • 初始化 CAN 模块、端口、中断。
    • 初始化 CAN 报文对象。
      • 确保滤波器/遮罩处于宽开状态
    • 将报文对象加载到 CAN 外设中进行配置。
    • 接收到报文时 CAN 外设中断。
    • 从 CAN 外设检索消息。

    看起来非常简单。 然而、不知怎么说、我可以从 CAN 外设中检索到的唯一消息是我加载到中以进行初始化的消息。

    我已经测试了它对特定消息 ID 的过滤、它仅在过滤的 ID 上中断。 因此、CAN 外设和 ISR 都在读取我非常确定的正确内容。 我无法正确检索它。 了解您的旧代码是否使用相同的过程将会很有趣。

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

    正如承诺的那样-这是在 StellarisWare 下发布的一个(很多)早期版本的'simple_RX.c'。   (版本9107 - 之前发布的版本(部分)在这里发布-已经诞生!    (几乎))

    e2e.ti.com/.../4162.simple_5F00_rx.c

    定义可能会有一些"冲突"-该供应商发布了一份指南、内容为"从 StellarisWare 过渡到软件"。    我早就要求(该供应商的)提供此类文档、使其更加"可选!"    这种"合理"的请求-既未得到确认、也未得到满足-而是供应商选择将"博客、小组和培训"停驻(大多数是不需要的)-但绝不会在本页面的"主要(海滨)"房地产上提供必要的"指导/放大"技术文档。   (那个-标识红色条纹( voici)的"显著区域"(顶部)-一些古咒"指南"-供应商"高贵"曾经告诉我。)    将"样式"提升到用户"方便/方便" 之上...  证明客户机用户不是很关心。

    我将包括(同样旧的 simple_tx.c -这样您就有两个文件 -我们(过去)使用了这两个文件-并且取得了相当大的成功。

    我不记得我们的"测试与验证"是否超出了您的要求(已经超过6年了)-但这些文件似乎是一种"合理的替代方案"-如果我们幸运的话-可能会提供所需的见解。  (有一个希望!)   祝您有机会 、我是 AMI……

    e2e.ti.com/.../3513.simple_5F00_tx.c

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

    产生超过 "PIN_MAP.h"的(已配接) 将有助于您查看(可能) TM4C 和(已淘汰) "LM3S 和 LX4F"之间的"细微冲突"。   这里的员工 已将 TM4C123添加到原始的 StellarisWare 9107中、以便可以通过这种过去的(无故障) API 来为 TM4C 提供服务。   (说明了较新的'date-code'-随附'pin_map.h')

    同样、也可以将"PIN_MAP.h"的过去(特定) "LM3S 和/或 LX4F" 组件"导入  "更容易获得的(即电流) "PIN_MAP.h"

    我们的团队是否以(完全)重复您的方法的方式实施了(成功的) CAN 总线、这一点尚不清楚。   然而、如果不了解供应商的"内部见解"、此文件"比较/对比"可能会证明是一个安全的(尽管是临时的)港湾-通过您当前的风暴...  (我们希望!)

    e2e.ti.com/.../7851.pin_5F00_map.h

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    感谢 CB1、从对代码的快速回顾来看、API 看起来根本没有发生过大变化。 不过、我今晚将有更多时间深入探讨这一问题。

    我已经借用了 CAN 总线分析器、并确认我的 TX 按预期工作、ID 和数据字节至少正在正确传输。

    Bob、我最近在这里获得了一台新的笔记本电脑、因此我正在进行 CCS 的全新安装(v8现在!) 和最新最出色的 TIvaware。 那么、我将看到它是否会产生任何不同的结果。

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

    嗯、我将被阻尼。 我在新计算机上全新安装了带有2.1.4.178的 CCS、它运行得很好。

    我对这种情况的发生方式非常困惑、不知怎么说、消息 Rx 的 CAN 驱动程序/例程中的一个在我的特定版本中已损坏? 哦、嗯、这并不重要。 现在我已经开始工作了、我对 API 和总线拓扑的了解要深得多、因为我花了几周时间来拔除头发、哈哈。

    感谢你们的帮助!