您好!
我正在尝试使用 CAN 来通信两个 F28379d LaunchPad、例如 CAN_ex3_external_transmit。
我听从了其中一个线程的建议、
"在 Launchpad 中、GPIO12和 GPIO17可直接连接到 CAN 收发器。 这意味着 CANB 应在 CAN_ex3_external_transmit 代码中使用。 DEVICE_GPIO_CFG_CANRXB 的值应更改为 GPIO_17_CANRXB、DEVICE_GPIO_CFG_CANTXB 更改为 GPIO_12_CANTXB。 在第一个 Launchpad 上、您需要修改示例代码以便 CANB 将进行传输、并且您可以移除接收例程的 ISR (基本上移除与 CANB 相关的引用和函数、并将 CANA 上的引用和函数替换为 ex3示例代码上的 CANB)。 在第二个 Launchpad 上、只需删除 CANA 上的引用和函数。 ex3示例代码已经为 CANB 设置了 ISR、以便从 CAN 总线接收数据"。
相应地更新了代码、但不幸运。 请就此事项向我提供建议。
此致、
Sohail
代码如下:
对于传输:
//########################################################################################################################
//
//文件:CAN_ex3_external_transmit
//
//标题:CAN 外部发送示例
//
//! \addtogroup driver_example_list
//!
CAN-A 到 CAN-B 外部发送
//!
//! 此示例对 CAN 模块 A 和 CAN 模块 B 进行外部初始化
//! 通信。 CAN-A 模块被设置为发送"n"的递增数据
//! 到 CAN-B 模块的次数、其中"n"为 TXCOUNT 的值。
//! 当设置为触发中断服务例程(ISR)时、CAN-B 模块被设置为触发中断服务例程(ISR)
//! 接收数据。 如果传输的数据不是、则会设置错误标志
//! 匹配接收到的数据。
//!
//! 注意设备上的两个 CAN 模块都需要
//! 通过 CAN 收发器相互连接。 GPIO 将会不同
//! 一个示例。
//!
//! 要求\n 硬件
//! 一个具有两个 CAN 收发器的 C2000板
//!
//! b 外部连接\n
//! - controlCARD CANA 位于 GPIO31 (CANTXA)和 GPIO30 (CANRXA)上
//! - controlCARD CANB 位于 GPIO8 (CANTXB)和 GPIO10 (CANRXB)上
//!
//! b 监视\b 变量\n
//! - TXCOUNT -调整以设置要发送的消息数
//! - txMsgCount -发送消息数的计数器
//! -rxMsgCount-接收报文数量的计数器
//! - txMsgData -一个包含正在发送的数据的数组
//! -rxMsgData-一个包含接收到的数据的数组
//! -errorFlag-表示发生错误的标志
//!
//
//########################################################################################################################
//$TI 发行版:F2837xD 支持库 v3.05.00.00 $
//$Release Date:Thu OCT 18 15:48:42 CDT 2018 $
//版权所有:
//版权所有(C) 2013-2018 Texas Instruments Incorporated - http://www.ti.com/
//
//以源代码和二进制形式重新分发和使用,有无
//如果满足以下条件,则允许进行修改
//满足:
//
//重新分发源代码必须保留上述版权
//注意、此条件列表和以下免责声明。
//
//二进制形式的重新分发必须复制上述版权
//注意、中的条件列表和以下免责声明
//随提供的文档和/或其他材料
//分布。
//
//德州仪器公司的名称和的名称都不是
//其贡献者可用于认可或推广衍生产品
//未经特定的事先书面许可,从该软件下载。
//
//本软件由版权所有者和作者提供
//“原样”以及任何明示或暗示的保证,包括但不包括
//限于对适销性和适用性的暗示保证
//一个特定的目的是免责的。 在任何情况下、版权均不得
//所有者或贡献者应对任何直接、间接、偶然、
//特殊、典型或必然的损害(包括但不包括)
//仅限于采购替代货物或服务;
//数据或利润;或业务中断)
//责任理论,无论是合同责任、严格责任还是侵权行为
//(包括疏忽或其他)以任何方式因使用而产生
//此软件,即使已被告知可能会发生此类损坏。
//$
//########################################################################################################################
//
//包含的文件
//
#include "driverlib.h"
#include "device.h"
//
//定义
//
#define TXCOUNT 100
#define MSG_DATA_LENGTH 4.
#define TX_MSG_OBJ_ID 1.
#define RX_MSG_OBJ_ID 1.
//
//全局
//
volatile unsigned long i;
volatile uint32_t txMsgCount = 0;
volatile uint32_t rxMsgCount = 0;
volatile uint32_t errorFlag = 0;
uint16_t txMsgData[4];
uint16_t rxMsgData[4];
//
//函数原型
//
_interrupt void canbISR (void);
//
//主函
//
void main (void)
{
//
//初始化设备时钟和外设
//
device_init();
//
//初始化 GPIO 并为 CANTX/CANRX 配置 GPIO 引脚
//在模块 A 和 B 上
//
DEVICE_initGPIO();
//GPIO_setPinConfig (DEVICE_GPIO_CFG_CANRXA);
//GPIO_setPinConfig (DEVICE_GPIO_CFG_CANTXA);
GPIO_setPinConfig (GPIO_17_CANRXB);
GPIO_setPinConfig (GPIO_12_CANTXB);
//
//初始化 CAN 控制器
//
//CAN_initModule (CANA_base);
CAN_initModule (CANB_BASE);
//
//为每个模块将 CAN 总线位速率设置为500kHz
//有关如何设置的信息,请参阅驱动程序库用户指南
//更严格的计时控制。 此外、请参阅器件数据表
//了解有关 CAN 模块计时的更多信息。
//
//CAN_setBitRate (CANA_base、DEVICE_SYSCLK_FREQ、50000、16);
CAN_setBitRate (CANB_BASE、DEVICE_SYSCLK_FREQ、50000、16);
//
//在 CAN B 外设上启用中断。
//
//CAN_enableInterrupt (CANB_BASE、CAN_INT_IE0 | CAN_INT_ERROR |
// CAN_INT_STATUS);
//
//初始化 PIE 并清除 PIE 寄存器。 禁用 CPU 中断。
//
interrupt_initModule();
//
//使用指向 shell 中断的指针初始化 PIE 矢量表
//服务例程(ISR)。
//
//Interrupt_initVectorTable();
//
//启用全局中断(INTM)和实时中断(DBGM)
//
EINT;
ERTM;
//
//此示例中使用的中断被重新映射到
//此文件中的 ISR 函数。
//这在 PIE 矢量表中注册中断处理程序。
//
//中断寄存器(INT_CANB0、&CANbISR);
//
//启用 CAN-B 中断信号
//
//中断_ENABLE (INT_CANB0);
//CAN_enableGlobalInterrupt (CANB_BASE、CAN_GLOBAL_INT_CANINT0);
//
//初始化用于发送 CAN 消息的发送消息对象。
//消息对象参数:
// CAN 模块:A
//消息对象 ID 号:1.
//消息标识符:0x95555555
//消息帧:扩展
//消息类型:发送
//消息 ID 掩码:0x0
//消息对象标志:无
//消息数据长度:4字节
//
CAN_setupMessageObject (CANB_BASE、TX_MSG_OBJ_ID、0x955555、
CAN_MSG_FRAME_EXT、CAN_MSG_OBJ_TYPE_TX、0、
CAN_MSG_OBJ_NO_FLAGS、MSG_DATA_LENGTH);
//
//初始化用于接收 CAN 消息的接收消息对象。
//消息对象参数:
// CAN 模块:b.
//消息对象 ID 号:1.
//消息标识符:0x95555555
//消息帧:扩展
//消息类型:接收
//消息 ID 掩码:0x0
//消息对象标志:接收中断
//消息数据长度:4字节
//
/* CAN_setupMessageObject (CANB_BASE、RX_MSG_OBJ_ID、0x955555、
CAN_MSG_FRAME_EXT、CAN_MSG_OBJ_TYPE_RX、0、
CAN_MSG_OBJ_RX_INT_ENABLE、MSG_DATA_LENGTH);*/
//
//初始化要发送的发送消息对象数据缓冲区
//
txMsgData[0]= 0x12;
txMsgData[1]= 0x34;
txMsgData[2]= 0x56;
txMsgData[3]= 0x78;
//
//启动 CAN 模块 A 和 B 操作
//
//CAN_startModule (CANA_base);
CAN_startModule (CANB_BASE);
//
//将消息从 CAN-A 发送到 CAN-B
//
对于(I = 0;I < TXCOUNT;I++)
{
//
//检查错误标志以查看是否发生错误
//
if (错误标志)
{
asm (" ESTOP0");
}
//
//验证传输的消息数是否等于的数量
//发送新消息之前收到的消息
//
if (txMsgCount = rxMsgCount)
{
CAN_sendMessage (CANB_BASE、TX_MSG_OBJ_ID、MSG_DATA_LENGTH、
txMsgData);
txMsgCount++;
}
其他
{
errorFlag = 1;
}
//
//在继续前延迟0.25秒
//
DEVICE_DELAY_US (250000);
//
//递增发送消息数据中的值。
//
txMsgData[0]+= 0x01;
txMsgData[1]+= 0x01;
txMsgData[2]+= 0x01;
txMsgData[3]+= 0x01;
//
//如果超过一个字节、则复位数据
//
if (txMsgData[0]> 0xFF)
{
txMsgData[0]= 0;
}
if (txMsgData[1]> 0xFF)
{
txMsgData[1]= 0;
}
if (txMsgData[2]> 0xFF)
{
txMsgData[2]= 0;
}
if (txMsgData[3]> 0xFF)
{
txMsgData[3]= 0;
}
}
//
//停止应用程序
//
asm (" ESTOP0");
}
//
// CAN B ISR -当 CAN 中断为时调用的中断服务例程
//在 CAN 模块 B 上触发
//
/*_INTERRUPT void
CANBISR (空)
{
uint32_t status;
//
//读取 CAN-B 中断状态以查找中断原因
//
状态= CAN_getInterruptCase (CANB_BASE);
//
//如果原因是控制器状态中断,则获取状态
//
if (status =CAN_INT_INT0ID_STATUS)
{
//
//读取控制器状态。 这将返回状态字段
//可以指示各种错误的错误位。 错误处理
//本示例中不是为了简单起见。 请参阅
// API 文档,了解有关错误状态位的详细信息。
//读取此状态的操作将清除中断。
//
状态= CAN_getStatus (CANB_BASE);
//
//检查是否发生错误。
//
if (((status &~(CAN_STATUS_RXOK))!= CAN_STATUS_LEC_MSK)&&
((STATUS &μ~(CAN_STATUS_RXOK))!= CAN_STATUS_LEC_NONE))
{
//
//设置一个标志来指示可能发生的某些错误。
//
errorFlag = 1;
}
}
//
//检查原因是否是 CAN-B 接收报文对象1
//
否则、如果(status == RX_MSG_OBJ_ID)
{
//
//获取收到的消息
//
CAN_readMessage (CANB_BASE、RX_MSG_OBJ_ID、rxMsgData);
//
//到达这一点意味着 RX 中断发生在上
//报文对象1、报文 RX 完成。 清除
//消息目标中断。
//
CAN_clearInterruptStatus (CANB_BASE、RX_MSG_OBJ_ID);
//
//递增计数器以跟踪已有多少消息
//已收到。 在实际应用中、这可用于将标志设置为
//指示何时接收到消息。
//
rxMsgCount++;
//
//由于接收到消息,请清除所有错误标志。
//
错误标志= 0;
}
//
//如果发生意外导致中断的情况,这将对中断进行处理。
//
其他
{
//
//可以在此处执行伪中断处理。
//
}
//
//清除 CAN 中断线的全局中断标志
//
CAN_clearGlobalInterruptStatus (CANB_BASE、CAN_GLOBAL_INT_CANINT0);
//
//确认位于组9中的此中断
//
INTERRUPT_clearACKGROUP (INTERRUPT_ACK_group9);
}
*
//
//文件结束
//
用于接收数据:
//########################################################################################################################
//
//文件:CAN_ex3_external_transmit
//
//标题:CAN 外部发送示例
//
//! \addtogroup driver_example_list
//!
CAN-A 到 CAN-B 外部发送
//!
//! 此示例对 CAN 模块 A 和 CAN 模块 B 进行外部初始化
//! 通信。 CAN-A 模块被设置为发送"n"的递增数据
//! 到 CAN-B 模块的次数、其中"n"为 TXCOUNT 的值。
//! 当设置为触发中断服务例程(ISR)时、CAN-B 模块被设置为触发中断服务例程(ISR)
//! 接收数据。 如果传输的数据不是、则会设置错误标志
//! 匹配接收到的数据。
//!
//! 注意设备上的两个 CAN 模块都需要
//! 通过 CAN 收发器相互连接。 GPIO 将会不同
//! 一个示例。
//!
//! 要求\n 硬件
//! 一个具有两个 CAN 收发器的 C2000板
//!
//! b 外部连接\n
//! - controlCARD CANA 位于 GPIO31 (CANTXA)和 GPIO30 (CANRXA)上
//! - controlCARD CANB 位于 GPIO8 (CANTXB)和 GPIO10 (CANRXB)上
//!
//! b 监视\b 变量\n
//! - TXCOUNT -调整以设置要发送的消息数
//! - txMsgCount -发送消息数的计数器
//! -rxMsgCount-接收报文数量的计数器
//! - txMsgData -一个包含正在发送的数据的数组
//! -rxMsgData-一个包含接收到的数据的数组
//! -errorFlag-表示发生错误的标志
//!
//
//########################################################################################################################
//$TI 发行版:F2837xD 支持库 v3.05.00.00 $
//$Release Date:Thu OCT 18 15:48:42 CDT 2018 $
//版权所有:
//版权所有(C) 2013-2018 Texas Instruments Incorporated - http://www.ti.com/
//
//以源代码和二进制形式重新分发和使用,有无
//如果满足以下条件,则允许进行修改
//满足:
//
//重新分发源代码必须保留上述版权
//注意、此条件列表和以下免责声明。
//
//二进制形式的重新分发必须复制上述版权
//注意、中的条件列表和以下免责声明
//随提供的文档和/或其他材料
//分布。
//
//德州仪器公司的名称和的名称都不是
//其贡献者可用于认可或推广衍生产品
//未经特定的事先书面许可,从该软件下载。
//
//本软件由版权所有者和作者提供
//“原样”以及任何明示或暗示的保证,包括但不包括
//限于对适销性和适用性的暗示保证
//一个特定的目的是免责的。 在任何情况下、版权均不得
//所有者或贡献者应对任何直接、间接、偶然、
//特殊、典型或必然的损害(包括但不包括)
//仅限于采购替代货物或服务;
//数据或利润;或业务中断)
//责任理论,无论是合同责任、严格责任还是侵权行为
//(包括疏忽或其他)以任何方式因使用而产生
//此软件,即使已被告知可能会发生此类损坏。
//$
//########################################################################################################################
//
//包含的文件
//
#include "driverlib.h"
#include "device.h"
//
//定义
//
#define TXCOUNT 100
#define MSG_DATA_LENGTH 4.
#define TX_MSG_OBJ_ID 1.
#define RX_MSG_OBJ_ID 1.
//
//全局
//
volatile unsigned long i;
volatile uint32_t txMsgCount = 0;
volatile uint32_t rxMsgCount = 0;
volatile uint32_t errorFlag = 0;
uint16_t txMsgData[4];
uint16_t rxMsgData[4];
//
//函数原型
//
_interrupt void canbISR (void);
//
//主函
//
void main (void)
{
//
//初始化设备时钟和外设
//
device_init();
//
//初始化 GPIO 并为 CANTX/CANRX 配置 GPIO 引脚
//在模块 A 和 B 上
//
DEVICE_initGPIO();
//GPIO_setPinConfig (DEVICE_GPIO_CFG_CANRXA);
//GPIO_setPinConfig (DEVICE_GPIO_CFG_CANTXA);
GPIO_setPinConfig (GPIO_17_CANRXB);
GPIO_setPinConfig (GPIO_12_CANTXB);
//
//初始化 CAN 控制器
//
//CAN_initModule (CANA_base);
CAN_initModule (CANB_BASE);
//
//为每个模块将 CAN 总线位速率设置为500kHz
//有关如何设置的信息,请参阅驱动程序库用户指南
//更严格的计时控制。 此外、请参阅器件数据表
//了解有关 CAN 模块计时的更多信息。
//
//CAN_setBitRate (CANA_base、DEVICE_SYSCLK_FREQ、50000、16);
CAN_setBitRate (CANB_BASE、DEVICE_SYSCLK_FREQ、50000、16);
//
//在 CAN B 外设上启用中断。
//
//CAN_enableInterrupt (CANB_BASE、CAN_INT_IE0 | CAN_INT_ERROR |
// CAN_INT_STATUS);
//
//初始化 PIE 并清除 PIE 寄存器。 禁用 CPU 中断。
//
interrupt_initModule();
//
//使用指向 shell 中断的指针初始化 PIE 矢量表
//服务例程(ISR)。
//
interrupt_initVectorTable();
//
//启用全局中断(INTM)和实时中断(DBGM)
//
EINT;
ERTM;
//
//此示例中使用的中断被重新映射到
//此文件中的 ISR 函数。
//这在 PIE 矢量表中注册中断处理程序。
//
//中断寄存器(INT_CANB0、&CANbISR);
//
//启用 CAN-B 中断信号
//
//中断_ENABLE (INT_CANB0);
//CAN_enableGlobalInterrupt (CANB_BASE、CAN_GLOBAL_INT_CANINT0);
//
//初始化用于发送 CAN 消息的发送消息对象。
//消息对象参数:
// CAN 模块:A
//消息对象 ID 号:1.
//消息标识符:0x95555555
//消息帧:扩展
//消息类型:发送
//消息 ID 掩码:0x0
//消息对象标志:无
//消息数据长度:4字节
//
/* CAN_setupMessageObject (CANA_base、TX_MSG_OBJ_ID、0x955555、
CAN_MSG_FRAME_EXT、CAN_MSG_OBJ_TYPE_TX、0、
CAN_MSG_OBJ_NO_FLAGS、MSG_DATA_LENGTH);*
//
//初始化用于接收 CAN 消息的接收消息对象。
//消息对象参数:
// CAN 模块:b.
//消息对象 ID 号:1.
//消息标识符:0x95555555
//消息帧:扩展
//消息类型:接收
//消息 ID 掩码:0x0
//消息对象标志:接收中断
//消息数据长度:4字节
//
CAN_setupMessageObject (CANB_BASE、RX_MSG_OBJ_ID、0x955555、
CAN_MSG_FRAME_EXT、CAN_MSG_OBJ_TYPE_RX、0、
CAN_MSG_OBJ_RX_INT_ENABLE、MSG_DATA_LENGTH);
//
//初始化要发送的发送消息对象数据缓冲区
//
txMsgData[0]= 0x12;
txMsgData[1]= 0x34;
txMsgData[2]= 0x56;
txMsgData[3]= 0x78;
//
//启动 CAN 模块 A 和 B 操作
//
//CAN_startModule (CANA_base);
CAN_startModule (CANB_BASE);
//
//将消息从 CAN-A 发送到 CAN-B
//
/*for (i = 0;i < TXCOUNT;i++)
{
//
//检查错误标志以查看是否发生错误
//
if (错误标志)
{
asm (" ESTOP0");
}
//
//验证传输的消息数是否等于的数量
//发送新消息之前收到的消息
//
if (txMsgCount = rxMsgCount)
{
CAN_sendMessage (CANA_base、TX_MSG_OBJ_ID、MSG_DATA_LENGTH、
txMsgData);
txMsgCount++;
}
其他
{
errorFlag = 1;
}
//
//在继续前延迟0.25秒
//
DEVICE_DELAY_US (250000);
//
//递增发送消息数据中的值。
//
txMsgData[0]+= 0x01;
txMsgData[1]+= 0x01;
txMsgData[2]+= 0x01;
txMsgData[3]+= 0x01;
//
//如果超过一个字节、则复位数据
//
if (txMsgData[0]> 0xFF)
{
txMsgData[0]= 0;
}
if (txMsgData[1]> 0xFF)
{
txMsgData[1]= 0;
}
if (txMsgData[2]> 0xFF)
{
txMsgData[2]= 0;
}
if (txMsgData[3]> 0xFF)
{
txMsgData[3]= 0;
}
}*/
//
//停止应用程序
//
asm (" ESTOP0");
}
//
// CAN B ISR -当 CAN 中断为时调用的中断服务例程
//在 CAN 模块 B 上触发
//
_interrupt void
CANBISR (空)
{
uint32_t status;
//
//读取 CAN-B 中断状态以查找中断原因
//
状态= CAN_getInterruptCase (CANB_BASE);
//
//如果原因是控制器状态中断,则获取状态
//
if (status =CAN_INT_INT0ID_STATUS)
{
//
//读取控制器状态。 这将返回状态字段
//可以指示各种错误的错误位。 错误处理
//本示例中不是为了简单起见。 请参阅
// API 文档,了解有关错误状态位的详细信息。
//读取此状态的操作将清除中断。
//
状态= CAN_getStatus (CANB_BASE);
//
//检查是否发生错误。
//
if (((status &~(CAN_STATUS_RXOK))!= CAN_STATUS_LEC_MSK)&&
((STATUS &μ~(CAN_STATUS_RXOK))!= CAN_STATUS_LEC_NONE))
{
//
//设置一个标志来指示可能发生的某些错误。
//
errorFlag = 1;
}
}
//
//检查原因是否是 CAN-B 接收报文对象1
//
否则、如果(status == RX_MSG_OBJ_ID)
{
//
//获取收到的消息
//
CAN_readMessage (CANB_BASE、RX_MSG_OBJ_ID、rxMsgData);
//
//到达这一点意味着 RX 中断发生在上
//报文对象1、报文 RX 完成。 清除
//消息目标中断。
//
CAN_clearInterruptStatus (CANB_BASE、RX_MSG_OBJ_ID);
//
//递增计数器以跟踪已有多少消息
//已收到。 在实际应用中、这可用于将标志设置为
//指示何时接收到消息。
//
rxMsgCount++;
//
//由于接收到消息,请清除所有错误标志。
//
错误标志= 0;
}
//
//如果发生意外导致中断的情况,这将对中断进行处理。
//
其他
{
//
//可以在此处执行伪中断处理。
//
}
//
//清除 CAN 中断线的全局中断标志
//
CAN_clearGlobalInterruptStatus (CANB_BASE、CAN_GLOBAL_INT_CANINT0);
//
//确认位于组9中的此中断
//
INTERRUPT_clearACKGROUP (INTERRUPT_ACK_group9);
}
//
//文件结束
//