TI E2E™ 设计支持论坛将于 5 月 30 日至 6 月 1 日进行维护。如果您在此期间需要技术支持,请联系 TI 的客户支持中心寻求帮助。

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.

[参考译文] F28M35x Cortex M3 CA 中断和 MessageBox 问题

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/594726/f28m35x-cortex-m3-ca-interrupt-and-messagebox-issues

您好!

我在 Cortex M3上遇到了 CanInntHandler 的一些问题、我将其设置为在接收(CANRx)发出中断时调用处理程序、但 它从未调用过。 我可以在 TE 寄存器值上看到中断被创建、消息被看到和处理会导致寄存器 CAN_ES 更新位 Rxok、IF2CMD 寄存器执行 ClrIntPnd

有 CanInit 和 CanIntHandler 的 mycode

/*********
初始化硬件以接收 CAN 消息并启动
CANopen 堆栈的计时器。
输入比特率 如果
成功,以千位输出1为单位的比特率
/
unsigned char canInit (unsigned int bitrate)
{

//初始化 CAN 控制器
int ulBase = CAN0_BASE;

int iMsg;

//检查参数。
ASSERT (CANBaseValid (ulBase));

//将 CAN 控制器置于初始化状态,与之前的状态无关。 这种情况
//将控制器置于空闲状态,并允许消息对象 RAM 处于空闲状态
//已编程。

HWREG (ulBase + CAN_O_CTL)= CAN_CTL_init;
HWREG (ulBase + CAN_O_CTL)= CAN_CTL_SWR;

//等待忙位清零
while (HWREG (ulBase + CAN_O_IF1_CMD)和 CAN_IF1_CMD_BUSY)
{
}

//清除仲裁寄存器中的报文值位。 这表示
//消息无效,是一个“安全”条件,可以离开消息
//对象。 相同的 ARB reg 用于对所有报文对象进行编程。
/* HWREGH (ulBase + CAN_O_IF1_MSK)= 0;

HWREGH (ulBase + CAN_O_IF1_CMD)=(无符号字符) 0xf8;

HWREG (ulBase + CAN_O_IF1_ARB)=(int) 0x8000000 |(int) 0x00000000 |(int) 0x20000000 |(int)((int)(((int) 0和(int) 0x000007FF)<<(int) 18);
HWREG (ulBase + CAN_O_IF1_MCTL)= 0x00001080 |(int) 0x00000000 |(int) 0x00000000 |(int) 0x00000000 |(int) 8;


HWREGH (ulBase + CAN_O_IF2_MSK)= 0;

HWREGH (ulBase + CAN_O_IF2_CMD)=(无符号字符) 0xf8;

HWREG (ulBase + CAN_O_IF2_ARB)=(int) 0x8000000 |(int) 0x00000000 |(int) 0x00000000 |(int)((int)(((int) 0 &(int) 0x000007FF)<<(int) 18);
HWREG (ulBase + CAN_O_IF2_MCTL)= 0x00001080 |(int) 0x00000400 |(int) 0x00000000 |(int) 8;

//循环以编程全部32个报文对象
for (iMsg = 1;iMsg <= 16;iMsg++)
{
//等待忙位清零
while (HWREG (ulBase + CAN_O_IF1_CMD)和 CAN_IF1_CMD_BUSY)
{
}

//开始对消息对象进行编程
HWREGH (ulBase + CAN_O_IF1_CMD)= iMsg;

}
for (iMsg = 16;iMsg <= 32;iMsg++)
{
//等待 BUSY 位清零
while (HWREG (ulBase + CAN_O_IF2_CMD)& CAN_IF2_CMD_BUSY)
{
}

//开始对消息对象
HWREGH (ulBase + CAN_O_IF2_CMD)进行编程;
}
* iMsg = iMsg
HWREGH (ulBase + CAN_O_IF1_CMD + 2)=(CAN_IF1_CMD_WR_RD | CAN_IF1_CMD_ARB |
CAN_IF1_CMD_CONTROL)>> 16;
HWREG (ulBase + CAN_O_IF1_ARB)= 0;
HWREG (ulBase + CAN_O_IF1_MCTL)= 0x1088;

HWREGH (ulBase + CAN_O_IF2_CMD + 2)=(CAN_IF2_CMD_WR_RD | CAN_IF2_CMD_ARB |
CAN_IF1_CMD_CONTROL)>> 16;
HWREG (ulBase + CAN_O_IF2_ARB)= 0;
HWREG (ulBase + CAN_O_IF2_MCTL)= 0x1488;

//循环以编程全部32个报文对象
for (iMsg = 1;iMsg <= 16;iMsg++)
{
//等待忙位清零
while (HWREG (ulBase + CAN_O_IF1_CMD)和 CAN_IF1_CMD_BUSY)
{
}

//开始对消息对象进行编程
HWREGH (ulBase + CAN_O_IF1_CMD)= iMsg;

}
for (iMsg = 16;iMsg <= 32;iMsg++)
{
//等待 BUSY 位清零
while (HWREG (ulBase + CAN_O_IF2_CMD)& CAN_IF2_CMD_BUSY)
{
}

//开始对消息对象进行编程
HWREGH (ulBase + CAN_O_IF2_CMD)= iMsg;
}

//确保更新的中断和新数据标志
//消息对象。
HWREGH (ulBase + CAN_O_IF1_CMD + 2)=(CAN_IF1_CMD_CLRINTPND)>> 16;
HWREGH (ulBase + CAN_O_IF2_CMD + 2)=(CAN_IF2_CMD_CLRINTPND)>> 16;

//循环以编程全部32个报文对象
for (iMsg = 1;iMsg <= 16;iMsg++)
{
//等待忙位清零
while (HWREG (ulBase + CAN_O_IF1_CMD)和 CAN_IF1_CMD_BUSY)
{
}

//开始对消息对象进行编程
HWREGH (ulBase + CAN_O_IF1_CMD)= iMsg;

}
for (iMsg = 16;iMsg <= 32;iMsg++)
{
//等待 BUSY 位清零
while (HWREG (ulBase + CAN_O_IF2_CMD)& CAN_IF2_CMD_BUSY)
{
}

//开始对消息对象进行编程
HWREGH (ulBase + CAN_O_IF2_CMD)= iMsg;
}


//等待忙位清零
while (HWREG (ulBase + CAN_O_IF1_CMD)和 CAN_IF1_CMD_BUSY)
{
}
HWREGH (ulBase + CAN_O_IF1_CMD)= 0x87;

//等待 BUSY 位清零
while (HWREG (ulBase + CAN_O_IF2_CMD)& CAN_IF2_CMD_BUSY)
{
}
HWREGH (ulBase + CAN_O_IF2_CMD)= 0x17;


//确认任何挂起状态中断。
HWREG (ulBase + CAN_O_ES);


//设置可以根据 M3/主子系统时钟计时
CANClkSourceSelect (CAN0_BASE、CAN_CLK_M3);

//设置 CAN 总线的比特率。 此函数设置 CAN
针对标称配置的//总线时序。 您可以实现更多控制
//使用函数 CANBitTimingSet()代替 CAN 总线时序
//如果需要。
//在此示例中、CAN 总线设置为500kHz。 在以下函数中、
//对 SysCtlClockGet ()的调用用于确定该时钟速率
//用于为 CAN 外设计时。 可将其替换为
//固定值如果您知道系统时钟的值,则节省额外的值
//函数调用。 对于某些器件、CAN 外设采用固定计时
// 8MHz,无论在哪种情况下调用的系统时钟如何
// SysCtlClockGet ()应替换为80000。 请查阅数据
//表以了解有关 CAN 外设计时的更多信息。
CANBitRateSet (CAN0_BASE、SysCtlClockGet (SYSTEM_CLOCK_SPEED)、比特率);

//在 CAN 外设上启用中断。 此示例使用静态
//分配中断处理程序,表示处理程序的名称
//位于启动代码的矢量表中。 如果您想使用动态的
//分配矢量表,然后还必须调用 CANIntRegister()
//此处。
// CANIntRegister (CAN0_BASE、CANIntHandler);// if using dynamic vectors
CANIntEnable (CAN0_BASE、CAN_INT_MASTER /*| CAN_INT_ERROR | CAN_INT_STATUS*/);

