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.

[参考译文] EK-TM4C1294XL:Tiva CAN 总线不适用于 EK-TM4C1294XL Rev.D 板

Guru**** 2383290 points
Other Parts Discussed in Thread: SN65HVD233-HT, SN74LVC4245A, SN74LV244A
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/691528/ek-tm4c1294xl-tiva-can-bus-not-working-for-ek-tm4c1294xl-rev-d-board

器件型号:EK-TM4C1294XL
主题中讨论的其他器件:SN65HVD233-HTSN74LVC4245ASN74LV244ATM4C123

我正在使用 CAN 总线。

我正在使用示例文件夹(外设 CAN)中提供的 simple_tx 和 simple_Rx 代码。

我已经修改了该代码、因为我不想使用 UART 并使代码变得简单。

我遵循了以下主题:  

但这对我不起作用。

不同的硬件连接和相应的输出波形、我已附加在以下文档中。 请看那个。

e2e.ti.com/.../Problem-TI-Post.pdf

和硬件连接:

所有跳线均处于默认位置。


/////////////////////////////////////////////////////////////////// simple_tx 代码
#include 
#include 
#include "inc/hw_ca.h"
#include "void/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 "volatile unsignature.idi20_intrl"#idu.idu.ide"#idu.ide"#include "u.idio nateg";"sys/intrack u.idu.idu.idu.idu.idu.idu.ide"#idu.idu.ide"#include "u.32
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOD);//启用 UART0 GPIO 外设
GPIOPinConfigure (GPIO_PD4_U2RX);
GPIOPinConfigure (GPIO_PD5_U2TX);
SysCtlPeripheralEnable (SYSCTL_Periph_UART2);
UARTClockSourceSet (UART2_base、UART_CLOCK_PIOSC);
GPIOPinTypeUART (GPIO_PORTD_base、GPIO_PIN_4 | GPIO_PIN_5);
//UARTStdioConfig (0、115200、sysClock);
}

void SimpleDelay (void)
{
SysCtlDelay (40000000);
}

void CANIntHandler (void)
{
uint32_t ui32Status;

ui32Status = CANIntStatus (CAN1_base、CAN_INT_STS_CAUST);

if (ui32Status = CAN_INT_INTID_STATUS)
{

ui32Status = CANStatusGet (CAN1_base、CAN_STS_CONTROL);

G_bErrFlag = 1;
}

否则、如果(ui32Status = 1)
{

CANIntClear (CAN1_base、1);

G_ui32MsgCount++;

G_bErrFlag = 0;
}

其他
{

}
}

int main (void)
{
tCANMsgObject sCANMessage;
uint32_t ui32MsgData=0;
uint8_t * pui8MsgData;

pui8MsgData =(uint8_t *) ui32MsgData;

SysClock = SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz | SYSCTL_OSC_main | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480)、120000000);SimpleDelay ();

//InitConsole();
SysCtlPeripheralEnable (SYSCTL_Periph_GPION);
GPIOPinTypeGPIOOutput (GPIO_PORTN_BASE、GPIO_PIN_0|GPIO_PIN_1);
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOB);SimpleDelay ();
GPIOPinConfigure (GPIO_PB0_CAN1RX);
GPIOPinConfigure (GPIO_PB1_CAN1TX);
GPIOPinTypeCAN (GPIO_PORTB_BASE、GPIO_PIN_0 | GPIO_PIN_1);
SysCtlPeripheralEnable (SYSCTL_Periph_CAN1);
CANInit (CAN1_base);SimpleDelay ();
CANBitRateSet (CAN1_base、SysCtlClockGet ()、50000);SimpleDelay ();
CANIntRegister (CAN1_base、CANIntHandler);SimpleDelay ();
CANIntEnable (CAN1_base、CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);SimpleDelay ();
IntEnable (INT_CAN1);SimpleDelay ();
CANEnable (CAN1_base);SimpleDelay ();

ui32MsgData = 0xAA;
sCANMessage.ui32MsgID = 1;
sCANMessage.ui32MsgIDMask = 0;
sCANMessage.ui32Flags = MSG_OBJ_TX_INT_ENABLE;
sCANMessage.ui32MsgLen = sizeof (pui8MsgData);
sCANMessage.pui8MsgData = pui8MsgData;

while (1)
{
//UARTprintf ("发送 msg:0x%02x %02x %02x %02x"、pui8MsgData[0]、pui8MsgData[1]、pui8MsgData[2]、pui8MsgData[3]);
GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_0|GPIO_PIN_1、0x02);
CANMessageSet (CAN1_base、1、&sCANMessage、MSG_OBJ_TYPE_TX);SimpleDelay ();
GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_0|GPIO_PIN_1、0x08);SimpleDelay ();
if (g_bErrFlag)
{
//UARTprintf ("错误-电缆已连接?\n");
}
其他
{
//UARTprintf ("总数=%u\n"、g_ui32MsgCount);
}
/*ui32MsgData++;
if (ui32MsgData>=0x65)
{
ui32MsgData = 0x55;
}*/
while (1)
{
}
}
return (0);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// simple_tx 代码结束 


