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.

[参考译文] TMS320F28075:CAN 邮箱初始化问题

Guru**** 2539500 points
Other Parts Discussed in Thread: C2000WARE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/609721/tms320f28075-can-mailbox-initialization-problem

器件型号:TMS320F28075
主题中讨论的其他器件:C2000WARE


您好!
我正在尝试在嵌入式系统上开发 CANopen 库、但我遇到了 CAN 控制器的一些问题。
我将 CCS 6.1.00022与 C 编译器 TI v15.12.4.LTS 搭配使用。

我从 C2000Ware_1_00_01_00示例项目(C2000Ware_1_00_01_00\driverlib\f2807x\examples\cpu1\can_ex3_external_transmit)和驱动程序(C2000Ware_1_00_01_driverlib\f2807x\driver\can\ex3_ex3_transmit)构建了项目"CAN"。

我稍微修改了主函数、以初始化我的硬件并通过 CAN B 模块接收和发送消息(CAN A 模块未使用)。 您可以在该帖子的底部看到我的代码。 我没有更改 CAN 驱动程序函数和 cannbISR 中断例程。

我使用邮箱2接收消息(RX 邮箱)、使用邮箱1发送消息(TX 邮箱)。

我用500kHz 的波特率将我的系统连接到 CANopen 主器件、并插入 CAN 分析器来监听消息。

当程序运行时、我看到两个问题。


问题1 -邮箱配置问题
如果我在初始化步骤后暂停程序(例如在行 CycleCounter++上)、我会找到以下值

CAN_mvL_21 = 0x800003.

这意味着邮箱1、2和32被启用。

但是我从未启用邮箱32。

此外、如果我观察从地址0x4B000开始的 RAM 区域、我会看到范围0x4B000-0x4B01F (RAM 消息对象32)中的字和范围0x4B040-0x4B05F (RAM 消息对象2)中的字具有相同的配置。
这意味着邮箱2和邮箱32具有相同的配置。

但我从未初始化邮箱32。


问题2 -发送消息
每次我通过 CAN_sendMessage 发送一条消息时、CAN 分析仪都会检测到两条消息:

- ID 为0x581且数据为0x11223344的消息(正确);
- ID 为0x345的 RTR 消息(不正确);

不应发送 RTR 消息。
发送到 TX 邮箱1的命令似乎也会触发邮箱2或32上的传输。 因为它们都是 RX 邮箱、所以会发送一条 RTR 消息、而不是一条数据消息。

但是、我从未在邮箱2或32上触发过传输。


