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.

[参考译文] TCAN4550-Q1:通过 CAN 进行通信时出现问题

Guru**** 682950 points
Other Parts Discussed in Thread: TCAN4550EVM, TCAN4550-Q1, TCAN4550
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/interface-group/interface/f/interface-forum/1287949/tcan4550-q1-issue-communicating-over-can

器件型号:TCAN4550-Q1
主题中讨论的其他器件: TCAN4550、TCAN4550EVM

我使用带 Adafruit Feather ESP32-S2 TFT 的 TCAN4550-Q1来控制芯片。 我已成功通过 SPI 读取寄存器以及使用 ESP32对其进行写入。  

我现在尝试通过 CAN 进行通信、但无法使其正常工作。  我对此非常陌生、因此我在设置中犯了一个微不足道的错误。 我一直在参考数据表和 TCAN45xx 软件用户指南。  

到目前为止、我已经配置了 CAN 时序和 MRAM、并回读 TXFQS 寄存器以获取 Put 索引。 然后我写入 Put 索引、但在读取寄存器0x1050时、FIFO 消息的标志保持为零。  

以下是到目前为止我将使用的代码:  

#包含

#define CAN1SPI_CS 6
#define CAN2SPI_CS 5
#define CANSPI_CLK 4000000

SPI 设置 TCAN4550_SPI_SETTINGS (CANSPI_CLK、MSBFIRST、SPI_MODE0);
字节 receivedDat[4]
字节写入数据[4];

