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:CAN1Tx 问题

Guru**** 2601605 points
Other Parts Discussed in Thread: EK-TM4C1294XL, SN65HVD251, SN65HVD233

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/742078/ek-tm4c1294xl-can1tx-problem

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

我在使用 tm4c1294的 CAN 控制器模块时遇到问题。 我尝试修改了可用于 TIvAware 上的 tm4c123的 CAN 示例、但似乎无法使其正常工作。 我正在使用2 个 EK-TM4C1294XL、每个 EK-TM4C1294XL 连接到各自 CAN1模块(CAN1Rx PB0和 CAN1Tx PB1)上的 MCP2561 CAN 收发器。 我的问题是、当我使用示波器观察 CAN1tx 传输数据时、显然没有数据被传输。 CAN1Tx 管脚始终保持在3V3。 我收到消息错误 CAN_BUS_OFF 和 CAN_STATUS_EWARN。 下面是我的代码:

//
//
// ca.c -简单的 CAN 示例。
//
//版权所有(c) 2013-2017 Texas Instruments Incorporated。 保留所有权利。
//软件许可协议
//
//德州仪器(TI)仅提供和使用此软件
//专门用于 TI 的微控制器产品。 该软件归其所有
// TI 和/或其供应商、受适用版权保护
//法律。 您不能将此软件与"病毒"开源软件结合使用
//软件,以便形成一个更大的程序。
//
//此软件按“原样”提供,且存在所有故障。
//不作任何明示、暗示或法定的保证,包括但
//不限于对适销性和适用性的暗示保证
//此软件的特定用途。 TI 不得以任何方式进行
//情况,对特殊、偶然或从属事件负责
//任何原因造成的损害。
//
//这是 DK-TM4C123G 固件包的版本2.1.4.178的一部分。
//
//

#include
#include
#include
#include
#include "inc/hw_ca.h"
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "driverlib/fpu.h"
#include "driverlib/CAN.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "grlib/grlib.h"
#include "drivers/cfal96x64x16.h"
#include "utils/uartstdio.h"
#include "driverlib/interrupt.h"

//
//
//! \addtogroup example_list
//!

CAN 示例(CAN)


//!
//! 此示例应用程序利用 CAN 来回发送字符
//! 之间的差异。 它使用 UART 读取/写入字符
//! UART 终端。 它还使用板上的图形显示进行显示
//! 最后一个字符被转接/接收。 还包括错误处理。
//!
//! CAN 硬件设置:
//!
//! 要使用此示例、您需要连接两个 DK-TM4C123G 板
//! 一起工作。 这涉及连接 CANH 螺钉端子
//! 和 CANL 端子一起。 此外、还具有120 Ω 终端
//! 需要在 CANH 之间的网络边缘添加电阻器
//! 和 CANL。 在两个电路板设置中、这意味着连接一个120欧姆的电阻器
//! CANH 和 CANL 之间的差值。
//!
//! 请参阅下图了解可视性。 '--'代表导线。
//!
//! \逐字记录
//! CANH---+--- +--CANH
//! ||
//! .. ..
//! || 120欧姆|| 120欧姆
//! |||||
//! '-'-'
//! ||
//! CANL---------------- +--CANL
//! \n 逐字记录
//!
//! 软件设置:
//!
//! 设置硬件连接后、将两个板连接到计算机
//! 通过图形显示屏旁边的在线调试接口 USB 端口。
//! 将一个 UART 终端连接到每块配置为115、200波特、8-n-1模式的电路板。
//!
//! 您在一个终端中键入的任何内容都将显示在另一个终端和中
//! 反之亦然。 发送/接收的最后一个字符也将显示在上
//! 板上的图形显示。
//
//

//
//
//跟踪 TX 和 RX 中断次数的计数器
//发生,它应与传输的消息数相匹配/
//已收到。
//
//
volatile uint32_t g_ui32RXMsgCount = 0;
volatile uint32_t g_ui32TXMsgCount = 0;

//
//
//中断处理程序指示已接收消息的标志。
//
//
volatile bool g_BRXFlag = 0;

//
//
//一个全局变量,用于跟踪已抛出的错误标志,以便它们可以被抛出
//进行处理。 这是必要的、因为读取错误寄存器会被清除
//标记,因此有必要将它们保存在某个位置进行处理。
//
//
volatile uint32_t g_ui32ErrFlag = 0;

//
//
//针对正在发送/接收的数据的 CAN 消息对象
//
//
tCANMsgObject g_sCAN1RxMessage;
tCANMsgObject g_sCAN1TxMessage;

//
//
//消息标识符和对象
// RXID 设为0,以便接收所有消息
//
//
#define CAN1RXID 0
#define RXOBJECT 1
#define CAN1TXID 2.
#define TXOBJECT 2.

//
//
//保存发送字符的变量/检索
//
//
uint8_t g_ui8TXMsgData;
uint8_t g_ui8RXMsgData;

//
//
//图形显示上打印的文本的全局上下文
//
//
tContext g_sContext;


//
//
//驱动程序库遇到错误时调用的错误例程。
//
//
#ifdef 调试
无效
_error__(char * pcFilename、uint32_t ui32Line)


#endif

//
//
// CAN 0中断处理程序。 它会检查中断的原因、和
//保留已发送/接收的所有消息的计数
//
//
无效
CAN1IntHandler (空)

uint32_t ui32Status;

//
//读取 CAN 中断状态以查找中断原因
//
// CAN_INT_STS_Cause 寄存器值
// 0x0000 =无中断挂起
// 0x0001-0x0020 =导致中断的报文对象数
// 0x8000 =状态中断
//所有其它数字都是保留的,在本系统中没有意义
//
ui32Status = CANIntStatus (CAN1_base、CAN_INT_STS_CAUST);

//
//如果这是一个状态中断、则通过读取 CAN 来确认它
//控制器状态寄存器。
//
if (ui32Status = CAN_INT_INTID_STATUS)

//
//读取控制器状态。 这将返回状态字段
//可以指示各种错误的错误位。 请参阅
// API 文档,了解有关错误状态位的详细信息。
//读取此状态的操作将清除中断。
//
ui32Status = CANStatusGet (CAN1_base、CAN_STS_CONTROL);

//
//将错误标志添加到当前错误列表中。 要处理的数据
//因为在中需要太多的时间
//中断。
//
G_ui32ErrFlag |= ui32Status;

//
//检查原因是否是我们正在使用的消息对象 RXOBJECT
//用于接收消息。
//
否则、IF (ui32Status = RXOBJECT)

//
//到达这一点意味着 RX 中断发生在上
//消息对象 RXOBJECT、消息接收完成。
//清除报文对象中断。
//
CANIntClear (CAN1_BASE、RXOBJECT);

//
//递增计数器以跟踪已有多少消息
//已收到。 在实际应用中、这可用于将标志设置为
//指示何时接收到消息。
//
G_ui32RXMsgCount++;

//
//设置标志以指示接收到的消息正暂挂。
//
G_bRXFlag = true;

//
//由于接收到消息,因此清除所有错误标志。
//这是因为在收到消息之前它会触发
// RX 完成的状态中断。 通过清除这里的标志、我们可以看到
//防止发生不必要的错误处理
//
G_ui32勘误标志= 0;

//
//检查原因是否是我们正在使用的消息对象 TXOBJECT
//用于传输消息。
//
否则、如果(ui32Status = TXOBJECT)

//
//到达这一点意味着 TX 中断发生在上
//消息对象 TXOBJECT、消息接收完成。
//清除报文对象中断。
//
CANIntClear (CAN1_BASE、TXOBJECT);

//
//递增计数器以跟踪已有多少消息
//已发送。 在实际应用中、可以使用此设置
//指示消息何时传输的标志。
//
G_ui32TXMsgCount++;

//
//由于已发送消息,因此清除所有错误标志。
//这是因为在发送消息之前它会触发
// TX 完成的状态中断。 通过清除这里的标志、我们可以看到
//防止发生不必要的错误处理
//
G_ui32勘误标志= 0;

//
//否则,发生意外导致中断的情况。 这应该是
//永远不会发生。
//
其他

//
//可以在此处执行伪中断处理。
//

//
//
//配置 UART 及其引脚。 这必须在 UARTprintf()之前调用。
//
//
无效
配置 UART (空)

