Thread 中讨论的其他器件:controlSUITE
您好!
我尝试使用示例代码进行 CAN 通信
C:\ti\controlSUITE\device_support\f2807x\v180\F2807x_examples_CPU1\CAN_loopback_interrupts
我面临2个问题
1。
我将其保持在外部回送模式并更改其 GPIO 引脚、但将 GPIO31-CANTXA 更改为 GPIO31以外的其他内容、例如 GPIO_SetupPinMux (32、GPIO_MUX_CPU1、1)、将发生错误、 我发现发生错误的点是 ulStatus &~(CAN_ES_TXOK | CAN_ES_RXOK)== 5、这有什么问题?
2.
我删除了外部回送模式并将其更改为 CAN 通信。 对 HWREG (CANA_base + CAN_O_CTL)进行注释|= CAN_CTL_TEST;HWREG (CANA_base + CAN_O_TEST)= CAN_TEST_EXL;
将 GPIO 设置更改为 GPIO_SetupPinMux (70、GPIO_MUX_CPU1、6);
// GPIO31-CANTXA
GPIO_SetupPinMux (71、GPIO_MUX_CPU1、6);
GPIO_SetupPinOptions (70、GPIO_INPUT、GPIO_异 步);
GPIO_SetupPinOptions (71、GPIO_OUTPUT、GPIO_PushPull);
我可以发送消息,但仍然无法接收消息。 我是否错过了什么?
完整代码如下:
//######################################################################################################################
//文件:CAN_loopback_interrupts.c
//标题:演示基本 CAN 设置和使用的示例。
//
//! addtogroup cpu01_example_list
//!
具有中断的 CAN 外部环回(CAN_LOOP_INTERRUPTS)
//!
//! 此示例显示了 CAN 用于发送和接收的基本设置
//! CAN 总线上的消息。 CAN 外设配置为发送
//! 具有特定 CAN ID 的消息。 然后根据传输一条消息
//! 其次、使用简单的延迟环路进行计时。 发送的消息是
//! 包含递增模式的4字节消息。 CAN 中断
//! 处理程序用于确认消息传输并计算数量
//! 已发送的消息。
//!
//! 此示例将 CAN 控制器设置为外部环回测试模式。
//! 发送的数据在 CAN0TX 引脚上可见、可通过接收
//! 适当的邮箱配置。
//!
//! 此示例使用以下中断处理程序:\n
//! - INT_CANA0 - CANIntHandler
//!
//
//######################################################################################################################
//$TI 发行版:F2807x 支持库 v180美元
//$Release Date:星期五11月6日16:33:02 CST 2015 $
//版权所有:版权所有(C) 2014-2015 Texas Instruments Incorporated -
// http://www.ti.com/ 保留所有权利$
//######################################################################################################################
#include "F28x_Project.h"//设备头文件和示例 include 文件
#include
#include
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "inc/hw_ca.h"
#include "driverlib/CAN.h"
//
//跟踪 TX 中断次数的计数器
//发生,它应与发送的 TX 消息数匹配。
//
volatile unsigned long g_ulTxMsgCount = 0;
volatile unsigned long g_ulRxMsgCount = 0;
int i;
//unsigned long u32CanAErrorStatus;
//unsigned long uCanaErrFlag;
//
//指示发生了某些传输错误的标志。
//
volatile unsigned long g_BErrFlag = 0;
tCANMsgObject sTXCANMessage;
tCANMsgObject sRXCANMessage;
unsigned char ucTXMsgData[8]={0x00、0x00、0x00、0x00、0x00、 0x00、0x00、0x00};
unsigned char ucRXMsgData[8];
//unsigned long u32CntTXMsgData = 0x12345678;
//
//此函数是 CAN 外设的中断处理程序。 它会进行检查
//查找中断原因,并保留所有消息的计数
//已传输。
//
中断无效
CANIntHandler (空)
{
unsigned long ulStatus;
//读取 CAN 中断状态以查找中断原因
ulStatus = CANIntStatus (CANA_base、CAN_INT_STS_Cause);
//如果原因是控制器状态中断,则获取状态
if (ulStatus = CAN_INT_INT0ID_STATUS)
{
//读取控制器状态。 这将返回状态字段
//可以指示各种错误的错误位。 错误处理
//本示例中不是为了简单起见。 请参阅
// API 文档,了解有关错误状态位的详细信息。
//读取此状态的操作将清除中断。 如果
// CAN 外设未与其它 CAN 器件连接到 CAN 总线
//存在,则会发生错误,并在中指示
//控制器状态。
ulStatus = CANStatusGet (CANA_base、CAN_STS_CONTROL);
//检查是否发生错误。
if (((ulStatus &~(CAN_ES_TXOK | CAN_ES_RXOK))!= 7)&&
((ulStatus &~(CAN_ES_TXOK | CAN_ES_RXOK))!= 0)){
//设置一个标志来指示可能发生的某些错误。
G_bErrFlag = 1;
}
}
//检查原因是否是我们正在使用的消息对象1
//发送消息。
否则、如果(ulStatus = 1)
{
//到达这一点意味着 TX 中断发生在上
//消息对象1、消息 TX 完成。 清除
//消息目标中断。
CANIntClear (CANA_base、1);
//递增计数器以跟踪已有多少消息
//已发送。 在实际应用中、这可用于将标志设置为
//指示何时发送消息。
G_ulTxMsgCount++;
//由于消息已发送,请清除所有错误标志。
G_bErrFlag = 0;
}
//检查原因是否是我们正在使用的消息对象1
//接收消息。
否则、如果(ulStatus = 2)
{
//获取收到的消息
CANMessageGet (CANA_base、2、&sRXCANMessage、true);
//到达这一点意味着 TX 中断发生在上
//消息对象1、消息 TX 完成。 清除
//消息目标中断。
CANIntClear (CANA_base、2);
//递增计数器以跟踪已有多少消息
//已发送。 在实际应用中、这可用于将标志设置为
//指示何时发送消息。
G_ulRxMsgCount++;
//由于消息已发送,请清除所有错误标志。
G_bErrFlag = 0;
}
//否则,发生意外导致中断的情况。 这应该是
//永远不会发生。
其他
{
//可以在此处执行伪中断处理。
}
//canaRegs.CAN_GLB_INT_CLR.bit.INT0_FLG_CLR = 1;
CANGLALIntClear (CANA_base、CAN_GLB_INT_CANINT0);
PieCtrlRegs.PIEACX.ALL = PIEACK_group9;
}
//
//配置 CAN 并输入循环以传输周期性 CAN 消息。
//
int main (空)
{
//步骤1. 初始化系统控制:
// PLL、安全装置、启用外设时钟
//此示例函数位于 F2807x_sysctrl.c 文件中。
InitSysCtrl();
//步骤2. 初始化 GPIO:
//此示例函数位于 F2807x_GPIO.c 文件和中
//说明了如何将 GPIO 设置为其默认状态。
InitGpio();
//GPIO 73 - XCLKOUT
//GPIO_SetupPinMux (73、GPIO_MUX_CPU1、3);
//GPIO_SetupPinOptions (73、GPIO_OUTPUT、GPIO_PushPull);//-> SYSCLOCK/8 = 25MHz
//GpioCtrlRegs.GPAMUX1.bit.GPIO10=0;
//GpioCtrlRegs.GPADIR.bit.GPIO10=0;
//GpioDataRegs.GPADAT.bit.GPIO10=0;
//GPIO30 - CANRXA
GPIO_SetupPinMux (70、GPIO_MUX_CPU1、6);
//GPIO31 - CANTXA
GPIO_SetupPinMux (71、GPIO_MUX_CPU1、6);
GPIO_SetupPinOptions (70、GPIO_INPUT、GPIO_异 步);
GPIO_SetupPinOptions (71、GPIO_OUTPUT、GPIO_PushPull);
//GPIO30 - CANRXB
//GPIO_SetupPinMux (73、GPIO_MUX_CPU1、6);
//GPIO31 - CANTXB
//GPIO_SetupPinMux (72、GPIO_MUX_CPU1、6);
//GPIO_SetupPinOptions (73、GPIO_INPUT、GPIO_异 步);
//GPIO_SetupPinOptions (72、GPIO_OUTPUT、GPIO_PushPull);
//初始化 CAN 控制器
CANInit (CANA_base);
//CANInit (CANB_BASE);
//设置可以从 PLL 输出时钟计时
CANClkSourceSelect (CANA_base、0);// 500kHz CAN 时钟*
//设置 CAN 总线的比特率。 此函数设置 CAN
针对标称配置的//总线时序。 您可以实现更多控制
//使用函数 CANBitTimingSet()代替 CAN 总线时序
//如果需要。
//在此示例中、CAN 总线设置为500kHz。 在以下函数中、
//对 SysCtlClockGet ()的调用用于确定该时钟速率
//用于为 CAN 外设计时。 可将其替换为
//固定值如果您知道系统时钟的值,则节省额外的值
//函数调用。 对于某些器件、CAN 外设采用固定计时
// 8MHz,无论在哪种情况下调用的系统时钟如何
// SysCtlClockGet ()应替换为80000。 请查阅数据
//表以了解有关 CAN 外设计时的更多信息。
CANBitRateSet (CANA_base、120000000、50000);
//CANBitRateSet (CANA_base、120000000、1000000);
//在 CAN 外设上启用中断。 此示例使用静态
//分配中断处理程序,表示处理程序的名称
//位于启动代码的矢量表中。 如果您想使用动态的
//分配矢量表,然后还必须调用 CANIntRegister()
//此处。
//CANIntEnable (CANA_base、CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);
//步骤3. 清除所有中断并初始化 PIE 矢量表:
//禁用 CPU 中断
Dint;
//将 PIE 控制寄存器初始化为默认状态。
//默认状态为禁用所有 PIE 中断和标志
//被清除。
//此函数位于 F2807x_PIECTRL.c 文件中。
InitPieCtrl();
//禁用 CPU 中断并清除所有 CPU 中断标志:
IER = 0x0000;
IFR = 0x0000;
//使用指向 shell 中断的指针初始化 PIE 矢量表
//服务例程(ISR)。
//这将填充整个表,即使是中断也是如此
//在本例中未使用。 这对于调试很有用。
//可以在 F2807x_DefaultIsr.c 中找到 shell ISR 例程
//此函数位于 F2807x_PieVect.c 中
InitPieVectTable();
//此示例中使用的中断被重新映射到
//此文件中的 ISR 函数。
//在 RAM 矢量表中注册中断处理程序
EALLOW;
PieVectTable.CANA0_INT = CANIntHandler;
EDIS;
//在处理器(PIE)上启用 CAN 中断。
PieCtrlRegs.PIEIER9.bit.INTx5 = 1;
IER |= 0x0100;/* M_INT9 */
EINT;
//启用测试模式并选择外部环回
//HWREG (CANA_base + CAN_O_CTL)|= CAN_CTL_TEST;
//HWREG (CANA_base + CAN_O_TEST)= CAN_TEST_EXL;
//启用 CAN 以进行操作。
CANEnable (CANA_base);
//CANEnable (CANB_BASE);
CANGLALIntEnable (CANA_base、CAN_GLB_INT_CANINT0);
//初始化将用于发送 CAN 的消息对象
//消息。 消息将是包含一个递增的4个字节
//值。 最初它将设置为0x12345678。
//ucTXMsgData[0]=(u32CntTXMsgData>>24)& 0xFF;
//ucTXMsgData[1]=(u32CntTXMsgData>16)和0xFF;
//ucTXMsgData[2]=(u32CntTXMsgData>>8)和0xFF;
//ucTXMsgData[3]=(u32CntTXMsgData)& 0xFF;
sTXCANMessage.ui32MsgID = 1;// CAN 消息 ID -使用1
sTXCANMessage.ui32MsgIDMask = 0;// TX 无需掩码
sTXCANMessage.ui32Flags = MSG_OBJ_TX_INT_ENABLE;//在 TX 上启用中断
sTXCANMessage.ui32MsgLen = sizeof (ucTXMsgData);//消息大小为8
sTXCANMessage.pucMsgData = ucTXMsgData;// ptr 至消息内容
//初始化将用于接收 CAN 的消息对象
//消息。
*(unsigned long *) ucRXMsgData = 0;
sRXCANMessage.ui32MsgID = 1;// CAN 消息 ID -使用1
sRXCANMessage.ui32MsgIDMask = 0;// TX 无需掩码
sRXCANMessage.ui32Flags = MSG_OBJ_RX_INT_ENABLE;//MSG_OBJ_USE_EXT_FILTER | MSG_OBJ_EXDED_ID;//启用 RX 上的中断
sRXCANMessage.ui32MsgLen = sizeof (ucRXMsgData);//消息大小为8
sRXCANMessage.pucMsgData = ucRXMsgData;// ptr 至消息内容
//设置用于接收消息的消息对象
CANMessageSet (CANA_base、2、&sRXCANMessage、MSG_OBJ_TYPE_RX);
//使用对象1发送 CAN 消息(与不一样
// CAN ID、在本例中也是1)。 此函数将导致
//要立即传输的消息。
ucTXMsgData[0]= 0x12;
ucTXMsgData[1]= 0x34;
ucTXMsgData[2]= 0x56;
ucTXMsgData[3]= 0x78;
//输入循环以发送消息。 根据、将发送一条新消息
//秒。 4字节的消息内容将被视为无符号
// long 并每次递增1。
for (;;)
{
//检查错误标志以查看是否发生错误
if (g_bErrFlag)
{
asm (" ESTOP0");
}
if (g_ulTxMsgCount = g_ulRxMsgCount){
CANMessageSet (CANA_base、1、&sTXCANMessage、MSG_OBJ_TYPE_TX);
}否则{
//g_BErrFlag = 1;
}
//现在等待1秒后再继续
DELAY_US (1000*1000);
//递增发送消息数据中的值。
ucTXMsgData[0]+= 0x01;
ucTXMsgData[1]+= 0x01;
ucTXMsgData[2]+= 0x01;
ucTXMsgData[3]+= 0x01;
}
}