//在 RAM 矢量表中注册中断处理程序
IntRegister (INT_CAN0INT0、CANIntHandler);
IntRegister (INT_CAN0INT1、CANIntHandler);

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

//禁用测试模式并选择外部环回
HWREG (CAN0_BASE + CAN_O_CTL)|=(0 | CAN_CTL_IE0 | CAN_CTL_IE1);//禁用测试模式
HWREG (CAN0_BASE + CAN_O_TEST)= 0;//禁用外部环回模式

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

返回1;
} 
void CANIntHandler (void)
{
unsigned long ulStatus;
消息 m =消息初始化程序;//包含 CAN 消息;

//读取 CAN 中断状态以查找中断原因
ulStatus = CANIntStatus (CAN0_BASE、CAN_INT_STS_CAUST);
x=ulStatus;
//如果原因是控制器状态中断,则获取状态
if (ulStatus = CAN_INT_INT0ID_STATUS)
{
//读取控制器状态。 这将返回状态字段
//可以指示各种错误的错误位。 错误处理
//本示例中不是为了简单起见。 请参阅
// API 文档,了解有关错误状态位的详细信息。
//读取此状态的操作将清除中断。 如果
// CAN 外设未与其它 CAN 器件连接到 CAN 总线
//存在,则会发生错误,并在中指示
//控制器状态。
ulStatus = CANStatusGet (CAN0_BASE、CAN_STS_CONTROL);

//设置一个标志来指示可能发生的某些错误。
G_bErrFlag = 1;
}

//检查原因是否是我们正在使用的消息对象1
//发送消息。
否则(((ulStatus > 0)&&(ulStatus <= 32))
{
//到达这一点意味着 TX 中断发生在上
//消息对象1、消息 TX 完成。 清除
//消息目标中断。
CANIntClear (CAN0_BASE、1);

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


if (canPreReceive (ulStatus、&m))(可预接收器(ulStatus、&m)))
{
canreceive(&M);
}


//由于消息已发送,请清除所有错误标志。
G_bErrFlag = 0;
}

//否则,发生意外导致中断的情况。 这应该是
//永远不会发生。
其他
{
//此处可以处理伪中断
。}
} 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    没有人可以帮助我?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    请帮帮我
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您能否检查中断是否在 NVIC 级别启用? NVIC 具有用于设置中断标志和调试的寄存器、可帮助您独立于 CAN 功能检查系统控制设置。 如果您能够生成中断并使用 NVIC 强制标志位获取 ISR、则 CAN 中断使能设置必须存在一些错误。

    希望这对您有所帮助。

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

    我能够解决这样一个事实、即它没有调用 CanIntHandler 函数(我曾在 commentaru 中使用过 CAN_INT_Status、该函数曾用于进入) 现在、我遇到了状态始终等于0x8000的问题、但我不知道为什么我认为它、因为我在设置电子邮件箱时出错、但我没有找到任何这样的示例。 此外、即使消息被处理、寄存器 CAN_INT 仍不会更新?????

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

    再次上升

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    再次上升
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    如果您在 CAN INT 寄存器中看到0x8000、则错误和状态寄存器(CAN ES)不是0x7、并且可能显示您所遇到错误的详细信息。

    有关这些寄存器的更多详细信息、请参阅 TRM:www.ti.com/lit/SPRUH22G

    此致
    Chris