// Uart0
GPIOPinConfigure (GPIO_PA0_U0RX);
GPIOPinConfigure (GPIO_PA1_U0TX);
GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1);
UARTConfigSetExpClk (UART0_BASE、120000000、115200、
(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
UART_CONFIG_PAR_NONE));
UARTFIFODisable (UART0_BASE);
UARTEnable (UART0_BASE);

//
//
//将 CAN1设置为以500kHz 的频率发送和接收。
//中断打开
//使用 PE4/PE5
//
//
无效
InitCAN1 (空)

//
//对于此示例、CAN1与端口 E4和 E5上的 RX 和 TX 引脚一起使用。
//需要启用 GPIO 端口 E,以便可以使用这些引脚。
//
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOB);
while (!SysCtlPeripheralReady (SYSCTL_Periph_GPIOB));
//
//配置 GPIO 引脚复用以选择这些引脚的 CAN1功能。
//此步骤选择可用于这些引脚的替代功能。
//
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);
while (!SysCtlPeripheralReady (SYSCTL_Periph_CAN1));
//
//初始化 CAN 控制器
//
CANInit (CAN1_base);

//
//设置 CAN 总线的比特率。 此函数设置 CAN
针对标称配置的//总线时序。 您可以实现更多控制
//使用函数 CANBitTimingSet()代替 CAN 总线时序
//如果需要。
//在此示例中、CAN 总线设置为500kHz。
//
CANBitRateSet (CAN1_base、120000000、50000);

//
//在 CAN 外设上启用中断。 此示例使用静态
//分配中断处理程序,表示处理程序的名称
//位于启动代码的矢量表中。
//
CANIntRegister (CAN1_base、CAN1IntHandler);
CANIntEnable (CAN1_base、CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);

//
//在处理器(NVIC)上启用 CAN 中断。
//
IntEnable (INT_CAN1);

//
//启用 CAN 以进行操作。
//
CANEnable (CAN1_base);

//
//初始化用于接收 CAN 消息的消息对象
//任何 CAN ID。 为了接收任何 CAN ID、ID 和掩码必须同时存在
//设置为0,并启用 ID 过滤器。
//
G_sCAN1RxMessage.ui32MsgID = CAN1RXID;
G_sCAN1RxMessage.ui32MsgIDMask = 0;
G_sCAN1RxMessage.ui32Flags = MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER;
G_sCAN1RxMessage.ui32MsgLen = sizeof (g_ui8RXMsgData);

//
//现在将消息对象加载到 CAN 外设中。 加载后
// CAN 将在总线上接收任何消息,并将发生中断。
//使用消息对象 RXOBJECT 接收消息(这不是
//与 CAN ID 相同,在本例中可以是任何值)。
//
CANMessageSet (CAN1_base、RXOBJECT、&g_sCAN1RxMessage、MSG_OBJ_TYPE_RX);

//
//初始化将用于发送 CAN 的消息对象
//消息。 消息将是包含字符的1个字节
//从另一个控制器接收。 最初它将设置为0。
//
G_ui8TXMsgData = 0;
G_sCAN1TxMessage.ui32MsgID = CAN1TXID;
G_sCAN1TxMessage.ui32MsgIDMask = 0;
G_sCAN1TxMessage.ui32Flags = MSG_OBJ_TX_INT_ENABLE;
G_sCAN1TxMessage.ui32MsgLen = sizeof (g_ui8TXMsgData);
G_sCAN1TxMessage.pui8MsgData =(uint8_t *)&g_ui8TXMsgData;


//
//
// CAN 错误处理。 如果存在错误、则在收到消息时
//保存到 g_ui32ErrFlag、错误标志集。 将检查标志下方的内容
//并被清除。 如果是、则由用户来添加处理概念
//需要。
//
//有关错误标志的更多信息,请参阅的 CAN 部分
//微控制器数据表。
//
//注:只有一个板通电时,您可能会在设置过程中遇到错误
//打开。 这是由一个板发送信号而不是另一个板引起的
//板到那里以确认它。 不用担心这些错误、它们可能会是这样
//不予考虑。
//
//
无效
CANErrorHandler (空)

//
// CAN 控制器已进入总线关闭状态。
//
if (g_ui32勘误标志和 CAN_STATUS_BUS_OFF)

