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.
您好!
我正在尝试使用 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
//!
//
//包含的文件
//
#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
//!
//
//包含的文件
//
#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);
}
//
//文件结束
//
您好、Sohail、
在发送节点中:
-删除以下行:
if (错误标志)
{
asm (" ESTOP0");
}
-删除以下行
if (txMsgCount = rxMsgCount)
{
CAN_sendMessage (CANB_BASE、TX_MSG_OBJ_ID、MSG_DATA_LENGTH、
txMsgData);
txMsgCount++;
}
其他
{
errorFlag = 1;
}
并替换为:
CAN_sendMessage (CANB_BASE、TX_MSG_OBJ_ID、MSG_DATA_LENGTH、
txMsgData);
上述操作使第一个节点严格传输数据、而不对接收到的数据执行任何错误检查(因为您正在通过禁用中断来删除接收部分)。
在接收节点中:
通过取消注释以下行启用中断:
CAN_enableInterrupt (CANB_BASE、CAN_INT_IE0 | CAN_INT_ERROR |
CAN_INT_STATUS);
INTERRUPT_REGTER (INT_CANB0、&CANbISR);
INTERRUPT_ENABLE (INT_CANB0);
CAN_enableGlobalInterrupt (CANB_BASE、CAN_GLOBAL_INT_CANINT0);
成功发送/接收 CAN 帧后、接收节点中的代码将转至 CAN ISR 例程 canbISR 以进行帧错误检查和数据解析。 然后、您可以在 CCS 的 Expressions 窗口中添加变量 rxMsgData、并在事务成功时看到接收到的数据递增。
希望这对您有所帮助。
此致、
Joseph
您好、Joseph、
正如您提到的、我更新了这些更改、并尝试了 CAN 通信仍然无法获取数据。
我连接了各自电路板的 CANH、CANL 和接地。
以下是我的更新接收器代码:
//########################################################################################################################
//
//文件:CAN_ex3_external_transmit
//
//标题:CAN 外部发送示例
//
//! \addtogroup driver_example_list
//!
//!
//! 此示例对 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 矢量表中注册中断处理程序。
//
INTERRUPT_REGTER (INT_CANB0、&CANbISR);
//
//启用 CAN-B 中断信号
//
INTERRUPT_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);
}
//
//文件结束
//
此致、
Sohail
您好、Sohail、
在接收器代码中、看起来最后一条语句以函数调用 CAN_startModule (CANB_BASE)结束;。 您能否在此行后面添加 while (1);语句以使 CPU 保持运行? 您还能在内部 ISR 函数 canbISR()中添加 ESTOP0;语句吗? 添加 ESTOP0将强制程序在 ISR 处停止-这是一种了解节点是否接收到有效消息以及是否生成了适当中断的方法。
此致、
Joseph
您好、Joseph、
我更新了代码。 接收器代码未正常运行、并且继续显示错误"break at address "0x3fe493"、no debug information available、or outside of program code"。
您能否建议如何解决此问题并进行 CAN 通信?
接收器代码:
//########################################################################################################################
//
//文件:CAN_ex3_external_transmit
//
//标题:CAN 外部发送示例
//
//! \addtogroup driver_example_list
//!
//!
//! 此示例对 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 矢量表中注册中断处理程序。
//
INTERRUPT_REGTER (INT_CANB0、&CANbISR);
//
//启用 CAN-B 中断信号
//
INTERRUPT_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);
while (1);
//
//将消息从 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++;
ESTOP0;
//
//由于接收到消息,请清除所有错误标志。
//
错误标志= 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
//!
//
//包含的文件
//
#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;
}*/
CAN_sendMessage (CANB_BASE、TX_MSG_OBJ_ID、MSG_DATA_LENGTH、
txMsgData);
//
//在继续前延迟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);
}
*
//
//文件结束
//
此致、
Sohail
您好、Sohail、
遗憾的是、代码附件已经很长、很难解密哪些行被注释掉或哪些行被缠绕。 我建议您将来必须插入代码、请使用该功能 (Syntax荧 光笔)、因为它使代码更易于理解。
根据您对程序计数器"0x3fe493"的描述 、这表示程序意外分支。 请检查您的所有设置(时钟、电源、收发器连接等)是否正确。
请尝试以下代码、而不是调试您的代码。 它使用 CANB 来接收外部 CAN 帧。 此外、请务必相应地修改代码、以便为连接到收发器的 CANTXB 和 CANRXB 引脚使用正确的 GPIO 通道。 我已经签出了下面的代码、它适用于200MHz 的 SYSCLK 设置和500Kbps 的 CAN 位速率。 这源自同一外部发送示例。
########################################################################################################################## // ////文件:CAN_ex3_external_transmit。c // //标题:CAN 外部传输示例 // ! \addtogroup driver_example_list //!CAN-A 到 CAN-B 外部发送
//! //! 此示例初始化 CAN 模块 A 和 CAN 模块 B 的外部 //! 通信。 CAN-A 模块被设置为传输"n"的递增数据 //! 到 CAN-B 模块的次数、其中"n"为 TXCOUNT 的值。 //! CAN-B 模块设置为在 //! 接收数据。 如果传输的数据不 是//! 匹配接收到的数据。 //! //! 注意设备上的两个 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.08.00.00 $ //$发行 日期:Mon Dec 23 17:32:30 IST 2019 $ //版权所有: //版权所有(C) 2013-2019德州仪器(TI)公司- 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 // Globals // volatile unsigned long i; volatile uint32_t txMsgCount = 0; volatile uint32_t rxMsgCount = 0; volatile uint32_t errorFlag = 0; uint16_t MstxgData[4]; uint16_t rxMsgData[4]; // ISR 函数(void);//函数 rxbvoid // CAN-B 的接收中断 // CAN-A 无发送中断 // // Main // void main (void) { // //初始化设备时钟和外设 // device_init(); // //初始化 GPIO 并为 CANTX/CANRX 配置 GPIO 引脚 //在模块 A 和 B 上。device.h 文件可能需要修改为 //在电路板中反映所选的 GPIO 引脚。 // DEVICE_initGPIO(); GPIO_setPinConfig (GPIO_13_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、20); CAN_setBitRate (CANB_BASE、DEVICE_SYSCLK_FREQ、50000、20); // //在 CAN B 外设上启用中断。 //启用 Int.line0、错误和状态更改中断 // 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 矢量表中注册中断处理程序。 // INTERRUPT_REGTER (INT_CANB0、&CANbISR); // //启用 CAN-B 中断信号 // INTERRUPT_ENABLE (INT_CANB0); // //设置 CAN_GLB_INT_EN 寄存器中的 GLBINT0_EN 位 // CAN_enableGlobalInterrupt (CANB_BASE、CAN_GLOBAL_INT_CANINT0); // //初始化用于接收 CAN 消息的接收消息对象。 //消息对象参数: // CAN 模块:B // 消息对象标识号:1. // 消息标识符:0x95555555 // 消息帧:扩展 // 消息类型:接收 // 消息 ID 掩码:0x0 // 报文对象标志:接收中断 // 消息数据长度:4字节 // CAN_setupMessageObject (CANB_BASE、RX_MSG_OBJ_ID、0x1FFFFFFF、 CAN_MSG_FRAME_EXT、CAN_MSG_OBJ_TYPE_RX、0、 CAN_MSG_OBJ_RX_INT_ENABLE、MSG_DATA_LENGTH); // //启动 CAN 模块 A 和 B 操作 // CAN_startModule (CANB_BASE); while (1); } // CAN B ISR -当中断为 //时调用中断服务例程 在 CAN 模块 B 上触发。每个 //将执行两次 接收到帧。 // 第一次更改状态;第二次接收邮箱。 // _interrupt void canbISR (void) { uint32_t status; // //读取 CAN-B 中断状态(在 CAN_INT 寄存器中)以找到 //中断原因 // 状态= CAN_getInterruptCase (CANB_BASE); // //如果原因是控制器状态中断,则获取状态。 //在每次 ISR 执行的第一次迭代期间、状态= 0x8000、 //这就是 CAN_ES!= 0x07。 // if (status =CAN_INT_INT0ID_STATUS) { // //读取控制器状态。 这将返回状态字段 //可以指示各种错误的错误位。 错误处理 //本示例中不是为了简单起见。 请参阅 // API 文档,了解有关错误状态位的详细信息。 //读取此状态的操作将清除中断。 // 状态= CAN_getStatus (CANB_BASE);//返回 CAN_ES 值。 // //现在状态= 0x00000010,表示 RxOK。 // // //检查是否发生错误。 // if (((status &~(CAN_STATUS_RXOK))!= CAN_STATUS_LEC_MSK)&& ((STATUS &μ~(CAN_STATUS_RXOK))!= CAN_STATUS_LEC_NONE)) { // //设置一个标志来指示可能发生的某些错误。 // errorFlag = 1; } } // //检查原因是否是 CAN-B 接收报文对象1。 将被跳过 //在每次 ISR 执行的第一次迭代中 // 否则、如果(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++; // //由于接收到消息,请清除所有错误标志。 // errorFlag = 0; } // //如果发生意外导致中断的情况,这将对中断进行处理。 // 其他 { // //可以在此处执行伪中断处理。 // } // jc -添加此 ESTOP0是为了使程序能够分支到 ISR 并检查内容 CAN_ES 寄存器的//、特别是最后一个错误代码(LEC) ESTOP0; // //清除 CAN 中断线的全局中断标志 // CAN_clearGlobalInterruptStatus (CANB_BASE、CAN_GLOBAL_INT_CANINT0); // //确认位于组9中的此中断 // interrupt_clearACKGroup (interrupt_ack_group9); } // //文件结束 //
此致、
Joseph
您好、Joseph、
"CAN_ex3_external_transmit "正在 Device_Init()中的函数"sysctl_delay()中中断。
但是、我 尝试对"CAN_EXTERNAL_Transmit "代码进行相同的更改 、 并且 CAN 通信工作正常。
感谢你们的帮助!!
此致、
Sohail
您好、Sohail、
您的代码可能不允许调用 SYSCTL_DELAY()的足够的延时时间,但您似乎有一个 CAN 接收代码的替代解决方案。 我将暂时将此线程标记为关闭、但如果您决定调试延迟代码的原始问题、请告诉我、并了解我们如何为您提供帮助。
此致、
Joseph