权变措施(可能...)
我注意到、C2000Ware CAN 驱动程序对 CAN 控制器寄存器进行32位和16位访问、但在此问题中(e2e.ti.com/.../2133415 Hareesh 报告了以下注意事项:
' CAN 模块使用一个特殊的寻址方案来支持字节访问。 建议使用 HWREG_BP ()宏(使用__byte_peripheral_32 ()内在函数)仅使用对 CAN 寄存器的32位访问。 如果要使用16位访问、低16位应写入寄存器的地址、高16位应写入寄存器的地址加2。" (另一个相关问题是以下 e2e.ti.com/.../2141528

因此、我修改了驱动程序函数 CAN_setupMessageObject、替换了这些行

 //
 //写出寄存器以编程报文对象。
 //
 HWREG_BP (base + CAN_O_IF1CMD)= cmdMaskReg;
 HWREG_BP (base + CAN_O_IF1MSK)= maskReg;
 HWREG_BP (base + CAN_O_IF1ARB)= arbReg;
 HWREG_BP (base + CAN_O_IF1MCTL)= msgCtrl;

 //
 //将数据传输到消息对象 RAM
 //
 HWREGH (base + CAN_O_IF1CMD)= Objid & CAN_IF1CMD_MSG_NUM_M;

进行通信       
      
   //
   //写出寄存器以编程报文对象。
   //
   HWREG_BP (base + CAN_O_IF1MSK)= maskReg;
   HWREG_BP (base + CAN_O_IF1ARB)= arbReg;
   HWREG_BP (base + CAN_O_IF1MCTL)= msgCtrl;

   //
   //将数据传输到消息对象 RAM
   //
   HWREG_BP (base + CAN_O_IF1CMD)= cmdMaskReg |(Objid & CAN_IF1CMD_MSG_NUM_M);

我发现这两个问题都消失了。

换言之、我已经用一个32位写入访问替换了对 IF1CMD 寄存器的两个16位写入访问、并且所有访问似乎都正常工作:邮箱32 SI 被禁用、其 RAM 区域为空白(全部为零)并且只发送 ID = 0x581的数据消息。

那么、我问:这种变通办法是否是解决问题的正确方法?

我是否应该用 C2000Ware CAN 驱动程序文件中的32位访问替换对 IF 寄存器的任何16位访问?

是否有其他方法可以解决这些问题?

谢谢、

演示




--------------------------------------------------
我的代码

//常量
#define MSG_DATA_LENGTH   8.
#define TX_MSG_OBJ_ID   1.
#define RX_MSG_OBJ_ID   2.


//主函数
void main (void)


   /*硬件初始化*/
   BootInit (true);

   /* CAN B 时钟启用*/
   SYSCTL_enablePeripheral (SYSCTL_Periph_CLK_CANB);

   //
   //初始化 GPIO 并为 CANTX/CANRX 配置 GPIO 引脚
   //在模块 B 上
   //
   GPIO_setPinConfig (DEVICE_GPIO_CFG_CANRXB);
   GPIO_setPinConfig (DEVICE_GPIO_CFG_CANTXB);

   //
   //初始化 CAN 控制器 B
   //
   CAN_initModule (CANB_BASE);

   //
   //将 CAN 总线位速率设置为500kHz
   //
   CAN_setBitRate (CANB_BASE、SYSTEM_CLOCK、50000、16);

   //
   //在 CAN B 外设上接收报文时启用中断。
   //
   CAN_enableInterrupt (CANB_BASE、CAN_INT_IE0);

   //
   //初始化 PIE 并清除 PIE 寄存器。 禁用 CPU 中断。
   //
   interrupt_initModule();

   //
   //使用指向 shell 中断的指针初始化 PIE 矢量表
   //服务例程(ISR)。
   //
   interrupt_initVectorTable();

   //
   //启用全局中断(INTM)和实时中断(DBGM)
   //
   EINT;
   ERTM;

   //
   //此示例中使用的中断被重新映射到
   //此文件中的 ISR 函数。
   //这在 PIE 矢量表中注册中断处理程序。
   //
   INTERRUPT_REGTER (INT_CANB_1、&CANbISR);

   //
   //启用 CAN-B 中断信号
   //
   INTERRUPT_ENABLE (INT_CANB_1);
   CAN_enableGlobalInterrupt (CANB_BASE、CAN_GLOBAL_INT_CANINT0);

   //
   //初始化用于接收 CAN 消息的接收消息对象。
   //消息对象参数:
   //     CAN 模块:b.
   //     消息对象 ID 号:2.
   //     消息标识符:0x345
   //     消息帧:标准
   //     消息类型:接收
   //     消息 ID 掩码:0x0
   //     消息对象标志:接收中断和使用 ID 过滤器
   //     消息数据长度:8字节
   //
   CAN_setupMessageObject (CANB_BASE、RX_MSG_OBJ_ID、0x345、
                        CAN_MSG_FRAME_STD、CAN_MSG_OBJ_TYPE_RX、0、
                        CAN_MSG_OBJ_RX_INT_ENABLE | CAN_MSG_OBJ_USE_ID_FILTER、MSG_DATA_LENGTH);


   //
   //初始化用于发送 CAN 消息的发送消息对象。
   //消息对象参数:
   //     CAN 模块:A
   //     消息对象 ID 号:1.
   //     消息标识符:0x581
   //     消息帧:标准
   //     消息类型:发送
   //     消息 ID 掩码:0x0
   //     消息对象标志:无
   //     消息数据长度:8字节
   //
   CAN_setupMessageObject (CANB_BASE、TX_MSG_OBJ_ID、0x581、
                        CAN_MSG_FRAME_STD、CAN_MSG_OBJ_TYPE_TX、0、
                        CAN_MSG_OBJ_NO_FLAGS、MSG_DATA_LENGTH);

   //
   //初始化要发送的发送消息对象数据缓冲区
   //
   txMsgData[0]= 0x43;
   txMsgData[1]= 0x00;
   txMsgData[2]= 0x10;
   txMsgData[3]= 0x00;
   txMsgData[4]= 0x44;
   txMsgData[5]= 0x33;
   txMsgData[6]= 0x22;
   txMsgData[7]= 0x11;

   //
   //启动 CAN 模块 B 操作
   //
   CAN_startModule (CANB_BASE);

   while (1)
   {
      //
      //用于调试的计数器
      //
      CycleCounter++;
   
      //
      //在继续前延迟1秒
      //
   DEVICE_DELAY_US (1000000);

      //
      //发送消息
      //
      CAN_sendMessage (CANB_BASE、TX_MSG_OBJ_ID、MSG_DATA_LENGTH、txMsgData);
   }

}/*   结束 main */

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

    是的、您的权变措施正确。 HWREG_BP 实际上是32位、HWREGH 是16位。 这已经是内部已注意到的错误、将予以修复。 很抱歉出现问题。

    此致
    Chris
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    谢谢 Chris、
    如果您也向客户通知内部确认的错误、是否不会更好?

    好的、我们都知道承认您做的事情不是很好、但我们是编程人员、我们都知道我们每天(几乎)都会制造新的错误、不是吗? ;-)

    因此、我认为、向我们通报 kwnown 问题将是一件非常有用的事情。

    它可能是从内部错误跟踪器中提取的错误列表或类似的内容。 一种数据库、当某些内容看起来不能正常工作时、可以咨询。
    这是我的看法。

    无论如何、感谢您的帮助。

    此致、

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

    感谢您的反馈。 我们将努力改善这方面的沟通。

    此致
    Chris