热度 19
2013-1-5 18:09
2790 次阅读|
2 个评论
CAN的识别码计算与数字隔离器AduM1201的CAN总线连接 1. 我们使用 MCP2510/2515 作为 CAN CONTROLLER 使用, 因此文中提及的 CAN 识别码的计算, 应指与 2515 的相应ID register 的设定. 2. 之所以将这个不特别的问题, 在这里再次提出的原因是, 我们又怀着好奇的心理, 对另一款 CAN CONTROLLER, 即 SJA1000 的 ID register 进行了简单的熟悉. 那么与 MCP2515 的比较, 就变得明显而自然. 我们以 D1, D2, D3, D4 称呼 SJA 的 4个 ID Register, 对于标准帧和扩展帧, 分别列表(From SJA datasheet): Standard frame: 应对应 D1 D2 Sample: 如设定 0x01 0x00, 故应计算得 ID = 8 修改为 0x01 0x20, 应计算得 ID = 8 + 1 = 9 Extend Frame: 对应 D1 D2 D3 D4, Sample: 如设定 0x01 0x00 0x00 0x00, 故应计算得 ID = 0x200000 修改为 0x01 0x20 0x00 0x00, 计算得到 ID = 0x240000 修改为 0x01 0x20 0x80 0x00, 计算得到 ID = 0x240000 + 0x1000 = 0x241000 修改为 0x01 0x20 0x80 0x10, 计算得到 ID = 0x241000 + 0x2 = 0x241002 我们能够用简单用 SIDH SIDL EIDH EIDL 来称呼可能在 TX/RX Register 中出现的这4个相关 Register, 更直观的例子是下表(From MCP2515 datasheet): 明显的, MCP2515 有着自有的 ID 定义(也应该注意的是, 在这4个 Registers 中, 往往不仅仅只定义了ID, 而且包括扩展帧 Ext 标识位, 或者远程帧 RTR 标识位). 我们用下列代码进行理解:(Reference: http://wenku.baidu.com/view/50f17ea6f524ccbff12184ec.html) /* * mcp2510_write_can_ID * * Description: * Write CAN bus ID. * * Parameter: * address: register address * can_id: ID returned * Is请自己删除Ext: extend or standard ID * * Return: * TRUE: extend CAN * FALSE: standard CAN */ void mcp2510_write_can_ID(U8 address, U32 can_id, bool Is请自己删除Ext) { U8 tbufdata ; U32 canid = 0; if (Is请自己删除Ext) { // EID: can_id = 0x1fffffff; // 29-bit canid = can_id 0xffff; tbufdata = canid 0xff; tbufdata = canid 8; canid = can_id 16; tbufdata = canid 0x03; tbufdata += ((canid0x1c)3); tbufdata |= TXB_EXIDE_M; tbufdata = canid 5; } else{ // SID: can_id = 0x7ff; // 11-bit tbufdata = 0x00; tbufdata = 0x00; tbufdata = ((can_id0x07)5); tbufdata = can_id 3; } mcp2510_swrite(address, tbufdata, 4); // write ID to target address } /* * mcp2510_read_can_ID * * Description: * Read CAN bus ID. * * Parameter: * address: register address, which is 0x61 as RXB0SIDH * can_id: ID returned * * Sample: * RXB0SIDH(0x61) RXB0SIDL(0x62) RXB0EID8(0x63) RXB0EID0(0x64) * 0x01 0x00 0x00 0x00 * If standard: 0x01 0x00 means 0x08 * If Extend: 0x01 0x00 0x00 0x00 means 0x00200000 ((0x0816)2) * * Return: * TRUE: extend CAN * FALSE: standard CAN */ bool mcp2510_read_can_ID(U8 address, U32* can_id) { U8 tbufdata ; mcp2510_sread(address, tbufdata, 4); //uart0_put((char*)tbufdata, 4); // test // (tbufdata 3) - handle RXB0SIDH to build SID10:SID3(bit10:bit3) // ((tbufdata13)0x7) - handle RXB0SIDL to build SID2:SID1(bit2:bit0) *can_id = (tbufdata 3) | (tbufdata 5); *can_id = 0x7ff; // I am extend ID? if ( (tbufdata RXB_IDE_M) == RXB_IDE_M ) { // can_id = (SID10:SID0):(EID17:EID16) *can_id = (*can_id2) | (tbufdata 0x03); // ((SID10:SID0):(EID17:EID16))16 *can_id = 16; // ((SID10:SID0):(EID17:EID16)):(EID15:EID8):((EID7:EID0)) *can_id += (tbufdata 8) + tbufdata ; return TRUE; } // just the standard ID return FALSE; } 之所以要随手列出这个讨论议题的原因是, 我们在网络资源得到的电路图是错误的, 我们应该标记这个错误, 以避免同行在参考文献中迷失. 列出参考电路图(From http://wenku.baidu.com/view/eae20ad5c1c708a1284a4483.html): 我们阅读了 1201 的文档, 直觉该电路图可疑, 方向怀疑颠倒(TX 和 RX 都颠倒). 该电路图中 ADuM1201AR 用于, 隔离 CAN CONTROLLER(如 MCP2510/2515), 以及 CAN DRIVER(如 PCA82C250). 为了确认我们的怀疑, 我们进入 ADuM1201 的 ADI 公司官方网页( http://www.analog.com/zh/interface-isolation/digital-isolators/adum1201/products/product.html ), 尽管在 datasheet 与 应用手册中, 都没有 1201 直接用于 CAN 总线隔离的实际例子, 我们仍然可以从 AN-770 application note pdf( Download from this webpage ), 找到两个1100 单独隔离的例子: 在该例子的比较下, 我们确认上述网络资源中的 1201 的电路图的连接错误, 图例中, 1201 的 PIN6, PIN7 应该交换(TX, RX 交换), 同理, 另一端连接 CONTROLL 的 PIN2与PIN3 应交换(RXCAN 与 TXCAN) 交换. 在选用 MCP2510 与 MCP2515 的问题上, 常常给人带来迷思. 网络上曾经出现的大量资源, 都是 08 年左右的驱动 2510 的文章, 这让我们情不自禁选择了 MCP2510 的样品... 当然, 最后我们不得不换用 MCP2515 的过程, 产生了完全不必要的工程浪费. 原因完全在于我们没有仔细比较两个 datasheet, 让我们简单看看吧: 在 3.3v 的工作电压, 以及更高工作温度的压力下, SPI of 2510 的通讯速度表现为 2.5MHz. 但是, 在阅读了网络大量的使用心得后, 两份不同的资料, 指明 2510 可能只能达到的最高速度为 1M 左右, 有人说是 1.3MHz, 有人说是 1MHz. 当我们茫然地面对已经确认不可更改的 5.4MHz SPI 系统总线时(LCD屏显示需要较高速度), 我们不得不苦笑着用烙铁一根一根取下蜘网般的飞线, 并谨慎再次换上 2515 新样品(已经不想说买新样品和取货浪费的时间)``` 抬头看着窗外的斜阳, 我们的心情如同元旦期间出现在深圳的寒流般冷冰冰... 这是对一个工程师不勤于思考比较, 不作基础准备工作的惩罚咩? Allen 作于深圳福田 发表于 电子工程专辑