////////////////////////////////////////////////////////////////////////////////////////////////////////// simple_RX 代码

#include 
#include 
#include "inc/hw_ca.h"
#include "idvolatile/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/ca.h"
#include "driverlib/gpio.h"#definvolatile "driverlib/gpio.h"

#include "driverbt translation_rmdio.h"




;#include "driverbidio.idrg.ide"#def";"sysbidrg.idrg.unsign"
= unsign.idr32_unsign.idrg.idrg.idrg.idrg.idrg.idrg.idrg.idrfb





= volt.unt = volt.idrfu.idrfu.idrg.idrg.idrg.idrg.

SysCtlDelay (20000000);
}
/*********
void InitConsole (void)
{
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOD);//启用 UART0 GPIO 外设
GPIOPinConfigure (GPIO_PD4_U2RX);
GPIOPinConfigure (GPIO_PD5_U2TX);
SysCtlPeripheralEnable (SYSCTL_Periph_UART2);
UARTClockSourceSet (UART2_base、UART_CLOCK_PIOSC);
GPIOPinTypeUART (GPIO_PORTD_base、GPIO_PIN_4 | GPIO_PIN_5);
//UARTStdioConfig (0、115200、sysClock);
}

void
CANIntHandler (void)
{
uint32_t ui32Status;
ui32Status = CANIntStatus (CAN1_base、CAN_INT_STS_CAUST);
if (ui32Status = CAN_INT_INTID_STATUS)
{
ui32Status = CANStatusGet (CAN1_base、CAN_STS_CONTROL);
G_bErrFlag = 1;
}

否则、如果(ui32Status = 1)
{
CANIntClear (CAN1_base、1);
G_ui32MsgCount++;
G_bRXFlag = 1;
G_bErrFlag = 0;
}

其他
{
}
}

int main (void)
{


tCANMsgObject sCANMessage;
uint8_t pui8MsgData[8];

SysClock = SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz | SYSCTL_OSC_main | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480)、120000000);
//InitConsole();
SysCtlPeripheralEnable (SYSCTL_Periph_GPION);
GPIOPinTypeGPIOOutput (GPIO_PORTN_BASE、GPIO_PIN_0|GPIO_PIN_1);

SysCtlPeripheralEnable (SYSCTL_Periph_GPIOB);
GPIOPinConfigure (GPIO_PB0_CAN1RX);
GPIOPinConfigure (GPIO_PB1_CAN1TX);
GPIOPinTypeCAN (GPIO_PORTB_BASE、GPIO_PIN_0 | GPIO_PIN_1);
SysCtlPeripheralEnable (SYSCTL_Periph_CAN1);SimpleDelay ();
CANInit (CAN1_base);SimpleDelay ();
CANBitRateSet (CAN1_base、SysCtlClockGet ()、50000);SimpleDelay ();
CANIntRegister (CAN1_base、CANIntHandler);SimpleDelay ();
CANIntEnable (CAN1_base、CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);SimpleDelay ();
IntEnable (INT_CAN1);SimpleDelay ();
CANEnable (CAN1_base);SimpleDelay ();
sCANMessage.ui32MsgIDMask = 0;
sCANMessage.ui32Flags = MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER;
sCANMessage.ui32MsgLen = 8;
CANMessageSet (CAN1_base、1、&sCANMessage、MSG_OBJ_TYPE_RX);

for (;;)
{
unsigned int uIdx;
if (g_bRXFlag)
{
GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_0|GPIO_PIN_1、0x08);
SimpleDelay();
GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_0|GPIO_PIN_1、0x02);
sCANMessage.pui8MsgData = pui8MsgData;
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]);
if (pui8MsgData[uIdx]=0xAA)
{
GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_0|GPIO_PIN_1、0x02);SimpleDelay ();
GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_0|GPIO_PIN_1、0x08);SimpleDelay ();
GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_0|GPIO_PIN_1、0x02);SimpleDelay ();
GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_0|GPIO_PIN_1、0x08);SimpleDelay ();
GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_0|GPIO_PIN_1、0x02);SimpleDelay ();
GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_0|GPIO_PIN_1、0x08);SimpleDelay ();
GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_0|GPIO_PIN_1、0x02);SimpleDelay ();
GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_0|GPIO_PIN_1、0x08);SimpleDelay ();
}
}
//UARTprintf ("total count=%u\n"、g_ui32MsgCount);
}
}

return (0);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// simple_RX 代码结束 


我认为我在硬件或代码方面犯了一些错误。 我无法对其进行调试。

Amit 建议 使用的 SN65HVD233-HT 3.3V CAN 收发器。   

MCP2551 CAN 收发器的问题是否是由于电压电平(TTL)造成的????

我已经尝试过 LVTTL 到 TTL 转换器和  TTL 到 LVTTL 转换器 ,SN74LV244A 和 SN74LVC4245A。 仍然会出现相同的误差。

此致、

Krishnat

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

    将 TM4C129控制器连接到 CAN 总线的首选方法是使用3.3V CAN 收发器。 以下是有关 CAN 总线的更多文档:

    http://www.ti.com/lit/an/sloa101b/sloa101b.pdf

    像在电路图4中那样、使用二极管在伪 CAN 总线上连接两个器件的方法应该有效。 如果您返回到该配置并在使用简单 TX 代码示例编程的器件的引脚 PB1 (CAN1TX)和 PB0 (CAN1RX)处捕获完整 CAN 帧的示波器图像、 当接收器件发出确认信号时、我们应该会看到两个信号之间存在差异。

    我看到您修改的软件中有一个大问题。 在 TX 和 RX 例程中、你在对 CANBitRateSet()的调用中使用了函数 SysCtlClockGet ()。 该功能仅适用于 TM4C123器件、不适用于 TM4C129器件。 相反、调用应该使用在对 SysCtlClockFreqSet()的调用中被初始化的变量 ui32SysClock。

    CANBitRateSet (CAN1_base、ui32SysClock、50000);
    

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

    您好、bob、

    我更正了代码、变量 ui32SysClock 已解决问题。

    我获得的输出与我提到的主题中的 Charles Tsai 相同:

    我还有一个问题。

    我将反复获取 CAN 帧。

    您可以看到我在 TX 代码中配置了一次 MSG。

    因此、一旦接收到 ACK、CAN 线路就会空闲。

    但它会再次传输相同的 MSG。 当我将代码修改为时、它变为空闲

    while (1)
    {
    //UARTprintf ("发送 msg:0x%02x %02x %02x %02x"、pui8MsgData[0]、pui8MsgData[1]、pui8MsgData[2]、pui8MsgData[3]);
    GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_0|GPIO_PIN_1、0x02);
    CANMessageSet (CAN1_base、1、&sCANMessage、MSG_OBJ_TYPE_TX);SimpleDelay ();
    GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_0|GPIO_PIN_1、0x08);SimpleDelay ();
    if (g_bErrFlag)
    {
    //UARTprintf ("错误-电缆已连接?\n");
    }
    其他
    {
    //UARTprintf ("总数=%u\n"、g_ui32MsgCount);
    }
    /*ui32MsgData++;
    if (ui32MsgData>=0x65)
    {
    ui32MsgData = 0x55;
    }*/
    CANMessageClear (CAN1_base、1);//////////////////////////////////////////////////// *********
    while (1)
    {
    }
    } 

     在 CANMessageSet()和 CANMessageClear()两个函数之间,我得到多个传输。

    因此、我再次将代码修改为:

    #include 
    #include 
    #include "inc/hw_ca.h"
    #include "inc/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 "volatile tidu.32_intrl";
    
    
    include "volatile unt uidi20_intrl"= uidu.idu.idu.idu.idu.idu.idu.idu.32t = u.idu.idu.idu.idu.idu.idu.idu.idu.32";"u.idu.idu.idu.idu.idu.idu.idu.idu.idu.idu.idu.idu.0
    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOD);//启用 UART0 GPIO 外设
    GPIOPinConfigure (GPIO_PD4_U2RX);
    GPIOPinConfigure (GPIO_PD5_U2TX);
    SysCtlPeripheralEnable (SYSCTL_Periph_UART2);
    UARTClockSourceSet (UART2_base、UART_CLOCK_PIOSC);
    GPIOPinTypeUART (GPIO_PORTD_base、GPIO_PIN_4 | GPIO_PIN_5);
    //UARTStdioConfig (0、115200、sysClock);
    }
    
    void SimpleDelay (void)
    {
    SysCtlDelay (40000000);
    }
    
    void CANIntHandler (void)
    {
    uint32_t ui32Status;
    
    ui32Status = CANIntStatus (CAN1_base、CAN_INT_STS_CAUST);
    
    if (ui32Status = CAN_INT_INTID_STATUS)
    {
    
    ui32Status = CANStatusGet (CAN1_base、CAN_STS_CONTROL);
    
    G_bErrFlag = 1;
    }
    
    否则、如果(ui32Status = 1)
    {
    
    CANIntClear (CAN1_base、1);
    G_ui32MsgCount++;
    G_bErrFlag = 0;
    G_bTXFlag = 1;
    }
    
    其他
    {
    
    }
    }
    
    int main (void)
    {
    tCANMsgObject sCANMessage;
    uint32_t ui32MsgData=0;
    uint8_t * pui8MsgData;
    
    pui8MsgData =(uint8_t *) ui32MsgData;
    
    ui32SysClock = SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz | SYSCTL_OSC_main | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480)、120000000);SimpleDelay ();
    //InitConsole();
    SysCtlPeripheralEnable (SYSCTL_Periph_GPION);
    GPIOPinTypeGPIOOutput (GPIO_PORTN_BASE、GPIO_PIN_0|GPIO_PIN_1);
    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOB);SimpleDelay ();
    GPIOPinConfigure (GPIO_PB0_CAN1RX);
    GPIOPinConfigure (GPIO_PB1_CAN1TX);
    GPIOPinTypeCAN (GPIO_PORTB_BASE、GPIO_PIN_0 | GPIO_PIN_1);
    SysCtlPeripheralEnable (SYSCTL_Periph_CAN1);
    CANInit (CAN1_base);SimpleDelay ();
    CANBitRateSet (CAN1_base、ui32SysClock、50000);SimpleDelay ();
    CANIntRegister (CAN1_base、CANIntHandler);SimpleDelay ();
    CANIntEnable (CAN1_base、CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);SimpleDelay ();
    IntEnable (INT_CAN1);SimpleDelay ();
    CANEnable (CAN1_base);SimpleDelay ();
    
    ui32MsgData = 0xAA;
    sCANMessage.ui32MsgID = 1;
    sCANMessage.ui32MsgIDMask = 0;
    sCANMessage.ui32Flags = MSG_OBJ_TX_INT_ENABLE;
    sCANMessage.ui32MsgLen = sizeof (pui8MsgData);
    sCANMessage.pui8MsgData = pui8MsgData;
    
    while (1)
    {
    //UARTprintf ("发送 msg:0x%02x %02x %02x %02x"、pui8MsgData[0]、pui8MsgData[1]、pui8MsgData[2]、pui8MsgData[3]);
    GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_0|GPIO_PIN_1、0x02);
    CANMessageSet (CAN1_base、1、&sCANMessage、MSG_OBJ_TYPE_TX);SimpleDelay ();
    GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_0|GPIO_PIN_1、0x08);SimpleDelay ();
    if (g_bErrFlag)
    {
    //UARTprintf ("错误-电缆已连接?\n");
    }
    否则、IF (g_bTXFlag)
    {
    CANMessageClear (CAN1_base、1);
    G_bTXFlag=0;
    //UARTprintf ("总数=%u\n"、g_ui32MsgCount);
    }
    /*ui32MsgData++;
    if (ui32MsgData>=0x65)
    {
    ui32MsgData = 0x55;
    }*/
    
    SimpleDelay();
    SimpleDelay();
    }
    返回(0);
    }
    

    仍然存在多个传输、但 多个传输的数量减少。

    代码中是否有任何错误?

    此致、

    Krishnat

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您对 CANMessageSet()的调用位于 while (1)循环内。 这将导致连续发送消息。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    while (1)

    //UARTprintf ("发送 msg:0x%02x %02x %02x %02x"、pui8MsgData[0]、pui8MsgData[1]、pui8MsgData[2]、pui8MsgData[3]);
    GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_0|GPIO_PIN_1、0x02);
    CANMessageSet (CAN1_base、1、&sCANMessage、MSG_OBJ_TYPE_TX);SimpleDelay ();
    GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_0|GPIO_PIN_1、0x08);SimpleDelay ();
    if (g_bErrFlag)

    //UARTprintf ("错误-电缆已连接?\n"\});

    其他

    //UARTprintf ("总数=%u\n"、g_ui32MsgCount);

    /*ui32MsgData++;
    if (ui32MsgData>=0x65)

    ui32MsgData = 0x55;
    }*/
    CANMessageClear (CAN1_base、1);//////////////////////////////////////////////////// *********
    while (1)




    有两个 while 循环、因为内部 loop msg 应发送一次。
    但 CANMessageSet 和 CANMessageClear 之间的时间存在多个传输。
    我使用 g_bTXFlag 来检查传输是否完成的第二个代码存在错误。 我将修改并发布结果。 很抱歉。

    此致、
    Krishnat
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    代码工作正常。
    谢谢您、请观看。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    嗨、Bob、

    我在 CAN 模块中遇到了新问题。
    请参阅我的新帖子 :e2e.ti.com/.../696119

    此致、
    Krishnat