本帖最后由 cking616 于 2025-4-17 14:55 编辑
1. 修改 PDO 配置寄存器属性, 将 SDO 1600~1A00 的 PDO 配置寄存器属性修改为 "wr"(可读写)模式。
2. XML 配置文件设置, 确保以下配置参数正确设置:
[XML] 纯文本查看 复制代码
<Mailbox DataLinkLayer="true">
<CoE SdoInfo="true" PdoAssign="false" PdoConfig="true" CompleteAccess="true" SegmentedSdo="true" />
<FoE />
</Mailbox>
<RxPdo Fixed="false" Mandatory="true" Sm="2">
<TxPdo Fixed="false" Mandatory="true" Sm="3">
注意 `PdoConfig="true"` 必须设为 true, RxPdo`和 TxPdo`的 Fixed`属性必须设为 false
3. 实现代码上, Ethercat接口函数generateMap、Input、Output这几个函数重新实现,正确从SDO配置中提取PDO变量指针和大小,示例代码:
[C] 纯文本查看 复制代码
// 位操作辅助宏
#define GET_INDEX(val) (((val) & 0xFFFF0000) >> 16)
#define GET_SUBINDEX(val) (((val) & 0xFF00) >> 8)
#define GET_BITSIZE(val) ((val) & 0xFF)
#define BITS_TO_BYTES(bits) ((bits) >> 3)
uint16_t axisCtrlEcatMapGenerate(axisDataT *axisEcat,
uint16_t *pInputSize,
uint16_t *pOutputSize) {
uint16_t result = ALSTATUSCODE_NOERROR;
TOBJ1A00 *txpdoPtr = &axisEcat->txpdoTable; // 发送PDO表指针
TOBJ1600 *rxpdoPtr = &axisEcat->rxpdoTable; // 接收PDO表指针
uint16_t inputSize = 0, outputSize = 0;
uint32_t objIndex, objSubindex;
uint16_t size;
uint8_t *pVarPtr;
int i;
// 限制RxPDO数量
if (rxpdoPtr->u16SubIndex0 > MAX_RX_PDO)
rxpdoPtr->u16SubIndex0 = MAX_RX_PDO;
// 处理RxPDO映射
for (i = 0; i < rxpdoPtr->u16SubIndex0; i++) {
objIndex = GET_INDEX(rxpdoPtr->SI[i]);
objSubindex = GET_SUBINDEX(rxpdoPtr->SI[i]);
size = BITS_TO_BYTES(GET_BITSIZE(rxpdoPtr->SI[i]));
// 获取对象变量指针,失败则设为0
axisEcat->rxPdoVarPtr[i] = (getObjectVariable(objIndex, objSubindex, &pVarPtr) == 0) ? pVarPtr : 0;
axisEcat->rxPdoSize[i] = size;
outputSize += GET_BITSIZE(rxpdoPtr->SI[i]);
}
axisEcat->numOfRxPdo = rxpdoPtr->u16SubIndex0;
outputSize = BITS_TO_BYTES(outputSize); // 比特转字节
// 限制TxPDO数量
if (txpdoPtr->u16SubIndex0 > MAX_TX_PDO)
txpdoPtr->u16SubIndex0 = MAX_TX_PDO;
// 处理TxPDO映射
for (i = 0; i < txpdoPtr->u16SubIndex0; i++) {
objIndex = GET_INDEX(txpdoPtr->SI[i]);
objSubindex = GET_SUBINDEX(txpdoPtr->SI[i]);
size = BITS_TO_BYTES(GET_BITSIZE(txpdoPtr->SI[i]));
// 获取对象变量指针,失败则设为0
axisEcat->txPdoVarPtr[i] = (getObjectVariable(objIndex, objSubindex, &pVarPtr) == 0) ? pVarPtr : 0;
axisEcat->txPdoSize[i] = size;
inputSize += GET_BITSIZE(txpdoPtr->SI[i]);
}
axisEcat->numOfTxPdo = txpdoPtr->u16SubIndex0;
inputSize = BITS_TO_BYTES(inputSize); // 比特转字节
// 更新总大小
*pInputSize += inputSize;
*pOutputSize += outputSize;
return result;
}
uint32_t axisCtrlEcatOutput(axisDataT *axisEcat, uint8_t *pData) {
uint32_t size = 0;
// 复制接收PDO数据到目标变量
for (int i = 0; i < axisEcat->numOfRxPdo; i++) {
if (axisEcat->rxPdoVarPtr[i]) { // 非空指针检查
memcpy(axisEcat->rxPdoVarPtr[i], pData, axisEcat->rxPdoSize[i]);
}
pData += axisEcat->rxPdoSize[i];
size += axisEcat->rxPdoSize[i];
}
return size;
}
uint32_t axisCtrlEcatInput(axisDataT *axisEcat, uint8_t *pData) {
uint32_t size = 0;
// 复制来源变量数据到发送PDO
for (int i = 0; i < axisEcat->numOfTxPdo; i++) {
if (axisEcat->txPdoVarPtr[i]) { // 非空指针检查
memcpy(pData, axisEcat->txPdoVarPtr[i], axisEcat->txPdoSize[i]);
}
pData += axisEcat->txPdoSize[i];
size += axisEcat->txPdoSize[i];
}
return size;
}
[i][i][i][i][i][i][i][i][i][i][i][i][i][i][i][i][i][i][i][i][i][i][i][i][i][i][i][i][i][i][i][i][i][i][i][i]
关于 PDO 配置的存储,您可以选择以下几种方式:
1. 使用 SSC Tool 的存储功能并实现相应接口
2. 将 SDO 1600~1A00 对应的 SDO 配置保存,并在设备上电时载入
|