字节 Setupreg[]=0b110010000、0b00000110、0b10101010};
字节 canTimer[]=23、6、1};//同步跳转、 预分频器、采样点前的 tq、采样点后的 tq -值将集成为 val + 1 (即、3、4、7、2)
字节 canCONTROL[]=0、0、0、0b00001011};
字节 SIDFC[]=0、0x020、0};
字节 XIDFC[]=0、0x01、0、0x08};
字节 RXF0C[]=0x02、0x04、0、0x10};
字节 RXF1C[]=0x03、0x05、0、0xF0};
字节 RXBC[]=00、0、0};
字节 RXESC[]=00、0、0x76};
字节 TXEFF[]=0x020x030x02、0x58};
字节 TXBC[]=0x0A、0、0x02、0x70};
字节 TXESC[]=0、0、0、0x07};  
字节 TXbuffer1[]=0x520x34、0x56、0x78};
字节 TXbuffer2[]=0x010x87、0、0};//将配置从示例更改为禁用 CAN FD 和位速率切换
字节 TXbuffer3[]=0x440x33、0x22、0x11};//虚拟数据
字节 TXbuffer4[]=0x000x770x66、0x55};//虚拟数据
字节 TXBAT[]=00、0、0b00000001};
void setup(){
//将设置代码放在这里,运行一次:
 Serial.begin(921600);
 引脚模式(CAN1SPI_CS输出);
 引脚模式(CAN2SPI_CS输出);

 digitalWrite (CAN1SPI_CS高电平);
 digitalWrite (CAN2SPI_CS高电平);
 SPI.begin();

 //设置模式和引脚配置寄存器
 setRegister (0x0800Setupregg4);

 //设置 CAN 位时序
 changeState ("待机");

 //待机设置 CAN 时序////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 setRegister (0x101CcanTimer4);
 setRegister (0x1018canCONTROL4);

 //设置 MRAM
 setRegister (0x1084SIDFC4);
 setRegister (0x1088XIDFC4);
 setRegister (0x10A0RXF0C4);
 setRegister (0x10B0RXF1C4);
 setRegister (0x10ACRXBC4);
 setRegister (0x10BCRXESC4);
 setRegister (0x10F0TXEFC4);
 setRegister (0x10C0TXBC4);
 setRegister (0x10C8TXESC4);

 //将状态更改为正常,应该可以进行 CAN 通信
 changeState ("正常");

 延迟(50);
void loop(){
 readRegister (0x0800"bin");

 //读取中断寄存器
 // read0820 ();

 //尝试重置寄存器中断寄存器
 // setRegister (0x0820、reset0820、4);

 // 读取 TXFQS 寄存器位20:16以获得"Put"寄存器(当前在第16位读回1)
 读寄存器(0x10C4"Hex");

 //尝试写入 TX 缓冲器
 setRegister (0x82B8TXbuffer14);//将索引设置为0x01、TX 缓冲区部分的开头为0x8270、因此应写入0x8270 + 0x48*0x01 (元素大小)
 setRegister (0x82BCTXbuffer24);
 setRegister (0x82B0TXbuffer34);
 setRegister (0x82B4TXbuffer44);
 setRegister (0x10D0TXBAR4);

 readRegister (0x1050"bin");
读取寄存器、设置寄存器和更改状态这些函数都是我写入的、已验证已按预期运行的函数。  
当我读取寄存器0x1050时、它会为我提供"0x00300800"。
提前感谢!
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    大家好、

    我可以立即提出几项建议。  首先、寄存器0x1050的值0x00300800表示位错误未校正并且已校正的位被置位。  如果您没有首先将 MRAM "归零"、这些位加电至未知状态、则可能会发生这种情况。  然后、当计算纠错码时、由于某些位具有错误值而导致错误。

    是否可以通过终端或 JTAG 调试器验证或读回寄存器值、以验证它们是否已设置为您的预期值?  如果可以、您能否提供器件寄存器配置的最终值以供查看?

    控制寄存器0x1018有两个位、这两个位都需要设置为"1"、以便可以访问数据表中由 RP 指示的所有 MCAN 保护寄存器。  这些是 INIT 位和 CCE 位0x1018[1]:0。  这是一个棘手的部分。  CCE 位被置为"1"之前、INIT 位需要被置位为"1"。  然后、CCE 位需要设置为"1"、之后再设置任何其他寄存器中的任何 RP 位。  这意味着、控制寄存器0x1018通常需要至少2次写入来解锁受保护位并允许对其进行配置。  

    我在您的序列中只看到对控制寄存器的一次写入、因此很可能您没有实际配置受写保护的寄存器。  完成配置序列后、您应该将 CCE 和 init 位恢复为"0"、并对控制寄存器0x1018进行最终写入。  

    另请注意、将器件状态更改为待机模式会强制 INIT 位为"1"。  但是将器件更改为正常模式不会自动将 INIT 位设置为"0"。

    在我们验证所有寄存器均已正确设置且 MRAM 已初始化为0后、我们就可以看到还需要解决哪些问题。

    TCAN4550-Q1使用 Bosch 为 CAN FD 控制器开发的 MCAN IP。  Bosch 发布的 MCAN 用户指南中包含大量未包含在 TCAN4550-Q1数据表中的有用信息。  因此、我想向您指出这是一个额外的参考。  (链接)。 唯一需要注意的是、TCAN4550已经为每个 MCAN 地址添加了一个0x1000的偏移量。  因此、TCAN4550中的控制寄存器地址为0x1018、但在 MCAN 用户指南中列为0x18。  除此之外、MCAN 信息都适用于 TCAN4550-Q1。

    在这一点上、地址小于0x1000的 TCAN4550寄存器不是 MCAN 的一部分、而是由 TI 添加的、并处理与 CAN 相关的非器件功能。

    此致、

    乔纳森

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

    您好、Jonathan、感谢您的答复!  

    我更新了该代码、按照您的建议对寄存器0x1018进行两次单独的写入、分别设置 INIT 和 CCE。 不过、我认为我的 MRAM 之前已正确配置、这是我在设置后通过读取寄存器进行检查得到的、结果符合预期。 无论如何、我在设置后再次读取寄存器、这就是我将得到的结果:  

    地址:1084:00020000  

    地址:1088:00010008

    地址:10A0:02040010

    地址:10B0:030500F0

    地址:10F0:02030258

    地址:10C0:0A000270

    地址:10C8: 00000007

    我真的不明白消除 MRAM 的过程、您能解释一下如何做得更好吗? 如果不将其清零、是否会导致 MRAM 的配置出现问题、或者尝试写入 TX 缓冲区时出现问题?  

    谢谢!  

    阿利  

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

    我向我配置的 MRAM (0x8000至0x8600)中的所有寄存器写入零、并且似乎已清除 BEU 错误、因此谢谢您!  

    现在、当我读取寄存器0x10C4以获取 Put 索引时、它会读回00010009。  

    根据我的理解、这意味着 Put 索引为1、因此我写入数据的地址应该是存储器中 Tx 缓冲器部分的开头(0x8270)加上1 *元素大小(0x048)、即0x82B8。  

    不过、当我尝试写入数据时、会读取寄存器1050以查看 Tx FIFO 是否已满、而1050会回读为:29800800、表示仲裁错误以及对保留地址的访问。  

    我再次附上了我的代码以支持这些问题。  

    谢谢!  

    #包含

    #define CAN1SPI_CS 6
    #define CAN2SPI_CS 5
    #define CANSPI_CLK 4000000

    SPI 设置 TCAN4550_SPI_SETTINGS (CANSPI_CLK、MSBFIRST、SPI_MODE0);
    字节 receivedDat[4]
    字节写入数据[4];

    字节 Setupreg[]=0b110010000、0b00000110、0b10101010};
    字节 canTimer[]=23、6、1};//同步跳转、 预分频器、采样点前的 tq、采样点后的 tq -值将集成为 val + 1 (即、3、4、7、2)
    字节 canCONTROL[]=0、0、0、0b00001011};
    字节 setCCE []=0、0、0、0b00001011};
    字节 setINIT[]=0、0、0、0b00001001};
    字节 clearINIT[]=0、0、0、0b00001000};

    字节 SIDFC[]=0、0x020、0};
    字节 XIDFC[]=0、0x01、0、0x08};
    字节 RXF0C[]=0x02、0x04、0、0x10};
    字节 RXF1C[]=0x03、0x05、0、0xF0};
    字节 RXBC[]=00、0、0};
    字节 RXESC[]=00、0、0x76};
    字节 TXEFF[]=0x020x030x02、0x58};
    字节 TXBC[]=0x0A、0、0x02、0x70};
    字节 TXESC[]=0、0、0、0x07};  
    字节 TXbuffer1[]=0x520x34、0x56、0x78};
    字节 TXbuffer2[]=0x010x87、0、0};//将配置从示例更改为禁用 CAN FD 和位速率切换
    字节 TXbuffer3[]=0x440x33、0x22、0x11};//虚拟数据
    字节 TXbuffer4[]=0x000x770x66、0x55};//虚拟数据
    字节 TXBAT[]=00、0、0b00000001};
    字节清除[]=0b000000000b000000000b00000000、0b00000000};
    字节 clear0C[]=00、0、0};
    字节 reset0820[]=00b000101000、0};
    字节 clearInterrupt[]=0xFF0b000000000b00000000、0b00000000};
    / /

    void setup(){
    //将设置代码放在这里,运行一次:
     Serial.begin(921600);
     引脚模式(CAN1SPI_CS输出);
     引脚模式(CAN2SPI_CS输出);

     digitalWrite (CAN1SPI_CS高电平);
     digitalWrite (CAN2SPI_CS高电平);
     SPI.begin();

     //设置模式和引脚配置寄存器
     setRegister (0x0800Setupregg4);

     //设置 CAN 位时序
     // changeState ("待机");

     //待机设置 CAN 时序////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     setRegister (0x101CcanTimer4);
     setRegister (0x1018setINIT4);
     setRegister (0x1018setCCE4);

     //设置 MRAM
     setRegister (0x1084SIDFC4);
     setRegister (0x1088XIDFC4);
     setRegister (0x10A0RXF0C4);
     setRegister (0x10B0RXF1C4);
     setRegister (0x10ACRXBC4);
     setRegister (0x10BCRXESC4);
     setRegister (0x10F0TXEFC4);
     setRegister (0x10C0TXBC4);
     setRegister (0x10C8TXESC4);

     //将状态更改为正常,应该可以进行 CAN 通信
     changeState ("正常");
     setRegister (0x1018clearINIT4);
     // setRegister (0x0830、clearInterrupts、4);
     // setRegister (0x0820、reset0820、4);
      CURR_ADDRESS = 0x8000
     while (CURR_ADDRESS < 0x8500){
      setRegister (CURR_ADDRESS清除4);
      CURR_ADDRESS = CURR_ADDRESS + 8
     }
     延迟(50);

    void loop(){

     // 读取 TXFQS 寄存器位20:16以获得"Put"寄存器(位20:16)(当前在第16位读回1)
     读寄存器(0x10C4"Hex");

     //尝试写入 TX 缓冲器
     setRegister (0x82B8TXbuffer14);//将索引设置为0x01、TX 缓冲区部分的开头为0x8270、因此应写入0x8270 + 0x48*0x01 (元素大小)
     setRegister (0x82BCTXbuffer24);
     setRegister (0x82C0TXbuffer34);
     setRegister (0x82C4TXbuffer44);
     setRegister (0x10D0TXBAR4);
     
     read1050()

      延迟(1000);

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

    大家好、

    我很高兴您清除了受保护的寄存器和 BEU、BEC 错误。  当器件上电时、MRAM 单元上未连接复位机制、它们可以使用未知的值上电。  通常、MRAM 会为每个字节单元加电0、但某些单元可能具有非零值。   

    如果没有向存储器写入值、则 ECC 计算假定其已初始化为零、因此如果您没有向启用的每个 MRAM 单元显式写入0x00、则可能会发生 BEU 和 BEC 错误。  在将 TX 消息写入 TX 缓冲器之前需要执行此操作、或者需要将0x00写入每个已启用的未使用单元。

    您是否看过 TCAN4550演示软件(SLLC469)作为参考? 您可以在 TCAN4550-Q1产品文件夹(链接)中或从此直接链接(链接)中找到下载链接。  通常与大多数用 C 语言编程的 MCU 配合使用的 ANSI-C 代码。 需要更新 SPI 驱动程序和 GPIO 硬件引脚配置、以匹配正在使用的特定 MCU。  但它可能是一个好的参考。

    地址:1084:00020000  

    您正在配置2个 SID 筛选器元素。  是否真的使用滤波器来编写 MRAM 空间?  如果您在 MRAM 中启用筛选器、那么您实际上必须拥有一个筛选器。  这是因为当接收到 CAN 消息时、MCAN 控制器将循环筛选器列表并比较消息 ID、并确定如何处理消息(存储或忽略它)。  如果您启用了滤波器、但实际上没有向 MRAM 写入一个、则 RX 进程在尝试将消息与空滤波器元素进行比较时将出错。  这不是发送消息的问题、但我没有看到您将筛选器写入已启用的 MRAM 的位置。  XID 也是如此

    我认为您的 RAM 寻址从 TXEFC 起始地址开始。  如果我正确地解释了您的寄存器值、您需要4个 RX FIFO 0元素、数据有效载荷为48字节。  每个缓冲区元素将占用14个字(2个字表示标头、12个字表示48个字节的数据)。

    那么您需要5个 RX FIFO 1元素、其数据有效载荷为64字节。  每个缓冲区元素将占用18个字(2个字表示标头、16个字表示64个字节的数据)。

    我认为下一个可用的 MRAM 段的起始地址应为0x258。  我想您正在尝试将下一部分分配给起始地址为0x58的 TX 事件 FIFO (TXEFC)。  这也会导致 TX 缓冲器出现问题。  如果有3个 TXEFC 元素、则我认为 TX 缓冲区的起始地址应为0x270。

    请仔细检查我对所需配置的计算和解释、并验证 MRAM 地址分配。  但我认为您可能无法将 TX 消息写入 MRAM 的正确部分、这可能是您无法发送消息的原因。

    此致、

    乔纳森

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

    尊敬的 Jonathan:  

    你已经完全把我丢了。 我一直主要关注 TCAN 45xx 软件指南中有关写入 CAN 的示例。 我唯一更改的是我要写入的地址、基于我从 TXFQS 读回的 PUT 索引。 我附上了我所指的书写表的图片。 我采用与本例中相同的方式配置了 MRAM。  

    在本例中、Put 索引为3、因此他们计算出要写入的地址为0x48 (元素大小)* 0x3 +段起始地址。 我遵循了相同的过程、但使用放置索引1来确定要写入的地址。 我还认为、 基于这个例子、我要在前两次写入中使用滤波器来填充 MRAM 空间? 但我不确定这一点。  

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

    大家好、

    我很抱歉让您困惑。  我忘记了您试图直接按照软件用户指南中的配置进行操作、并且我试图确定您的配置并根据解码寄存器值查找错误、因此了解您正在尝试执行的操作会有所帮助。

    TCAN4550使用由 Bosch 开发的 MCAN CAN FD 控制器 IP、因此我还会向您推荐 Bosch 发布的 MCAN 用户手册。 (链接)。  它包含无法整合到 TI 发布的文档中的 MCAN 功能的其他信息。

    我还认为我在 前两次写入中使用筛选器来填充 MRAM 空间,是基于这个例子吗? 但我不确定这一点。  [/报价]

    对于 SID 和 XID 过滤器、您在 MRAM 中用 SIDFC 和 XIDFC 配置寄存器为过滤器配置空间、但是我没有看到任何过滤器实际写入到包含消息 ID、过滤器类型(传统位掩码或范围过滤器等)的 MRAM 中。

     //设置 MRAM
     setRegister (0x1084SIDFC4);
     setRegister (0x1088XIDFC4);
    [/报价]

    如果您启用起始地址为0x8000的2个 SID 过滤器、则需要将 SID 过滤器写入 MRAM 地址0x8000、另一个写入0x8004。  然后、使用一个 XID 滤波器元件、您需要将该滤波器写入 MRAM 地址0x8008。  SID 过滤器只是内存的一个字、而 XID 过滤器是内存的两个字。  

    这些滤波器可能不会导致 TX 问题、但当您尝试接收消息时、这将是一个问题。  有关更多详细信息、请参阅 MCAN 用户手册的第2.4节。

    TX FIFO 应从初始 Put 索引值"0"开始、因此用于第一条 TX 消息的 TX 缓冲区元素应为"0"。  从你的代码,我不知道你是如何或为什么在你的第一个消息前把 Put Index 增加到1。

    但是、如果您要将 TX 消息元素写入 MRAM 索引"1"位置、则还需要更改 TXBAR 字节的值以与您在 MRAM 中使用的索引位置相匹配。  您的代码显示位"0"设置为索引位置"0"、因此、当您向 TXBAR 寄存器0x10D0写入值0x00000001时、它将尝试发送位于 MRAM 起始地址0x8270的消息、具体根据 MRAM 配置。

    您能否尝试使用索引"0"代替索引"1"表示第一条 TX 消息、看看它是否有任何变化?

    此致、

    乔纳森

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

    尊敬的 Jonathan:  

    我会为 TX 缓冲器尝试一下、谢谢!

    关于筛选器-是否有可能不具有 SID 和 XID 筛选器? 在这种情况下、我将更改 MRAM 配置以反映这一点。 只是不确定这些是否是必需的,或者是否有具体的负面影响没有它们。

    再次感谢你的所有帮助:)  

    阿利  

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

    大家好、

    是的、你只需将 SIDFC (0x1084)和 XIDFC (0x1088)寄存器保留为缺省值、或者将它们注释掉在你的代码中。  您无需对任何其他 MRAM 元素的起始地址分配进行任何更改、因为要求各段不重叠。  您可以有间隙、也可以按照自己喜欢的方式排列部分。  只要 SID 和 XID 列表大小的值为零、MCAN 就不会在接收消息时尝试使用它们。

    为了拥有多个 RX FIFO、您需要设置过滤器、以便将消息定向到相应的 RX FIFO。  默认情况下、所有的 RX 消息都会存储在 RX FIFO 0中、因此如果您没有过滤器、那么实际上就无需配置 RX FIFO 1、因为系统只需要使用这些过滤器。  

    如果希望真正简化测试设置以查看是否传输 CAN 消息、则可以先使用"专用 TX 缓冲区"、而不是 TX FIFO。  这样、您就可以100%控制使用哪个缓冲元件来存储消息和您设置的相应 TXBAR 位。  您只需交换 TXBC (0x10C0)寄存器中 TFQS 和 NDTB 寄存器字段的值、并保持起始地址相同。  这样就只需要在每次要发送消息时将 TX 消息写入 MRAM 缓冲区并将 TXBAR 位设置为"1"。  如果不重新写入 TX 缓冲区、则每次设置 TXBAR 位时、就可以一次又一次地发送相同的消息。

    在您了解它的工作原理并更好地了解器件的工作原理之后、如果您愿意、可以添加 FIFO 获取/放置索引代码。

    此致、

    乔纳森

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

    尊敬的 Jonathan:

    感谢 FIFO 的建议。 我添加了针对 SIDFC 和 XIDFC 的 MRAM 分配的注释。将 MRAM 配置为000A0270时、我更改了0x10C0的地址。 我还将 TXBAR 更改成了仅为零。 否则、我的代码与上述相同、但在循环中、我具有以下内容:  

     //尝试写入 TX 缓冲器
     setRegister (0x8270TXbuffer14);  
     setRegister (0x8274TXbuffer24);
     setRegister (0x827CTXbuffer34);
     setRegister (0x8280TXbuffer44);
     setRegister (0x10D0TXBAR4);

    现在、读取寄存器1050时没有任何错误、但是该寄存器仅读回零。 我不确定为什么 Rx FIFO 位没有设置?  

    此致、

    阿利  

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

    大家好、

    我想澄清一点、我们是在正确设置 TXBAR 寄存器中的位。  将全部零写入 TXBAR 不会传输消息。

    最多可以启用32个 TX 缓冲器元件。  您现在使用寄存器0x10C0的新值来启用其中的10个。

    TXBAR 寄存器中的每个位对应于其中一个 TX 缓冲器元件、器件将尝试发送保存在与 TXBAR 位对应的 MRAM 缓冲区位置的消息。  因此、当您将消息存储到第一个 TX 缓冲器"0"中且起始地址为0x8270时、您需要将 TXBAR 寄存器的位"0"设置为值"1"以发送消息。  这意味着向0x10D0写入0x00000001。

    如果您希望从最后一个启用的 TX 缓冲区元素发送消息、索引将为"9"、所以将消息写入 MRAM、然后将 TXBAR 寄存器的第9位设置为"1"的值。  这意味着您要将0x00000200写入寄存器0x10D0。

    此外、可以一次设置多个 TXBAR 位、器件将尝试在每个 TX 缓冲区中传输与"1"相对应的消息。

    现在,读取寄存器1050时没有任何错误,但是寄存器只读回零。 我不确定为什么 Rx FIFO 位没有设置?  [/报价]

    您正在连接到 TCAN4550器件、该器件将接收并确认 CAN 总线上的消息?

    您是否正在尝试执行某种形式的环回测试、使 RX FIFO 也接收它刚刚传输的同一条消息?  

    您需要将另一个 CAN 设备连接到 TCAN4550、该设备将发送一条将在 RX FIFO 中接收到的消息。  或者需要启用其中一个环回模式。

    可以配置两种不同类型的环回。

    如果您希望将器件配置为内部环回模式、则 TEST.LBCK 位(0x1010.4)应设置为"1"、从而使 TX 数据能够环回 RX。  此外、应设置 CCCR.MON 位(0x1018.5)、从而断开 TX 数据与 CAN 总线的连接。  

    但是、如果清除 CCCR.MON 位或将其设置为"0"、这将针对外部环回模式配置器件、从而允许 TX 数据在 CAN 总线上输出并环回到 RX 输入。  在此模式下、外部 CAN 总线数据不会到达 RX 输入端。  下图摘自 Bosch M_CAN 用户指南、很好地展示了设备的配置方式。

    此致、

    乔纳森

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

    尊敬的 Jonathan:  

    再次感谢您。 我现在在1050的仲裁阶段收到协议错误,我不明白为什么。 我已附上更新后的代码。

    #包含

    #define CAN1SPI_CS 6
    #define CAN2SPI_CS 5
    #define CANSPI_CLK 4000000

    SPI 设置 TCAN4550_SPI_SETTINGS (CANSPI_CLK、MSBFIRST、SPI_MODE0);
    字节 receivedDat[4]
    字节写入数据[4];

    字节 Setupreg[]=0b110010000、0b00000110、0b10101010};
    字节 canTimer[]=23、6、1};//同步跳转、 预分频器、采样点前的 tq、采样点后的 tq -值将集成为 val + 1 (即、3、4、7、2)
    字节 canCONTROL[]=0、0、0、0b00001011};
    字节 setCCE []=0、0、0、0b00001011};
    字节 setINIT[]=0、0、0、0b00001001};
    字节 clearINIT[]=0、0、0、0b00101000};

    字节 SIDFC[]=0、0x020、0};
    字节 XIDFC[]=0、0x01、0、0x08};
    字节 RXF0C[]=0x02、0x04、0、0x10};
    字节 RXF1C[]=0x03、0x05、0、0xF0};
    字节 RXBC[]=00、0、0};
    字节 RXESC[]=00、0、0x76};
    字节 TXEFF[]=0x020x030x02、0x58};
    //字节 TXBC[]={0x0A、0、0x02、0x70};为 FIFO 配置
    字节 TXBC[]=0x00、0x0A、0x02、0x70};//已配置为缓冲器
    字节 TXESC[]=0、0、0、0x07};  
    字节 TXbuffer1[]=0x520x34、0x56、0x78};
    字节 TXbuffer2[]=0x010x87、0、0};//将配置从示例更改为禁用 CAN FD 和位速率切换
    字节 TXbuffer3[]=0x440x33、0x22、0x11};//虚拟数据
    字节 TXbuffer4[]=0x000x770x66、0x55};//虚拟数据
    字节 TXBAAR[]=00、0、0x01};
    字节清除[]=0b000000000b000000000b00000000、0b00000000};
    字节 clear0C[]=00、0、0};
    字节 reset0820[]=00b000101000、0};
    字节 testReg []=00、0、0x10};
    字节 clearInterrupt[]=0xFF0b000000000b00000000、0b00000000};
    / /

    void setup(){
    //将设置代码放在这里,运行一次:
     Serial.begin(921600);
     引脚模式(CAN1SPI_CS输出);
     引脚模式(CAN2SPI_CS输出);

     digitalWrite (CAN1SPI_CS高电平);
     digitalWrite (CAN2SPI_CS高电平);
     SPI.begin();

     //设置模式和引脚配置寄存器
     setRegister (0x0800Setupregg4);

     //设置 CAN 位时序
     // changeState ("待机");

     //待机设置 CAN 时序////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     setRegister (0x101CcanTimer4);
     setRegister (0x1018setINIT4);
     setRegister (0x1018setCCE4);

     //设置 MRAM
     // setRegister (0x1084、SIDFC、4);
     // setRegister (0x1088、XIDFC、4);
     setRegister (0x10A0RXF0C4);
     setRegister (0x10B0RXF1C4);
     setRegister (0x10ACRXBC4);
     setRegister (0x10BCRXESC4);
     setRegister (0x10F0TXEFC4);
     setRegister (0x10C0TXBC4);
     setRegister (0x10C8TXESC4);

     //将状态更改为正常,应该可以进行 CAN 通信
     changeState ("正常");
     setRegister (0x1018clearINIT4);
     setRegister (0x1010testReg、4);

     //清除 MRAM
      CURR_ADDRESS = 0x8000
     while (CURR_ADDRESS < 0x8500){
      setRegister (CURR_ADDRESS清除4);
      CURR_ADDRESS = CURR_ADDRESS + 8
     }
     延迟(50);

    void loop(){
     //尝试写入 TX 缓冲器
     setRegister (0x8270TXbuffer14);
     setRegister (0x8274TXbuffer24);
     setRegister (0x827CTXbuffer34);
     setRegister (0x8280TXbuffer44);
     setRegister (0x10D0TXBAR4);
     read1050()

      延迟(1000);

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

    大家好、

    仲裁(标称)和数据阶段的协议错误通常是由于 CAN 总线上不同器件的位时序配置不兼容所致。  CAN 总线上的所有节点通常都应配置相同的标称位时序参数和数据位时序参数、以便它们以相同的方式发送和接收/采样数据。  如果配置不同、它们可能会错误地对数据进行采样并产生位错误、从而导致各种类型的协议错误之一。

    标称位时序&预分频器寄存器(NBTP) 0x101C

    数据位时序&预分频器寄存器(DBTP) 0x100C

    发送器延迟补偿寄存器(TDCR) 0x1048 (如果使用 CAN FD)

    我看到要配置 NBTP 寄存器0x101C、但看不出要配置 DBTP 寄存器0x100C 的位置。  器件可能尝试使用默认寄存器值进行传输、这些值对于您的应用不正确、并且可能是导致协议错误的原因。

    此致、

    乔纳森

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

    尊敬的 Jonathan:

    我更新了寄存器0x100C 的位时序、仲裁错误似乎消失了、谢谢!

    我正在尝试设置 寄存器1010、以便可以进入回送模式、但回读寄存器时、它不会反映我向其写入的值。 我注意到它是 RP、因此我将在我设置 MRAM 的同一个部分进行写入(在设置 CCE 和 INIT 之后)。 我还将 CCCR.TEST 设置为1。 当我读回地址1010时、收到0x00000080。  

    此外、在寄存器0820中、会出现 CAN 静默错误。

    谢谢!  

    阿利  

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

    大家好、

    很高兴我们取得了进步!

    如您所述、测试寄存器中的 LPBK 位是 RP。  我知道这会阻止您将其置位的唯一原因是、在您尝试写入此寄存器之前、INIT 和 CCE 位不等于1。  或许可以尝试多次写入此寄存器或在写入后进行读取验证、以查看是否未受保护。  如果 INIT 和 CCE 位都设置为"1"、我没有看到受保护寄存器无法更新的问题。  关于此问题、我唯一的建议是仔细检查代码、并在需要时向 CCCR 寄存器添加重复写入、以确保所有位均已设置、然后执行读取验证是否以帮助确定问题。

    如需额外参考、请参阅此 E2E 主题、其中包含许多有关配置环回的详细信息、您可能需要参考。 (链接)。

    CAN 静默错误只是意味着 CAN 总线上大约1秒没有任何活动。  这是失效防护功能的一部分、有助于检测故障情况、例如器件与 CAN 总线物理断开的情况。  如果启用了失效防护模式、则大约4分钟的 CAN 静默错误可能会导致器件进入睡眠模式。  默认情况下、失效防护模式是禁用的、因此您通常可以忽略 CAN 静默错误。

    此致、

    乔纳森

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

    你好、Jonathan。  

    找到了问题,我只是把它设置错误,对不起! 现在已设置环回模式。 我还设置 CCR.Mon。 我现在尝试发送一条消息、这个问题与之前的问题是 Rx FIFO 从未被设置为满。  

    这是循环中唯一的代码:  

     //尝试写入 TX 缓冲器
     setRegister (0x8270TXbuffer14);
     setRegister (0x8274TXbuffer24);
     setRegister (0x827CTXbuffer34);
     setRegister (0x8280TXbuffer44);
     setRegister (0x10D0TXBAR4);
    此外、这些变量的定义:  
    字节 TXbuffer1[]=0x520x34、0x56、0x78};
    字节 TXbuffer2[]=0x010x87、0、0};//将配置从示例更改为禁用 CAN FD 和位速率切换
    字节 TXbuffer3[]=0x440x33、0x22、0x11};//虚拟数据
    字节 TXbuffer4[]=0x000x770x66、0x55};//虚拟数据
    字节 TXBAAR[]=00、0、0x01};
    我回读寄存器10cc、读数为0x00000001、我认为是正确的。 我试图回读寄存器0x10D8、看看它是否被设置成表示传输发生、但我得到的却是全零。 我也会在寄存器1050中获取所有的零。  我已确认我处于 正常模式、是否缺少传输消息所需的其他内容?  
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我不再遇到 CAN 静默错误、因此似乎 CAN 总线上有活动、但我无法确定在何处

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

    如果您看到 TXBRP 位被设置(0x10CC[0])、则器件应尝试发送消息并等待 ACK。  在环回模式下、为了进行自检、它应该忽略 ACK 错误、因此我们应该在 RX FIFO 中看到该消息。  

    您能否以寄存器地址和值的形式提供最终 TCAN4550配置的列表?  如果是、我可以将这些值编程到 EVM 中、然后更轻松地对其进行调试并为您提供反馈。

    此致、

    乔纳森

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

    尊敬的 Jonathan:

    以下是我的完整代码:

    #包含

    #define CAN1SPI_CS 6
    #define CAN2SPI_CS 5
    #define CANSPI_CLK 4000000

    SPI 设置 TCAN4550_SPI_SETTINGS (CANSPI_CLK、MSBFIRST、SPI_MODE0);
    字节 receivedDat[4]
    字节写入数据[4];

    字节 Setupreg[]=0b110010000b00100000、0b00000110、0b10101010};

    字节 canTimer[]=23、6、1};//同步跳转、 预分频器、采样点前的 tq、采样点后的 tq -值将集成为 val + 1 (即、3、4、7、2)
    字节 canCONTROL[]=0、0、0、0b00001011};

    //允许访问受保护的写入寄存器的控制寄存器
    字节 setCCE []=0、0、0、0b10111011};
    字节 reset1018[]=0、0、0、0x99};
    字节 clearINIT[]=0、0、0、0b10110000};

    字节 SIDFC[]=0、0x020、0};
    字节 XIDFC[]=0、0x01、0、0x08};
    字节 RXF0C[]=0x02、0x04、0、0x10};
    字节 RXF1C[]=0x03、0x05、0、0xF0};
    字节 RXBC[]=00、0、0};
    字节 RXESC[]=00、0、0x76};
    字节 TXEFF[]=0x020x030x02、0x58};
    //字节 TXBC[]={0x0A、0、0x02、0x70};为 FIFO 配置
    字节 TXBC[]=0x00、0x0A、0x02、0x70};//已配置为缓冲器
    字节 TXESC[]=0、0、0、0x07};  
    字节 TXbuffer1[]=0x520x34、0x56、0x78};
    字节 TXbuffer2[]=0x010x87、0、0};//将配置从示例更改为禁用 CAN FD 和位速率切换
    字节 TXbuffer3[]=0x440x33、0x22、0x11};//虚拟数据
    字节 TXbuffer4[]=0x000x770x66、0x55};//虚拟数据
    字节 TXBAAR[]=00、0、0x01};
    字节清除[]=0b000000000b000000000b00000000、0b00000000};
    字节 clear0C[]=00、0、0};
    字节 reset0820[]=00b000101000、0};
    字节测试寄存器[]=00、0、0b00010000};
    字节 clearInterrupt[]=0xFF0b000000000b00000000、0b00000000};
    / /

    void setup(){
    //将设置代码放在这里,运行一次:
     Serial.begin(921600);
     引脚模式(CAN1SPI_CS输出);
     引脚模式(CAN2SPI_CS输出);

     digitalWrite (CAN1SPI_CS高电平);
     digitalWrite (CAN2SPI_CS高电平);
     SPI.begin();
     // while (!Serial){
     // 延时(10);
     //}
     //设置模式和引脚配置寄存器
     setRegister (0x0800Setupregg4);

     //设置 CAN 位时序
     changeState ("待机");

     //待机设置 CAN 时序////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     setRegister (0x1018reset10184);//设置 INIT 位
     setRegister (0x1018setCCE4);//设置 CCE
     setRegister (0x101CcanTimer4);//设置 CAN 时序 NBTP
     setRegister (0x100CcanTimer4);//设置 CAN 时序 DBTP
     setRegister (0x1010testReg、4);//设置环回模式

     //设置 MRAM
     setRegister (0x10A0RXF0C4);
     setRegister (0x10B0RXF1C4);
     setRegister (0x10ACRXBC4);
     setRegister (0x10BCRXESC4);
     setRegister (0x10F0TXEFC4);
     setRegister (0x10C0TXBC4);
     setRegister (0x10C8TXESC4);

     //将状态更改为正常,应该可以进行 CAN 通信
     changeState ("正常");

     //清除初始位
     setRegister (0x1018clearINIT4);

     //零 MRAM
      CURR_ADDRESS = 0x8000
     while (CURR_ADDRESS < 0x8500){
      setRegister (CURR_ADDRESS清除4);
      CURR_ADDRESS = CURR_ADDRESS + 8
     }
     
     延迟(50);

    void loop(){

     //尝试写入 TX 缓冲器
     setRegister (0x8270TXbuffer14);
     setRegister (0x8274TXbuffer24);
     setRegister (0x827CTXbuffer34);
     setRegister (0x8280TXbuffer44);
     setRegister (0x10D0TXBAR4);//检查10cc 以查看位是否已正确设置

     read1050()

     readRegister (0x10A4"bin");//检查 Rx FIFO 0状态寄存器
     readRegister (0x8270"hex");// Rx FIFO 0的起始地址、应读回  
     延迟(1000);


    //设置器件状态(睡眠、待机、正常)//////////////////////////////
    void changeState (char state[]){
     字节集字节
     if (state ="normal"){
      setbyte = 0b10101010//前两位10表示正常
     否则,如果(状态="STANDBY"){
      setbyte = 0b01101010//待机时的前两位01
     否则,如果(state ="sleep"){
      setbyte = 0b00101010//进入睡眠模式、前两位00
     }

     Setupreg[3]= setbyte
     setRegister (0x0800Setupregg4);


    //写入寄存器//////////////////////////////////////////////////////////////////////////////////////////
    void setRegister (short regAddressbyte sendDat[]int nbytes){
     SPI.beginTransaction(TCAN4550_SPI_settings);   
     digitalWrite (CAN1SPI_CS低电平);
     spi.transfer (0x61);//写入命令
     spi.transfer16 (regAddress);//发送要写入的地址
     spi.transfer (0x01);//要写入的数据长度(0x01是32位?)

     for (int i = 0i < nbytesi++){
       spi.transfer (sendDat[i]);
     }
     
     digitalWrite (CAN1SPI_CS高电平);
     spi.endTransaction ();

    //将寄存器输出读取到串行监视器////////////////////////////////////////////
    void readRegister (short regAddresschar 编码[]){

     SPI.beginTransaction(TCAN4550_SPI_settings);   
     digitalWrite (CAN1SPI_CS低电平);

     spi.transfer (0x41);//读取命令
     spi.transfer16 (regAddress);//将寄存器的地址发送至 READ
     spi.transfer (0x01);//预期返回的数据长度

     //接收数据
     for (int i = 0i < 4i++){
      receivedDat [i]= spi.transfer (0x00);//传输虚拟零到读出寄存器值
     }

     digitalWrite (CAN1SPI_CS高电平);
     spi.endTransaction ();

     //读取到串行监视器
     serial.println ("地址:");
     serial.println (regAddresshex);

     if (编码=="hex"){
      for (int i = 0i < 4i++){
       serial.println (receivedDat[i],hex);
      }
      serial.println ();
     其他(else)
      for (int i = 0i < 4i++){
       serial.print ("字节");
       serial.print (i);
       serial.print (":");
       serial.println (receivedDat [i],bin);
      }
     }

    //读取中断寄存器////////////////////////////////////////////////
    void read0820 (){
     SPI.beginTransaction(TCAN4550_SPI_settings);   
     digitalWrite (CAN1SPI_CS低电平);

     spi.transfer (0x41);//读取命令
     spi.transfer16 (0x0820);//将寄存器的地址发送至 READ
     spi.transfer (0x01);//预期返回的数据长度

     //接收数据
     for (int i = 0i < 4i++){
      receivedDat [i]= spi.transfer (0x00);//传输虚拟零到读出寄存器值
     }

     //结束事务
     digitalWrite (CAN1SPI_CS高电平);
     spi.endTransaction ();

     //读取到串行监视器
     serial.println ("/////////////////////// 读数0820 //////////////////////// ");

     //第一个字节[31:24]////////////////////////
     //只有第一个位有数据
     serial.print ("第一字节:");
     serial.println(civedDat[0]bin );
     
     if (bitRead (receivedDat [0]7)== 1){
      serial.println ("CAN 总线正常");
     }

     //第二字节[23:16]////////////////////
     //第17位保留,因此不打印
     serial.print ("第二字节:");
     serial.println(civedDat[1]bin);
     if (bitRead (receivedDat [1]、7)== 1){
      serial.println ("睡眠模式");
     }如果(bitRead (receivedDat[1]6)== 1){
      serial.println ("欠压 Vsup 和 UVccout ");
     }如果(bitRead (receivedDat[1]5)== 1){
      serial.println ("欠压 Vio");  
     }如果(bitRead (receivedDat[1]4)== 1){
      serial.println ("开机");
     }如果(bitRead (receivedDat[1]3)== 1){
      serial.println ("热关机");
     }如果(bitRead (receivedDat[1]2)== 1){
      serial.println ("看门狗超时");
     }如果(bitRead (receivedDat[1]0)== 1){
      serial.println ("检测到不可纠正的 ECC 错误");
     }

     //第三字节[15:8]////////////////////////
     //第12、11、9位保留
     serial.print ("第三字节:");
     serial.println(civedDat[2]bin );

     if (bitRead (receivedDat [2]、7)== 1){
      serial.println ("CAN 总线唤醒中断");
     }如果(bitRead (receivedDat[2]6)== 1){
      serial.println ("本地唤醒");
     }如果(bitRead (receivedDat[2]5)== 1){
      serial.println ("唤醒错误");
     }如果(bitRead (receivedDat[2]2)== 1){
      serial.println (" CAN 静默");
     }如果(bitRead (receivedDat[2]0)== 1)
      serial.println ("可以卡在显性状态");
     }

     //第四字节[7:0]//////////////////////////////////////
     //位2,4保留
     serial.print ("第四字节:");
     serial.println(civedDat[3]bin );
     if (bitRead (receivedDat [3]7)== 1){
      serial.println ("全局错误-任何故障");
     }如果(bitRead (receivedDat[3]6)== 1){
      serial.println ("唤醒请求");
     }如果(bitRead (receivedDat[3]5)== 1){
      serial.println ("can error ");
     }如果(bitRead (receivedDat[3],3)== 1){
      serial.println ("SPI 错误");
     }如果(bitRead (receivedDat[3],1)== 1){
      serial.println ("M_can global int");
     }如果(bitRead (receivedDat[3],0)== 1){
      serial.println ("全局电压、温度或 WDTO ");
     }

    //读取中断寄存器////////////////////////////////////////////////
    void read1050(){
     SPI.beginTransaction(TCAN4550_SPI_settings);   
     digitalWrite (CAN1SPI_CS低电平);

     spi.transfer (0x41);//读取命令
     spi.transfer16 (0x1050);//发送寄存器的地址以进行读取
     spi.transfer (0x01);//预期返回的数据长度

     //接收数据
     for (int i = 0i < 4i++){
      receivedDat [i]= spi.transfer (0x00);//传输虚拟零到读出寄存器值
     }

     //结束事务
     digitalWrite (CAN1SPI_CS高电平);
     spi.endTransaction ();

     //读取到串行监视器
     serial.println ("/////////////////////// 读数1050 //////////////////////// ");

     //第一个字节[31:24]////////////////////////
     // 31,30 rsvd
     serial.print ("第一字节:");
     serial.println(civedDat[0]bin );
     
     if (bitRead (receivedDat [0]5)== 1){
      serial.println ("访问保留地址");
     }如果(bitRead (receivedDat[0]4)== 1){
      serial.println ("数据阶段的协议错误");
     }如果(bitRead (receivedDat[0]3)== 1){
      serial.println ("仲裁阶段协议错误");
     }如果(bitRead (receivedDat[0]2)== 1){
      serial.println ("看门狗中断");
     }如果(bitRead (receivedDat[0]1)== 1){
      serial.println (" Bus_Off 状态");
     }如果(bitRead (receivedDat[0]0)== 1){
      serial.println ("警告状态");
     }

     //第二字节[23:16]////////////////////
     serial.print ("第二字节:");
     serial.println(civedDat[1]bin);
     if (bitRead (receivedDat [1]、7)== 1){
      serial.println ("错误被动");
     }如果(bitRead (receivedDat[1]6)== 1){
      serial.println ("日志记录溢出错误");
     }如果(bitRead (receivedDat[1]5)== 1){
      serial.println ("位错误未更正");  
     }如果(bitRead (receivedDat[1]4)== 1){
      serial.println ("位错误已更正");
     }如果(bitRead (receivedDat[1]3)== 1){
      serial.println ("消息存储到专用 Rx 缓冲器");
     }如果(bitRead (receivedDat[1]2)== 1){
      serial.println ("发生超时");
     }如果(bitRead (receivedDat[1]1)== 1){
      serial.println ("消息 RAM 访问失败");
     }如果(bitRead (receivedDat[1]0)== 1){
      serial.println ("Timestamp wrapround");
     }

     //第三字节[15:8]////////////////////////
     serial.print ("第三字节:");
     serial.println(civedDat[2]bin );

     if (bitRead (receivedDat [2]、7)== 1){
      serial.println ("Tx Event FIFO 元素丢失");
     }如果(bitRead (receivedDat[2]6)== 1){
      serial.println ("Tx Event FIFO FULL (Tx 事件 FIFO 已满)");
     }如果(bitRead (receivedDat[2]5)== 1){
      serial.println ("Tx Event FIFO Watermark ached");
     }如果(bitRead (receivedDat[2]4)== 1){
      serial.println ("Tx Event FIFO 新条目");
     }如果(bitRead (receivedDat[2]3)== 1)
      serial.println ("Tx FIFO 空");
     }如果(bitRead (receivedDat[2]2)== 1){
      serial.println ("传输取消已完成");
     }如果(bitRead (receivedDat[2]1)== 1){
      serial.println ("传输取消已完成");
     }如果(bitRead (receivedDat[2]0)== 1)
      serial.println ("高优先级消息");
     }

     //第四字节[7:0]//////////////////////////////////////
     serial.print ("第四字节:");
      serial.println(civedDat[3]bin );

     if (bitRead (receivedDat [3]7)== 1){
      serial.println (" Rx FIFO 1消息丢失");
     }如果(bitRead (receivedDat[3]6)== 1){
      serial.println (" Rx FIFO 1满");
     }如果(bitRead (receivedDat[3]5)== 1){
      serial.println ("达到 Rx FIFO 1水印");
     }如果(bitRead (receivedDat[3]4)== 1){
      serial.println (" Rx FIFO 1新消息");
     }如果(bitRead (receivedDat[3],3)== 1){
      serial.println (" Rx FIFO 0消息丢失");
     }如果(bitRead (receivedDat[3]2)== 1){
      serial.println (" Rx FIFO 0满");
     }如果(bitRead (receivedDat[3],1)== 1){
      serial.println ("已达到 Rx FIFO 0水印");
     }如果(bitRead (receivedDat[3],0)== 1){
      serial.println (" Rx FIFO 0新消息");
     }
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    大家好、

    您能否在配置结束时添加一个函数来读回所有寄存器并在屏幕上执行 serial.print 函数、以便我们能够获得最终器件配置的日志?  

    如果是、这会使我的工作快得多、允许我仅将最终寄存器值硬编码到器件中、然后开始查找哪些位未正确设置。

    如果没有、我将尝试根据代码重新创建您的配置、并确定问题所在。  

    此致、

    乔纳森

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

    以下是寄存器读数:

    地址:800
    0xC8 20 06 AA


    地址:1050
    0x00 00 00 00

    地址:1018
    0x00 00 00 B9

    地址:101C
    0x02 03 06 01

    地址:100C
    0x00 03 06 01

    地址:1010
    0x00 00 90

    地址:10A0
    0x02 04 00 10

    地址:10B0
    0x03 05 00 F0

    地址:10AC
    0x00 00 00 00

    地址:10BC
    0x00 00 76

    地址:10F0
    0x02 03 02 58

    地址:10C0
    0x00 0A 02 70

    地址:10C8
    0x00 00 07

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

    也忘了这个:

    地址:820
    0x00 40 00 81  

    我将受到 Vsup 和 UVccout 欠压、但我用示波器对这两个器件进行了探测、并且它们从不低于所需值。 我不确定为什么此错误会继续出现。 这是否会阻止通过 CAN 发送消息?  

    谢谢!  

    阿利

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

    大家好、

    我找到了几点、而且我已经能够设置 TCAN4550EVM、使其在环回模式下向自己发送和接收消息。  希望这些更改也会对您有用。

    您是否将 TCAN4550EVM 用作电路板、还是其他一些板上装有 TCAN4550?

    我注意到您在寄存器0x0800中将 INH_DIS 位设置为"1"。  这会禁用连接到 TCAN4550EVM 上 LDO 的禁止(INH)引脚、该 LDO 为收发器提供 VIO。  如果您使用的是 EVM、这会禁用设置数字 IO 电平的 VIO 电压并为晶体振荡器供电。  我建议将 INH_DIS 位保持在其默认值"0"上。  这也可能是导致欠压误差的原因。

    您还在寄存器0x0800中将 TEST_MODE_EN 位设置为"1"。  这实际上是一种与我们要用于 MCAN 环回测试模式不同的测试模式。  启用此测试模式将会隔离 MCAN 控制器与收发器、并将内部 TX 和 RX 信号路由至 GPIO1和 GPO2引脚。  这很容易被误解、因此我们需要将寄存器0x0800中的 TEST_MODE_EN 位设置回"0"。

    因此、寄存器0x0800的最终值应为0xC80004AA。

    我还认为 TX 缓冲器 MRAM 存在地址错误。  似乎您正在将消息的第三个字写入0x827C 并跳过0x82778存储器位置。  地址应处于偏移量"4"中。  这将导致传输不正确的数据、并且您还将有一些数据覆盖下一个 TX 缓冲区元素中的第一个字。

     //尝试写入 TX 缓冲器
     setRegister (0x8270TXbuffer14);
     setRegister (0x8274TXbuffer24);
     setRegister (0x827CTXbuffer34);
     setRegister (0x8280TXbuffer44);
     setRegister (0x10D0TXBAR4);//检查10cc 以查看位是否已正确设置
    [/报价]

    您应该写入以下4个 MRAM 地址:0x8270、0x8274、0x8278和0x827C。

    我的最后一个观察结果是关于零 MRAM 函数。  在我看来、您将地址递增8个字节、而不是4个字节。  如果您每次通过此循环时只写入4个字节或1个字的零、则可能实际正在清除 MRAM 中的每一个其他字。

     //零 MRAM
      CURR_ADDRESS = 0x8000
     while (CURR_ADDRESS < 0x8500){
      setRegister (CURR_ADDRESS清除4);
      CURR_ADDRESS = CURR_ADDRESS + 8
     }
    [/报价]

    您可能需要验证此循环的最后一行是否应为:

    CURR_ADDRESS = CURR_ADDRESS + 4;

    对您提供的寄存器值进行这些调整后、我能够看到 TXBTO.TO0位设置为1、这表示从 TX 缓冲区0发送了一条消息。  我能够看到、MCAN 中断寄存器0x1050中的 RXF0N (位0)设置为"1"、表示接收到新消息。

    请告诉我、这是否可以解决您的问题。

    此致、

    乔纳森

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

    尊敬的 Jonathan:

    感谢您发送编修。 很遗憾、我的问题仍未解决。 我不使用  TCAN4550EVM、我使用的 是定制板、因此可能问题在于硬件。 我禁用 INH 引脚的原因是、它在我们的硬件设置中保持悬空。 这会导致问题吗? 我探测了振荡器引脚、它仍然似乎在提供输出。  

    我有一个 EVM 板、因此我将在下周结束时对该设置的代码进行尝试(在此之前我会处于关闭状态)、然后我会报告回来的情况!  

    非常感谢您在过去几天的帮助、这对我了解这款芯片的工作原理有很大帮助。

    此致、

    阿利  

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

    大家好、

    如果 INH 引脚未使用、则可以禁用该引脚。  它在 EVM 上使用、所以它导致了我的问题、我想它也可能会导致您的问题。  如果您在使 EVM 正常工作方面遇到困难、敬请告知、因为我一定会为您提供帮助。  如果您愿意、我也可以查看定制电路板原理图的 TCAN4550部分。  如果您希望我这样做、但不想在此论坛上发布、请告诉我、我可以通过电子邮件直接与您联系。

    此致、

    乔纳森

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

    那将会很好! 是的、如果您可以通过首选的电子邮件与我联系。  

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

    我已经向您发送了一封电子邮件、地址是您用于注册 E2E 帐户的地址、您可以使用它与我分享原理图以供查阅。

    此致、

    乔纳森