//
//此处处理错误条件
//
// UARTprintf ("错误:CAN_STATUS_BUS_OFF \n");
Debug_UART ("错误:CAN_STATUS_BUS_OFF \n"、strlen ("错误:CAN_STATUS_BUS_OFF \n");

//
//清除 CAN_STATUS_BUS_OFF 标志
//
G_ui32ErrFlag &=~(CAN_STATUS_BUS_OFF);

//
// CAN 控制器错误级别已达到警告级别。
//
if (g_ui32勘误表和 CAN_STATUS_EWARN)

//
//此处处理错误条件
//
//UARTprintf ("错误:CAN_STATUS_EWARN \n");
Debug_UART ("错误:CAN_STATUS_EWARN \n"、strlen ("错误:CAN_STATUS_EWARN \n");
//
//清除 CAN_STATUS_EWARN 标志
//
G_ui32勘误表&=~(CAN_STATUS_EWARN);

//
// CAN 控制器错误级别已达到错误被动级别。
//
if (g_ui32勘误标志和 CAN_STATUS_EPASS)

//
//此处处理错误条件
//

//
//清除 CAN_STATUS_EPASS 标志
//
G_ui32勘误表&=~(CAN_STATUS_EPASS);

//
//自上次读取此状态以来,已成功接收到消息。
//
if (g_ui32勘误标志和 CAN_STATUS_RXOK)

//
//此处处理错误条件
//

//
//清除 CAN_STATUS_RXOK 标志
//
G_ui32勘误表&=~(CAN_STATUS_RXOK);

//
//自上次读取此消息以来,已成功发送消息
//状态。
//
if (g_ui32勘误标志和 CAN_STATUS_TXOK)

//
//此处处理错误条件
//

//
//清除 CAN_STATUS_TXOK 标志
//
G_ui32勘误表&=~(CAN_STATUS_TXOK);

//
//这是最后一个错误代码字段的掩码。
//
if (g_ui32勘误表和 CAN_STATUS_LEC_MSK)

//
//此处处理错误条件
//

//
//清除 CAN_STATUS_LEC_MSK 标志
//
G_ui32勘误表&=~(CAN_STATUS_LEC_MSK);

//
//发生了位填充错误。
//
if (g_ui32勘误表和 CAN_STATUS_LEC_SALES)

//
//此处处理错误条件
//

//
//清除 CAN_STATUS_LEC_填 充标志
//
G_ui32勘误表&=~(CAN_STATUS_LEC_SALES);

//
//发生格式错误。
//
if (g_ui32勘误表和 CAN_STATUS_LEC_FORM)

//
//此处处理错误条件
//

//
//清除 CAN_STATUS_LEC_FORM 标志
//
G_ui32勘误表&=~(CAN_STATUS_LEC_FORM);

//
//发生了确认错误。
//
if (g_ui32勘误标志和 CAN_STATUS_LEC_ACK)

//
//此处处理错误条件
//

//
//清除 CAN_STATUS_LEC_ACK 标志
//
G_ui32勘误表&=~(CAN_STATUS_LEC_ACK);

//
//总线保持1的位电平的时间比允许的时间长。
//
if (g_ui32勘误表和 CAN_STATUS_LEC_BIT1)

//
//此处处理错误条件
//

//
//清除 CAN_STATUS_LEC_BIT1标志
//
G_ui32勘误表&=~(CAN_STATUS_LEC_BIT1);

//
//总线保持为0的位电平的时间比允许的时间长。
//
if (g_ui32勘误表和 CAN_STATUS_LEC_BIT0)

//
//此处处理错误条件
//

//
//清除 CAN_STATUS_LEC_BIT0标志
//
G_ui32勘误表&=~(CAN_STATUS_LEC_BIT0);

//
//发生了 CRC 错误。
//
if (g_ui32勘误表和 CAN_STATUS_LEC_CRC)

//
//此处处理错误条件
//

//
//清除 CAN_STATUS_LEC_CRC 标志
//
G_ui32勘误表&=~(CAN_STATUS_LEC_CRC);

//
//这是 CAN 最后一个错误代码(LEC)的掩码。
//
if (g_ui32勘误标志和 CAN_STATUS_LEC_MASK)

//
//此处处理错误条件
//

//
//清除 CAN_STATUS_LEC_MASK 标志
//
G_ui32勘误表&=~(CAN_STATUS_LEC_MASK);

//
//如果 g_ui32ErrFlag 中仍有任何位被置位,则表示未处理
//已经发生。 打印 g_ui32ErrFlag 的值。
//
if (g_ui32勘误标志!=0)

// UARTprintf ("未处理的错误:%x \n"、g_ui32ErrFlag);
Debug_UART ("未处理错误:%x \n"、strlen ("未处理错误:%x \n"));

void debug_UART (char * p、uint16_t length)

uint16_t x = 0;

while (x < length)

while (UARTBusy (UART0_BASE));
UARTCharPutNonBlocking (UART0_BASE、*);
P++;
X++;

void sendCharUart0 (unsigned char _c)

while (UARTBusy (UART0_BASE));
UARTCharPutNonBlocking (UART0_BASE、_c);

//
//
//设置系统,初始化 UART、图形和 CAN。 然后轮询
//用于数据的 UART。 如果有任何数据发送、如果接收到任何数据
//将其打印到 UART。 如果有错误、请调用错误处理
//函数。
//
//
内部
main (空)

//
//为中断处理程序启用怠惰堆栈。 这允许使用浮点
//在中断处理程序中使用的指令,但代价是
//额外的堆栈用法。
//
ROM_FPULazyStackingEnable();

//
//将时钟设置为直接从晶体运行。
//
uint32_t freq = SysCtlClockFreqSet (
(SYSCTL_XTAL_25MHz | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL |
SYSCTL_CFG_VCO_480)、120000000);

SysCtlPeripheralEnable (SYSCTL_Periph_UART0);
SysCtlPeripheralEnable (SYSCTL_Periph_UART3);
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOD);

while (!SysCtlPeripheralReady (SYSCTL_Periph_UART3));
while (!SysCtlPeripheralReady (SYSCTL_Periph_UART0));
while (!SysCtlPeripheralReady (SYSCTL_Periph_GPIOA));
while (!SysCtlPeripheralReady (SYSCTL_Periph_GPIOD));

GPIOPinTypeGPIOOutput (GPIO_PORTD_base、GPIO_PIN_6);
GPIOPinWrite (GPIO_PORTD_BASE、GPIO_PIN_6、0);

//初始化 UART
ConfigureUART();


//初始化 CAN1
InitCAN1();


//打印欢迎消息
// UARTprintf ("\n 可示例应用\n"\n);
// UARTprintf ("键入可在另一个终端上显示的内容:\n\n");

debug_uart ("\ncan example app\n"、strlen ("\n can example app\n");
Debug_UART ("键入要在另一个终端上显示的内容:\n"strlen ("键入要在另一个终端上显示的内容:\n\n");

//轮询 UART 数据,输入内容后跨 CAN 发送
while (1)

//如果该标志被置位、则表示发生了 RX 中断、然后
//有一条消息可以从 CAN 读取
if (g_bRXFlag)

//
//重复使用之前用于配置的同一消息对象
//用于接收消息的 CAN。 用于存储的缓冲器
//还必须提供接收到的数据,所以设置缓冲区指针
//在消息对象中。
//
G_sCAN1RxMessage.pui8MsgData =(uint8_t *)&g_ui8RXMsgData;

//
//从 CAN 读取消息。 使用报文对象 RXOBJECT
//(与 CAN ID 不相同)。 中断清除
//标志未设置、因为中已清除此中断
//中断处理程序。
//
CANMessageGet (CAN1_base、RXOBJECT、&g_sCAN1RxMessage、0);

//
//清除挂起的消息标志,以便中断处理程序可以
//在下一条消息到达时再次设置它。
//
G_bRXFlag = 0;

//
//检查是否有某些消息的指示
//丢失。
//
if (g_sCAN1RxMessage.ui32Flags & MSG_OBJ_DATA_LOST)

// UARTprintf ("\n 检测到消息丢失\n"CAN);
DEBUG_UART ("\n 检测到消息丢失\n"、
strlen("\n 检测到信息丢失\n");


//将接收到的字符打印到 UART 终端
// UARTprintf ("%c"、g_ui8RXMsgData);
sendCharUart0 (g_ui8RXMsgData);

//
//将接收到的字符打印到显示屏上,
//用空格清除行
//

其他

//
//错误处理
//
if (g_ui32勘误标志!= 0)

CANErrorHandler();

//
//查看是否有要传输的新内容
//
while (UARTCharsAvail (UART0_BASE))

//
//从 UART 终端读取下一个字符
//
G_ui8TXMsgData = UARTCharGetNonBlocking (UART0_BASE);


//使用对象编号 TXOBJECT (不是)发送 CAN 消息
//与 CAN ID 相同、在这里也是 TXOBJECT
//示例)。 此函数将导致消息为
//立即传输。
CANMessageSet (CAN1_base、TXOBJECT、&g_sCAN1TxMessage、
MSG_OBJ_TYPE_TX);



有没有人知道会发生什么错误?

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

    您好!

     您的代码很难读取。 发布代码时、请首先选择"插入代码、附加文件等..." 如下所示、然后单击将使用语法荧光笔插入代码的按钮。

     BTW、我建议您也参考下面的 TivaWare CAN 示例 /examples/peripherals/can. 在此文件夹中、您可以找到 simple_tx.c 和 simple_rx.c 这些示例是更简单的入门示例。 您只需更改 TM4C129的引脚映射即可。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    //
    //
    // CAN.c -简单的 CAN 示例。
    //
    //版权所有(c) 2013-2017 Texas Instruments Incorporated。 保留所有权利。
    //软件许可协议
    //
    //德州仪器(TI)提供此软件仅供
    和//仅供 TI 的微控制器产品使用。 软件归
    // TI 和/或其供应商所有,并受适用的版权
    //法律保护。 您不能将此软件与"病毒"开源
    //软件组合在一起以形成更大的程序。
    //
    //此软件按“原样”提供,且存在所有故障。
    //对于
    
    本软件,不作任何明示、暗示或法定的保证,包括但不限于对适销性和适用性的暗示保证//特定用途。 在任何
    //情况下、TI 不对任何
    原因造成的特殊、意外或必然//损害负责。
    //
    //这是 DK-TM4C123G 固件包的修订版本2.1.4.178的一部分。
    ////
    *****************
    
    #include 
    #include 
    #include 
    #include 
    #include "inc/hw_ca.h"
    #include "include/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "driverlib/fpu.h"
    #include "driverlib/ca.h"
    #include "driverlib/gpin_map.h"
    
    
    
    
    
    
    
    #include "driverlib/drivers.mdio.h"#include "drivers/drivers.mdio.ultrl
    
    
    //
    //! \addtogroup example_list
    //! 

    CAN 示例(CAN)

    //! //! 此示例应用程序利用 CAN 来回发送字符 //! 之间的差异。 它使用 UART 读取/写入字符到 //! UART 终端。 它还使用板上的图形显示来显示 //! 最后一个字符被转接/接收。 还包括错误处理。 //! //! CAN 硬件设置: //! //! 要使用此示例、您需要连接两个 DK-TM4C123G 板 //! 一起工作。 这涉及连接 CANH 螺纹接线端子 //! 和 CANL 端子一起。 此外、120 Ω 终端 //! 需要在 CANH //!之间的网络边缘添加电阻器 和 CANL。 在两个电路板设置中、这意味着连接一个120欧姆的电阻 器//! CANH 和 CANL 之间的差值。 //! //! 请参阅下图了解可视性。 '--'代表导线。 //! //! 逐字记录 //! CANH---+--- +--CANH //! | | //! .. .. //! ||120欧姆 ||120欧姆 //! || || //! "-" '-' //! | | //! CANL---------------- +--CANL //! \end逐 字记录 //! //! 软件设置: //! //! 设置硬件连接后、将两个板连接到计算机 //! 通过图形显示屏旁边的在线调试接口 USB 端口。 //! 将一个 UART 终端连接到每块配置为115、200波特、8-n-1模式的电路板。 //! //! 您键入一个终端的任何内容都将显示在另一个终端和 //! 反之亦然。 发送/接收的最后一个字符也将显示在 //! 板上的图形显示。 //// ***************** // // //跟踪 TX & RX 中断次数 的计数器//发生,该计数器应与发送的消息数匹 配//接收的消息数匹配。 //// ***************** 易失性 uint32_t g_ui32RXMsgCount = 0; 易失性 uint32_t g_ui32TXMsgCount = 0; //********* // //中断处理程序的标志,指示已收到消息。 //// ***************** 易失性 bool g_BRXFlag = 0; //********* // //一个全局变量,用于跟踪已抛出的错误标志,以便 可以//进行处理。 这是必要 的、因为读取错误寄存器会清除//标志、所以有必要将它们保存在某个位置进行处理。 //// ***************** volatile uint32_t g_ui32 ErrFlag = 0; //********* // //正在发送/接收的数据的 CAN 消息对象 // tCANMsgObject g_sCAN0RxMessage; tCANMsgObject g_sCAN0TxMessage; //********* // //消息标识符和对象 // RXID 设置为0,因此接收所有消息 // ********* #define CAN1RXID 0 #define RXOBJECT 1 #define CAN1TXID 2 #define TXOBJECT 2 //********* // //保存字符的变量被发送/接收 // //************* uint8_t g_ui8TXMsgData; uint8_t g_ui8RXMsgData; //********* // //图形显示上打印的文本的全局上下文 // //********* tContext g_sContext; //********* // //屏幕行显示,以像素为单位的顶部偏移 // //********* #define SCREENLINE1 10 #define SCREENLINE2 20 #define SCREENLINE3 30 #define SCREENLINE4 40 #define SCREENLINE5 50 //********* // //如果驱动程序库遇到错误,则调用的错误例程。 //// ***************** #ifdef debug void __error__(char *dpcFilename、uint32_t ui32Line) { #endif //********* // // CAN 0中断处理程序。 它检查中断原因、 并且//保持已发送/接收 的所有消息的计数// ********* void CAN0IntHandler (void) { uint32_t ui32Status; // //读取 CAN 中断状态以查找中断原因 // // CAN_INT_STS_Cause 寄存器值 // 0x0000 =无中断挂起 // 0x0001-0x0020 =导致中断的报文对象数 // 0x8000 =状态中断 //所有其它数字都是保留的,在本系统中没有意义 // ui32Status = CANIntStatus (CAN1_base、CAN_INT_STS_CAUST); // //如果这是一个状态中断、则通过读取 CAN 来确认它 //控制器状态寄存器。 // if (ui32Status = CAN_INT_INTID_STATUS) { // //读取控制器状态。 这将返回状态字段 //可以指示各种错误的错误位。 请参阅 // API 文档,了解有关错误状态位的详细信息。 //读取此状态的操作将清除中断。 // ui32Status = CANStatusGet (CAN1_base、CAN_STS_CONTROL); // //将错误标志添加到当前错误列表中。 要处理的数据 //因为在中需要太多的时间 //中断。 // G_ui32ErrFlag |= ui32Status; } // //检查原因是否是我们正在使用的消息对象 RXOBJECT //用于接收消息。 // 否则、IF (ui32Status = RXOBJECT) { // //到达这一点意味着 RX 中断发生在上 //消息对象 RXOBJECT、消息接收完成。 //清除报文对象中断。 // CANIntClear (CAN1_BASE、RXOBJECT); // //递增计数器以跟踪已有多少消息 //已收到。 在实际应用中、这可用于将标志设置为 //指示何时接收到消息。 // G_ui32RXMsgCount++; // //设置标志以指示接收到的消息正暂挂。 // G_bRXFlag = true; // //由于接收到消息,因此清除所有错误标志。 //这是因为在收到消息之前它会触发 // RX 完成的状态中断。 通过清除这里的标志、我们可以看到 //防止发生不必要的错误处理 // G_ui32ErrFlag = 0; } // //检查原因是否是我们正在使用的消息对象 TXOBJECT //用于传输消息。 // 否则、如果(ui32Status = TXOBJECT) { // //到达这一点意味着 TX 中断发生在上 //消息对象 TXOBJECT、消息接收完成。 //清除报文对象中断。 // CANIntClear (CAN1_BASE、TXOBJECT); // //递增计数器以跟踪已有多少消息 //已发送。 在实际应用中、可以使用此设置 //指示消息何时传输的标志。 // G_ui32TXMsgCount++; // //由于已发送消息,因此清除所有错误标志。 //这是因为在发送消息之前它会触发 // TX 完成的状态中断。 通过清除这里的标志、我们可以看到 //防止发生不必要的错误处理 // G_ui32ErrFlag = 0; } // //否则,发生意外导致中断的情况。 这应该是 //永远不会发生。 // 其他 { // //可以在此处执行伪中断处理。 // } } //********* // //配置 UART 及其引脚。 这必须在 UARTprintf()之前调用。 //// ***************** void ConfigureUART (void) { // Uart0 GPIOPinConfigure (GPIO_PA0_U0RX); GPIOPinConfigure (GPIO_PA1_U0TX); GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1); UARTConfigSetExpClk (UART0_BASE、120000000、115200、 (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE)); UARTFIFODisable (UART0_BASE); UARTEnable (UART0_BASE); } //********* // //将 CAN0设置为以500kHz 的频率发送和接收。 //中断// 使用 PE4/PE5 // //********* 空 InitCAN0 (空) { // //对于此示例、CAN0与端口 E4和 E5上的 RX 和 TX 引脚搭配使用。 //需要启用 GPIO 端口 E,以便可以使用这些引脚。 // SysCtlPeripheralEnable (SYSCTL_Periph_GPIOB); while (!SysCtlPeripheralReady (SYSCTL_Periph_GPIOB)); // //配置 GPIO 引脚复用以选择这些引脚的 CAN0功能。 //此步骤选择可用于这些引脚的替代功能。 // 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); while (!SysCtlPeripheralReady (SYSCTL_Periph_CAN1)); // //初始化 CAN 控制器 // CANInit (CAN1_base); // //设置 CAN 总线的比特率。 此函数设置 CAN 针对标称配置的//总线时序。 您可以实现更多控制 //使用函数 CANBitTimingSet()代替 CAN 总线时序 //如果需要。 //在此示例中、CAN 总线设置为500kHz。 // CANBitRateSet (CAN1_base、120000000、50000); // //在 CAN 外设上启用中断。 此示例使用静态 //分配中断处理程序,表示处理程序的名称 //位于启动代码的矢量表中。 // CANIntRegister (CAN1_base、CAN0IntHandler); CANIntEnable (CAN1_base、CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS); // //在处理器(NVIC)上启用 CAN 中断。 // IntEnable (INT_CAN1); // //启用 CAN 以进行操作。 // CANEnable (CAN1_base); // //初始化用于接收 CAN 消息的消息对象 //任何 CAN ID。 为了接收任何 CAN ID、ID 和掩码必须同时存在 //设置为0,并启用 ID 过滤器。 // G_sCAN0RxMessage.ui32MsgID = CAN1RXID; G_sCAN0RxMessage.ui32MsgIDMask = 0; G_sCAN0RxMessage.ui32Flags = MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER; G_sCAN0RxMessage.ui32MsgLen = sizeof (g_ui8RXMsgData); // //现在将消息对象加载到 CAN 外设中。 加载后 // CAN 将在总线上接收任何消息,并将发生中断。 //使用消息对象 RXOBJECT 接收消息(这不是 //与 CAN ID 相同,在本例中可以是任何值)。 // CANMessageSet (CAN1_base、RXOBJECT、&g_sCAN0RxMessage、MSG_OBJ_TYPE_RX); // //初始化将用于发送 CAN 的消息对象 //消息。 消息将是包含字符的1个字节 //从另一个控制器接收。 最初它将设置为0。 // G_ui8TXMsgData = 0; G_sCAN0TxMessage.ui32MsgID = CAN1TXID; G_sCAN0TxMessage.ui32MsgIDMask = 0; G_sCAN0TxMessage.ui32Flags = MSG_OBJ_TX_INT_ENABLE; G_sCAN0TxMessage.ui32MsgLen = sizeof (g_ui8TXMsgData); G_sCAN0TxMessage.pui8MsgData =(uint8_t *)&g_ui8TXMsgData; } //********* // // CAN 错误处理。 当收到消息时、如果存在错误、 则//将其保存到 g_ui32ErrFlag 中、错误标志置1。 标志下方被选中 //并被清除。 如果需要的话 、由用户来添加处理功能//。 // //有关错误标志的更多信息、请参阅 //微控制器数据表的 CAN 部分。 // //注:只有一个板通电 时,您在设置过程中可能会遇到错误//打开。 这是由一个板发送信号而 没有另一个//板来确认的。 不要担心这些错误、 它们可以被//忽略。 //// ***************** void CANErrorHandler (void) { // // CAN 控制器已进入总线关闭状态。 // if (g_ui32勘误标志和 CAN_STATUS_BUS_OFF) { // //此处处理错误条件 // // UARTprintf ("错误:CAN_STATUS_BUS_OFF \n"); Debug_UART ("错误:CAN_STATUS_BUS_OFF \n"、strlen ("错误:CAN_STATUS_BUS_OFF \n"); // //清除 CAN_STATUS_BUS_OFF 标志 // G_ui32ErrFlag &=~(CAN_STATUS_BUS_OFF); } // // CAN 控制器错误级别已达到警告级别。 // if (g_ui32勘误表和 CAN_STATUS_EWARN) { // //此处处理错误条件 // //UARTprintf ("错误:CAN_STATUS_EWARN \n"); Debug_UART ("错误:CAN_STATUS_EWARN \n"、strlen ("错误:CAN_STATUS_EWARN \n"); // //清除 CAN_STATUS_EWARN 标志 // G_ui32ErrFlag &=~(CAN_STATUS_EWARN); } // // CAN 控制器错误级别已达到错误被动级别。 // if (g_ui32勘误标志和 CAN_STATUS_EPASS) { // //此处处理错误条件 // // //清除 CAN_STATUS_EPASS 标志 // G_ui32ErrFlag &=~(CAN_STATUS_EPASS); } // //自上次读取此状态以来,已成功接收到消息。 // if (g_ui32勘误标志和 CAN_STATUS_RXOK) { // //此处处理错误条件 // // //清除 CAN_STATUS_RXOK 标志 // G_ui32ErrFlag &=~(CAN_STATUS_RXOK); } // //自上次读取此消息以来,已成功发送消息 //状态。 // if (g_ui32勘误标志和 CAN_STATUS_TXOK) { // //此处处理错误条件 // // //清除 CAN_STATUS_TXOK 标志 // G_ui32ErrFlag &=~(CAN_STATUS_TXOK); } // //这是最后一个错误代码字段的掩码。 // if (g_ui32勘误表和 CAN_STATUS_LEC_MSK) { // //此处处理错误条件 // // //清除 CAN_STATUS_LEC_MSK 标志 // G_ui32ErrFlag &=~(CAN_STATUS_LEC_MSK); } // //发生了位填充错误。 // if (g_ui32勘误表和 CAN_STATUS_LEC_SALES) { // //此处处理错误条件 // // //清除 CAN_STATUS_LEC_填 充标志 // G_ui32ErrFlag &=~(CAN_STATUS_LEC_SALES); } // //发生格式错误。 // if (g_ui32勘误表和 CAN_STATUS_LEC_FORM) { // //此处处理错误条件 // // //清除 CAN_STATUS_LEC_FORM 标志 // G_ui32ErrFlag &=~(CAN_STATUS_LEC_FORM); } // //发生了确认错误。 // if (g_ui32勘误标志和 CAN_STATUS_LEC_ACK) { // //此处处理错误条件 // // //清除 CAN_STATUS_LEC_ACK 标志 // G_ui32ErrFlag &=~(CAN_STATUS_LEC_ACK); } // //总线保持1的位电平的时间比允许的时间长。 // if (g_ui32勘误表和 CAN_STATUS_LEC_BIT1) { // //此处处理错误条件 // // //清除 CAN_STATUS_LEC_BIT1标志 // G_ui32ErrFlag &=~(CAN_STATUS_LEC_BIT1); } // //总线保持为0的位电平的时间比允许的时间长。 // if (g_ui32勘误表和 CAN_STATUS_LEC_BIT0) { // //此处处理错误条件 // // //清除 CAN_STATUS_LEC_BIT0标志 // G_ui32ErrFlag &=~(CAN_STATUS_LEC_BIT0); } // //发生了 CRC 错误。 // if (g_ui32勘误表和 CAN_STATUS_LEC_CRC) { // //此处处理错误条件 // // //清除 CAN_STATUS_LEC_CRC 标志 // G_ui32ErrFlag &=~(CAN_STATUS_LEC_CRC); } // //这是 CAN 最后一个错误代码(LEC)的掩码。 // if (g_ui32勘误标志和 CAN_STATUS_LEC_MASK) { // //此处处理错误条件 // // //清除 CAN_STATUS_LEC_MASK 标志 // G_ui32ErrFlag &=~(CAN_STATUS_LEC_MASK); } // //如果 g_ui32ErrFlag 中仍有任何位被置位,则表示未处理 //已经发生。 打印 g_ui32ErrFlag 的值。 // if (g_ui32勘误标志!=0) { // UARTprintf ("未处理错误:%x \n"、g_ui32ErrFlag); Debug_UART ("未处理错误:%x \n"、strlen ("未处理错误:%x \n")); } } void debug_UART (char * p、uint16_t length) { uint16_t x = 0; while (x < length) { while (UARTBusy (UART0_BASE)); UARTCharPutNonBlocking (UART0_BASE、*); P++; X++; } } void sendCharUart0 (unsigned char _c) { while (UARTBusy (UART0_BASE)); UARTCharPutNonBlocking (UART0_BASE、_c); } //********* // //设置系统,初始化 UART、图形和 CAN。 然后轮询 // UART 以获取数据。 如果有任何数据发送、如果接收到任何数据 //将其打印到 UART。 如果出现错误、请调用错误处理 //函数。 //// ***************** int main (void) { // //为中断处理程序启用怠惰堆栈。 这允许使用浮点 //在中断处理程序中使用的指令,但代价是 //额外的堆栈用法。 // ROM_FPULazyStackingEnable(); // //将时钟设置为直接从晶体运行。 // uint32_t freq = SysCtlClockFreqSet ( (SYSCTL_XTAL_25MHz | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480)、120000000); SysCtlPeripheralEnable (SYSCTL_Periph_UART0); SysCtlPeripheralEnable (SYSCTL_Periph_UART3); SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA); SysCtlPeripheralEnable (SYSCTL_Periph_GPIOD); while (!SysCtlPeripheralReady (SYSCTL_Periph_UART3)); while (!SysCtlPeripheralReady (SYSCTL_Periph_UART0)); while (!SysCtlPeripheralReady (SYSCTL_Periph_GPIOA)); while (!SysCtlPeripheralReady (SYSCTL_Periph_GPIOD)); GPIOPinTypeGPIOOutput (GPIO_PORTD_base、GPIO_PIN_6); GPIOPinWrite (GPIO_PORTD_BASE、GPIO_PIN_6、0); //初始化 UART ConfigureUART(); //初始化 CAN0 InitCAN0(); //打印欢迎消息 // UARTprintf ("\nCAN 示例应用\n"); // UARTprintf ("键入要在另一个终端上显示的内容:\n"\}); debug_uart ("\ncan example app\n"、strlen ("\n can example app\n"); Debug_UART ("键入要在另一个终端上显示的内容:\n"strlen ("键入要在另一个终端上显示的内容:\n\n"); //轮询 UART 数据,输入内容后跨 CAN 发送 while (1) { //如果该标志被置位、则表示发生了 RX 中断、然后 //有一条消息可以从 CAN 读取 if (g_bRXFlag) { // //重复使用之前用于配置的同一消息对象 //用于接收消息的 CAN。 用于存储的缓冲器 //还必须提供接收到的数据,所以设置缓冲区指针 //在消息对象中。 // G_sCAN0RxMessage.pui8MsgData =(uint8_t *)&g_ui8RXMsgData; // //从 CAN 读取消息。 使用报文对象 RXOBJECT //(与 CAN ID 不相同)。 中断清除 //标志未设置、因为中已清除此中断 //中断处理程序。 // CANMessageGet (CAN1_base、RXOBJECT、&g_sCAN0RxMessage、0); // //清除挂起的消息标志,以便中断处理程序可以 //在下一条消息到达时再次设置它。 // G_bRXFlag = 0; // //检查是否有某些消息的指示 //丢失。 // if (g_sCAN0RxMessage.ui32Flags & MSG_OBJ_DATA_LOST) { // UARTprintf ("\n 检测到消息丢失\n"CAN); DEBUG_UART ("\n 检测到消息丢失\n"、 strlen("\n 检测到消息丢失\n"); } //将接收到的字符打印到 UART 终端 // UARTprintf ("%c"、g_ui8RXMsgData); sendCharUart0 (g_ui8RXMsgData); // //将接收到的字符打印到显示屏上, //用空格清除行 // } 其他 { // //错误处理 // if (g_ui32勘误标志!= 0) { CANErrorHandler(); } // //查看是否有要传输的新内容 // while (UARTCharsAvail (UART0_BASE)) { // //从 UART 终端读取下一个字符 // G_ui8TXMsgData = UARTCharGetNonBlocking (UART0_BASE); //使用对象编号 TXOBJECT (不是)发送 CAN 消息 //与 CAN ID 相同、在这里也是 TXOBJECT //示例)。 此函数将导致消息为 //立即传输。 CANMessageSet (CAN1_base、TXOBJECT、&g_sCAN0TxMessage、 MSG_OBJ_TYPE_TX); } } }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!
    您是否具有至少具有两个节点的 CAN 网络设置? 您使用的示例基于具有板载 CAN 收发器的 DK-TM4C123板。 EK-TM4C129 LaunchPad 没有收发器。 我假设您连接了一个外部收发器。 是这样吗? 我快速浏览了您的代码、我没有发现任何明显的错误。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    是的、我有两个 EK 节点、每个节点都连接到收发器。 我以前使用 MCP2561收发器进行过测试、现在我尝试使用65hvd251收发器。 我将 Tiva 的引脚 PB1 (CAN1tx)连接到收发器的 DO 引脚1 (TXD)、将引脚 PB0 (CAN1RX)连接到引脚4 (RXD)、将 Rs 引脚接地、将两个收发器的 CANH 和 CANL 连接在一起、 但是、由于我要在试验电路板上进行测试、其中两个收发器非常靠近、因此我没有在总线上放置任何终端电阻器。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您能否参考 simple_tx.c 和 simple_rx.c 示例并尝试这两个示例?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    是的、当然可以。 我会尝试一下。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    简单 Rx 
    // // //// simple_rx.c -演示简单 CAN 消息接收的示例。 // //版权所有(c) 2010-2017 Texas Instruments Incorporated。 保留所有权利。 //软件许可协议 // 以源代码和二进制形式重新分发和使用,无论是否 进行//修改,只要 满足以下条件//: // 重新分发源代码必须保留上述版权 //声明、此条件列表和以下免责声明。 // //二进制形式的再发行必须复制上述版权 //声明、此条件列表和// 分发随附的//文档和/或其他材料中的以下免责声明。 //// 未经 事先书面许可,不能使用德州仪器公司的名称或//其贡献者的名称来认可或推广源自此软件的产品//。 //// 本软件由版权所有者和贡献者提供 //“按原样”,不 承认任何明示或暗示的保证,包括但不限于//适销性和对//特定用途适用性的暗示保证。 在任何情况下、版权 //所有者或贡献者都不对任何直接、间接、偶然、 //特殊、模范、 或相应的损害(包括但不 限于采购替代产品或服务;丧失使用、 //数据或利润; 或业务中断)、无论 出于何 种原因使用 本软件、无论在合同中、在合同中、严格责任还是在侵权行为中//(INCLUDIFNG 疏忽或其他原因)、均会引起任何//责任理论、即使被告知存在此类损坏的可能性。 // //这是 Tiva 固件开发包的修订版2.1.4.178的一部分。 //// ***************** #include #include #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 信号。 您必须 //! 查看这些内容并根据您自己的董事会需要进行更改: //! - CAN1外设 //! - GPIO 端口 B 外设(用于 CAN1引脚) //! - CAN1RX - PB4 //! - CAN1TX - PB5 //! //! 以下 UART 信号仅配置为显示控制台 //! 消息。 CAN 的运行不需要这些参数。 //! - GPIO 端口 A 外设(用于 UART0引脚) //! - UART0RX - PA0 //! - UART0TX - PA1 //! //! 此示例使用以下中断处理程序。 要使用此示例 //! 在您自己的应用程序中、您必须将这些中断处理程序添加到 您的//! 矢量表。 //! - INT_CAN1 - CANIntHandler // /********* // // //跟踪 RX 中断次数 的计数器//发生,该计数器应与接收到的消息数匹配。 //// ***************** 易失性 uint32_t g_ui32MsgCount = 0; //********* // //中断处理程序的标志,指示已收到消息。 //// ***************** 易失性 bool g_BRXFlag = 0; //********* // //指示发生了一些接收错误的标志。 //// ***************** volatile bool g_BErrFlag = 0; //********* // //此函数将 UART0设置为用于控制台,以便 在示例运行时显示信息//。 //// ***************** void InitConsole (void) { SysCtlPeripheralEnable (SYSCTL_Periph_UART0); SysCtlPeripheralEnable (SYSCTL_Periph_UART3); SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA); SysCtlPeripheralEnable (SYSCTL_Periph_GPIOD); while (!SysCtlPeripheralReady (SYSCTL_Periph_UART3)); while (!SysCtlPeripheralReady (SYSCTL_Periph_UART0)); while (!SysCtlPeripheralReady (SYSCTL_Periph_GPIOA)); while (!SysCtlPeripheralReady (SYSCTL_Periph_GPIOD)); // Uart0 GPIOPinConfigure (GPIO_PA0_U0RX); GPIOPinConfigure (GPIO_PA1_U0TX); GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1); UARTConfigSetExpClk (UART0_BASE、120000000、115200、 (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE)); UARTFIFODisable (UART0_BASE); UARTEnable (UART0_BASE); } //********* // //此函数是 CAN 外设的中断处理程序。 它会检查 //中断原因,并对 所有已接收到的消息进行计数。 //// ***************** void CANIntHandler (void) { uint32_t ui32Status; // //读取 CAN 中断状态以查找中断原因 // ui32Status = CANIntStatus (CAN1_base、CAN_INT_STS_CAUST); // //如果原因是控制器状态中断,则获取状态 // if (ui32Status = CAN_INT_INTID_STATUS) { // //读取控制器状态。 这将返回状态字段 //可以指示各种错误的错误位。 错误处理 //本示例中不是为了简单起见。 请参阅 // API 文档,了解有关错误状态位的详细信息。 //读取此状态的操作将清除中断。 // ui32Status = CANStatusGet (CAN1_base、CAN_STS_CONTROL); // //设置一个标志来指示可能发生的某些错误。 // G_bErrFlag = 1; } // //检查原因是否是我们正在使用的消息对象1 //接收消息。 // 否则、如果(ui32Status = 1) { // //到达这一点意味着 RX 中断发生在上 //消息对象1,消息接收完成。 清除 //消息目标中断。 // CANIntClear (CAN1_base、1); // //递增计数器以跟踪已有多少消息 //已收到。 在实际应用中、这可用于将标志设置为 //指示何时接收到消息。 // G_ui32MsgCount++; // //设置标志以指示接收到的消息正暂挂。 // G_bRXFlag = 1; // //由于接收到消息,因此清除所有错误标志。 // G_bErrFlag = 0; } // //否则,发生意外导致中断的情况。 这应该是 //永远不会发生。 // 其他 { // //可以在此处执行伪中断处理。 // } } void debug_UART (char * p、uint16_t length) { uint16_t x = 0; while (x < length) { while (UARTBusy (UART0_BASE)); UARTCharPutNonBlocking (UART0_BASE、*); P++; X++; } } void sendCharUart0 (unsigned char _c) { while (UARTBusy (UART0_BASE)); UARTCharPutNonBlocking (UART0_BASE、_c); } //********* // //配置 CAN 并输入一个循环来接收 CAN 消息。 //// ***************** int main (void) { SysCtlPeripheralEnable (SYSCTL_Periph_GPIOD); while (!SysCtlPeripheralReady (SYSCTL_Periph_GPIOD)); GPIOPinTypeGPIOOutput (GPIO_PORTD_base、GPIO_PIN_6); GPIOPinWrite (GPIO_PORTD_BASE、GPIO_PIN_6、0); uint32_t ui32SysClock; tCANMsgObject sCANMessage; uint8_t pui8MsgData[8]; // //将时钟设置为直接从外部晶振/振荡器运行。 //必须更改 sysctl_XTAL_value 以匹配的值 //您的板上使用的晶体。 // ui32SysClock = SysCtlClockFreqSet() (SYSCTL_XTAL_25MHz | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480)、120000000); // //设置用于显示消息的串行控制台。 这是 //仅针对此示例程序,CAN 操作不需要。 // InitConsole(); // //对于此示例、CAN1与端口 B4和 B5上的 RX 和 TX 引脚一起使用。 //您使用的实际端口和引脚可能有所不同,请参阅 //数据表以了解更多信息。 // GPIO 端口 B 需要启用、以便可以使用这些引脚。 // TODO:将其更改为您正在使用的 GPIO 端口 // SysCtlPeripheralEnable (SYSCTL_Periph_GPIOB); while (!SysCtlPeripheralReady (SYSCTL_Periph_GPIOB)); // //配置 GPIO 引脚复用以选择这些引脚的 CAN1功能。 //此步骤选择可用于这些引脚的替代功能。 //如果您的器件支持 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); while (!SysCtlPeripheralReady (SYSCTL_Periph_CAN1)); // //初始化 CAN 控制器 // CANInit (CAN1_base); // //设置 CAN 总线的比特率。 此函数设置 CAN 针对标称配置的//总线时序。 您可以实现更多控制 //使用函数 CANBitTimingSet()代替 CAN 总线时序 //如果需要。 //在此示例中、CAN 总线设置为500kHz。 在以下函数中、 // SysCtlClockGet ()或 ui32SysClock 的调用被用来确定 //用于为 CAN 外设计时的时钟速率。 这是可以的 //如果您知道系统时钟的值,则替换为固定值, //保存额外的函数调用。 对于某些器件、CAN 外设是 //使用固定的8MHz 时钟进行计时,而不管在哪种情况下是系统时钟 //对 SysCtlClockGet()或 ui32SysClock 的调用应替换为 // 80000。 有关 CAN 的更多信息、请参阅数据表 //外设时钟。 // CANBitRateSet (CAN1_base、ui32SysClock、50000); // //在 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_CAN1); // //启用 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); // //输入循环以处理收到的消息。 该循环仅检查一个标志 //由中断处理程序设置,如果该位置位,则读取 //消息并显示内容。 这不是一种稳健的方法 //处理传入的 CAN 数据,并且一次只能处理一条消息。 //如果多条消息一起接收,则会收到一些消息 //可能被丢弃。 在实际应用中、应使用其他一些方法 //对收到的消息进行排队,以确保它们不会丢失。 您 //也可以使用 CAN FIFO 模式,允许消息为 //在处理前进行缓冲。 // DEBUG_UART ("CAN 接收代码开始!!!!!!!!!"strlen ("CAN 接收代码开始!!!!!!!!!!"); 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"); DEBUG_UART ("检测到 CAN 消息丢失\n",strlen ("检测到 CAN 消息丢失\n"); } char ponteiro[50]; // //打印接收到的消息的内容。 // //UARTprintf ("Msg ID=0x%08X len=%u data=0x"、sCANMessage.ui32MsgID、sCANMessage.ui32MsgLen); sprintf (ponteiro、"Msg ID=0x%08X len=%u data=0x"、sCANMessage.ui32MsgID、sCANMessage.ui32MsgLen); debug_uart (ponteiro、strlen (ponteiro)); for (uIdx = 0;uIdx < sCANMessage.ui32MsgLen;uIdx++) { //UARTprintf ("%02x "、pui8MsgData[uIdx]); sprintf (ponteiro、"%d"、pui8MsgData[uIdx]); debug_uart (ponteiro、strlen (ponteiro)); } //UARTprintf ("total count=%u\n"、g_ui32MsgCount); sprintf (ponteiro、"总计数=%u\n"、g_ui32MsgCount); debug_uart (ponteiro、strlen (ponteiro)); } } // //返回无错误 // 返回(0); }

    简单 Tx

    //
    //
    //// simple_tx.c -演示简单 CAN 消息传输的示例。
    //
    //版权所有(c) 2010-2017 Texas Instruments Incorporated。 保留所有权利。
    //软件许可协议
    //
    以源代码和二进制形式重新分发和使用,无论是否
    进行//修改,只要
    满足以下条件//:
    //
    重新分发源代码必须保留上述版权
    //声明、此条件列表和以下免责声明。
    //
    //二进制形式的再发行必须复制上述版权
    //声明、此条件列表和//
    
    分发随附的//文档和/或其他材料中的以下免责声明。
    ////
    未经
    
    事先书面许可,不能使用德州仪器公司的名称或//其贡献者的名称来认可或推广源自此软件的产品//。
    ////
    本软件由版权所有者和贡献者提供
    //“按原样”,不
    
    承认任何明示或暗示的保证,包括但不限于//适销性和对//特定用途适用性的暗示保证。 在任何情况下、版权
    //所有者或贡献者都不对任何直接、间接、偶然、
    //特殊、模范、 或相应的损害(包括但不
    限于采购替代产品或服务;丧失使用、
    //数据或利润; 或业务中断)、无论
    
    出于何种原因使用
    本软件(即使被告知可能会造成此类损坏)、还是出于任何原因而产生的任何//责任理论(无论是合同、严格责任还是侵权行为)//(包括疏忽或其他)。
    //
    //这是 Tiva 固件开发包的修订版2.1.4.178的一部分。
    ////
    *****************
    
    #include 
    #include 
    #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 信号。 您必须 //! 查看这些内容并根据您自己的董事会需要进行更改: //! - CAN1外设 //! - GPIO 端口 B 外设(用于 CAN1引脚) //! - CAN1RX - PB4 //! - CAN1TX - PB5 //! //! 以下 UART 信号仅配置为显示控制台 //! 消息。 CAN 的运行不需要这些参数。 //! - GPIO 端口 A 外设(用于 UART0引脚) //! - UART0RX - PA0 //! - UART0TX - PA1 //! //! 此示例使用以下中断处理程序。 要使用此示例 //! 在您自己的应用程序中、您必须将这些中断处理程序添加到 您的//! 矢量表。 //! - INT_CAN1 - CANIntHandler // /********* // // //跟踪 TX 中断次数 的计数器//发生,该计数器应与发送的 TX 消息数匹配。 //// ***************** 易失性 uint32_t g_ui32MsgCount = 0; //********* // //指示发生了一些传输错误的标志。 //// ***************** volatile bool g_BErrFlag = 0; //********* // //此函数将 UART0设置为用于控制台,以便 在示例运行时显示信息//。 //// ***************** void InitConsole (void) { SysCtlPeripheralEnable (SYSCTL_Periph_UART0); SysCtlPeripheralEnable (SYSCTL_Periph_UART3); SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA); SysCtlPeripheralEnable (SYSCTL_Periph_GPIOD); while (!SysCtlPeripheralReady (SYSCTL_Periph_UART3)); while (!SysCtlPeripheralReady (SYSCTL_Periph_UART0)); while (!SysCtlPeripheralReady (SYSCTL_Periph_GPIOA)); while (!SysCtlPeripheralReady (SYSCTL_Periph_GPIOD)); // Uart0 GPIOPinConfigure (GPIO_PA0_U0RX); GPIOPinConfigure (GPIO_PA1_U0TX); GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1); UARTConfigSetExpClk (UART0_BASE、120000000、115200、 (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE)); UARTFIFODisable (UART0_BASE); UARTEnable (UART0_BASE); } //********* // //此函数使用简单的轮询方法提供1秒延迟。 //// ***************** void SimpleDelay (void) { // //延迟周期1秒 // SysCtlDelay (16000000 / 3); } //********* // //此函数是 CAN 外设的中断处理程序。 它会检查 //中断原因,并保持 //已传输的所有消息的计数。 //// ***************** void CANIntHandler (void) { uint32_t ui32Status; // //读取 CAN 中断状态以查找中断原因 // ui32Status = CANIntStatus (CAN1_base、CAN_INT_STS_CAUST); // //如果原因是控制器状态中断,则获取状态 // if (ui32Status = CAN_INT_INTID_STATUS) { // //读取控制器状态。 这将返回状态字段 //可以指示各种错误的错误位。 错误处理 //本示例中不是为了简单起见。 请参阅 // API 文档,了解有关错误状态位的详细信息。 //读取此状态的操作将清除中断。 如果 // CAN 外设未与其它 CAN 器件连接到 CAN 总线 //存在,则会发生错误,并在中指示 //控制器状态。 // ui32Status = CANStatusGet (CAN1_base、CAN_STS_CONTROL); // //设置一个标志来指示可能发生的某些错误。 // G_bErrFlag = 1; } // //检查原因是否是我们正在使用的消息对象1 //发送消息。 // 否则、如果(ui32Status = 1) { // //到达这一点意味着 TX 中断发生在上 //消息对象1、消息 TX 完成。 清除 //消息目标中断。 // CANIntClear (CAN1_base、1); // //递增计数器以跟踪已有多少消息 //已发送。 在实际应用中、这可用于将标志设置为 //指示何时发送消息。 // G_ui32MsgCount++; // //由于消息已发送,请清除所有错误标志。 // G_bErrFlag = 0; } // //否则,发生意外导致中断的情况。 这应该是 //永远不会发生。 // 其他 { // //可以在此处执行伪中断处理。 // } } //********* // //配置 CAN 并输入循环以传输周期性 CAN 消息。 //// ***************** void debug_UART (char * p、uint16_t length) { uint16_t x = 0; while (x < length) { while (UARTBusy (UART0_BASE)); UARTCharPutNonBlocking (UART0_BASE、*); P++; X++; } } void sendCharUart0 (unsigned char _c) { while (UARTBusy (UART0_BASE)); UARTCharPutNonBlocking (UART0_BASE、_c); } int main (void) { SysCtlPeripheralEnable (SYSCTL_Periph_GPIOD); while (!SysCtlPeripheralReady (SYSCTL_Periph_GPIOD)); GPIOPinTypeGPIOOutput (GPIO_PORTD_base、GPIO_PIN_6); GPIOPinWrite (GPIO_PORTD_BASE、GPIO_PIN_6、0); uint32_t ui32SysClock; tCANMsgObject sCANMessage; uint32_t ui32MsgData; uint8_t * pui8MsgData; pui8MsgData =(uint8_t *) ui32MsgData; // //将时钟设置为直接从外部晶振/振荡器运行。 // TODO:必须更改 SYSCTL_XTAL_VALUE 以匹配的值 板上的//晶体。 // ui32SysClock = SysCtlClockFreqSet() (SYSCTL_XTAL_25MHz | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480)、120000000); // //设置用于显示消息的串行控制台。 这是 //仅针对此示例程序,CAN 操作不需要。 // InitConsole(); // //对于此示例、CAN1与端口 B4和 B5上的 RX 和 TX 引脚一起使用。 //您使用的实际端口和引脚可能有所不同,请参阅 //数据表以了解更多信息。 // GPIO 端口 B 需要启用、以便可以使用这些引脚。 // TODO:将其更改为您正在使用的 GPIO 端口 // SysCtlPeripheralEnable (SYSCTL_Periph_GPIOB); while (!SysCtlPeripheralReady (SYSCTL_Periph_GPIOB)); // //配置 GPIO 引脚复用以选择这些引脚的 CAN1功能。 //此步骤选择可用于这些引脚的替代功能。 //如果您的器件支持 GPIO 引脚功能多路复用、这是必需的。 //请查阅数据表以查看每个引脚分配的函数。 // TODO:更改此选项以选择您正在使用的端口/引脚 // GPIOPinConfigure (GPIO_PB0_CAN1RX); GPIOPinConfigure (GPIO_PB1_CAN1TX); // //启用 GPIO 引脚上的复用功能。 以上步骤选择 //可用的备用功能。 此步骤实际上启用 //这些引脚的替代功能、而不是 GPIO。 //待办事项:更改此项以匹配您正在使用的端口/引脚 // GPIOPinTypeCAN (GPIO_PORTB_BASE、GPIO_PIN_1 | GPIO_PIN_0); // //已为 CAN 设置 GPIO 端口和引脚。 CAN 外设 //必须启用。 // SysCtlPeripheralEnable (SYSCTL_Periph_CAN1); while (!SysCtlPeripheralReady (SYSCTL_Periph_CAN1)); // //初始化 CAN 控制器 // CANInit (CAN1_base); // //设置 CAN 总线的比特率。 此函数设置 CAN 针对标称配置的//总线时序。 您可以实现更多控制 //使用函数 CANBitTimingSet()代替 CAN 总线时序 //如果需要。 //在此示例中、CAN 总线设置为500kHz。 在以下函数中、 // SysCtlClockGet ()或 ui32SysClock 的调用被用来确定 //用于为 CAN 外设计时的时钟速率。 这是可以的 //如果您知道系统时钟的值,则替换为固定值, //保存额外的函数调用。 对于某些器件、CAN 外设是 //使用固定的8MHz 时钟进行计时,而不管在哪种情况下是系统时钟 //对 SysCtlClockGet()或 ui32SysClock 的调用应替换为 // 80000。 有关 CAN 的更多信息、请参阅数据表 //外设时钟。 // CANBitRateSet (CAN1_base、ui32SysClock、50000); // //在 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_CAN1); // //启用 CAN 以进行操作。 // CANEnable (CAN1_base); // //初始化将用于发送 CAN 的消息对象 //消息。 消息将是包含一个递增的4个字节 //值。 最初它将设置为0。 // ui32MsgData = 0; sCANMessage.ui32MsgID = 1; sCANMessage.ui32MsgIDMask = 0; sCANMessage.ui32Flags = MSG_OBJ_TX_INT_ENABLE; sCANMessage.ui32MsgLen = sizeof (pui8MsgData); sCANMessage.pui8MsgData = pui8MsgData; // //输入循环以发送消息。 根据、将发送一条新消息 //秒。 4字节的消息内容将被视为 uint32_t //并每次递增1。 // char ponteiro[50]; while (1) { // //将显示消息计数和的消息打印到控制台 //正在发送的消息的内容。 // // UARTprintf ("发送消息:0x%02x %02x %02x %02x %02x"、 // pui8MsgData[0]、pui8MsgData[1]、pui8MsgData[2]、 // pui8MsgData[3]); sprintf (ponteiro、"正在发送 msg:0x%02x %02x %02x %02x\n\r"、pui8MsgData[0]、pui8MsgData[1]、pui8MsgData[2]、pui8MsgData[3]); debug_uart (ponteiro、strlen (ponteiro)); // //使用对象1发送 CAN 消息(与不一样 // CAN ID、在本例中也是1)。 此函数将导致 //要立即传输的消息。 // CANMessageSet (CAN1_base、1、&sCANMessage、MSG_OBJ_TYPE_TX); // //现在等待1秒后再继续 // SimpleDelay(); // //检查错误标志以查看是否发生错误 // if (g_bErrFlag) { //UARTprintf ("错误-电缆已连接?\n"\}); debug_uart ("错误-电缆已连接?\n"\}、strlen ("错误-电缆已连接?\n"\}); } 其他 { // //如果没有错误,则打印已发送消息的计数 // //UARTprintf ("总数=%u\n"、g_ui32MsgCount); sprintf (ponteiro、"总计数=%u\n\r\n、g_ui32MsgCount); debug_uart (ponteiro、strlen (ponteiro)); } // //递增消息数据中的值。 // ui32MsgData++; } // //返回无错误 // 返回(0); }

    已尝试示例、但仍然没有尝试。 现在、我可以看到发送了一些数据、但在传输过程中发生了一些事情、我不断得到"是否已连接电缆?" 误差。 有什么想法吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    已尝试示例、但仍然没有尝试。 现在、我可以看到发送了一些数据、但在传输过程中发生了一些事情、我不断得到"是否已连接电缆?" 误差。 有什么想法吗?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

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

    您的两个120欧姆端接电阻器在哪里? CAN 收发器的引脚6和7之间必须有终端电阻器、否则总线将无法返回隐性状态。

    有关如何设置 CAN 总线、请参阅以下信息:
    www.ti.com/.../sloa101b.pdf

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尝试过、不起作用。 当我使用示波器进行测量时、CANH 和 CANL 之间的电压差保持为零伏。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    使用电阻器进行了尝试、但没有产生任何影响。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您是否确实使用了 SN65HVD251收发器? 这些是5V 部件、您仅使用3.3V 电源供电。 使用 SN65HVD233是正确的。