struct GeneralBatchIICData
{
uint8_t uiWRMode;//0:写入 1:读取
uint16_t uiSalvid;//器件地址
uint64_t uiReg;//reg
uint64_t uiValue;//value
uint16_t usType;//IIC模式 0x0808为8位地址8位值 0x1608为16位地址8位值 最大0x3232
int iDelayUs;//延时 单位us
bool bAck;//是否需要ACK
GeneralBatchIICData(){
bAck = true;
}
};
typedef std::basic_string<unsigned char, std::char_traits<unsigned char>, std::allocator<unsigned char> >
u8string;
DWORD CEmbeddedInterface::GeneralBatchIIC(int iCamType, int iCount, GeneralBatchIICData data[], int* iErrorIndex)
{
//组包
{
std::list<u8string> packetList;
for (int i = 0; i < iCount; i++)
{
u8string miniPacket;
GeneralBatchIICData& currentData = data[i];
unsigned int uiRegSize = 0, uiDataSize = 0;
unsigned char ucReg[8] = { 0 };
unsigned char ucData[8] = { 0 };
unsigned char ucSleep[4] = { 0 };
switch (currentData.usType & 0xff00) {
case 0x1600:
uiRegSize = 2;
ucReg[0] = (unsigned char)((currentData.uiReg >> 8) & 0xFF);
ucReg[1] = (unsigned char)(currentData.uiReg & 0xFF);
break;
case 0x3200:
uiRegSize = 4;
ucReg[0] = (unsigned char)((currentData.uiReg >> 24) & 0xFF);
ucReg[1] = (unsigned char)((currentData.uiReg >> 16) & 0xFF);
ucReg[2] = (unsigned char)((currentData.uiReg >> 8) & 0xFF);
ucReg[3] = (unsigned char)(currentData.uiReg & 0xFF);
break;
case 0x0800:
default:
uiRegSize = 1;
ucReg[0] = (unsigned char)(currentData.uiReg & 0xFF);
break;
}
switch (currentData.usType & 0xff) {
case 0x16:
uiDataSize = 2;
ucData[0] = (unsigned char)((currentData.uiValue >> 8) & 0xFF);
ucData[1] = (unsigned char)(currentData.uiValue & 0xFF);
break;
case 0x32:
uiDataSize = 4;
ucData[0] = (unsigned char)((currentData.uiValue >> 24) & 0xFF);
ucData[1] = (unsigned char)((currentData.uiValue >> 16) & 0xFF);
ucData[2] = (unsigned char)((currentData.uiValue >> 8) & 0xFF);
ucData[3] = (unsigned char)(currentData.uiValue & 0xFF);
break;
case 0x08:
default:
uiDataSize = 1;
ucData[0] = (unsigned char)(currentData.uiValue & 0xFF);
break;
}
int iSleep10Ns = max(2100, currentData.iDelayUs * 100);
ucSleep[0] = (unsigned char)((iSleep10Ns >> 24) & 0xFF);
ucSleep[1] = (unsigned char)((iSleep10Ns >> 16) & 0xFF);
ucSleep[2] = (unsigned char)((iSleep10Ns >> 8) & 0xFF);
ucSleep[3] = (unsigned char)(iSleep10Ns & 0xFF);
if (currentData.uiWRMode == 0)
{
//写入
int iPacketSize = 1 + 1 + 1 + uiRegSize + uiDataSize + 4;
miniPacket += (unsigned char)(iPacketSize & 0xFF);
if (currentData.bAck)
miniPacket += u8string(1, 0x00 | 0x02);
else
miniPacket += u8string(1, 0x00);
miniPacket += (uint8_t)currentData.uiSalvid;
miniPacket += u8string(ucReg, uiRegSize);
miniPacket += u8string(ucData, uiDataSize);
miniPacket += u8string(ucSleep, 4);
}
else if (currentData.uiWRMode == 1)
{
//读取
int iPacketSize = 1 + 1 + 1 + 1 + 4 + 4;
miniPacket += (unsigned char)(iPacketSize & 0xFF);
if (currentData.bAck)
miniPacket += u8string(1, 0x01 | 0x02);
else
miniPacket += u8string(1, 0x01);
miniPacket += (uiRegSize - 1) + (uiDataSize << 4);
miniPacket += (uint8_t)(currentData.uiSalvid | 0x01);
miniPacket += u8string(4 - uiRegSize, 0x00);
miniPacket += u8string(ucReg, uiRegSize);
miniPacket += u8string(ucSleep, 4);
}
else
{
AddString(iCamType, "index:%d,uiWRMode异常", i);
return 0x1000;
}
packetList.push_back(miniPacket);
}
u8string totalPacket;
totalPacket += (unsigned char)((iCount >> 8) & 0xFF);
totalPacket += (unsigned char)((iCount) & 0xFF);
std::list<u8string>::iterator it;
for (it = packetList.begin(); it != packetList.end(); ++it)
totalPacket += *it;
if (totalPacket.size() > 60000)
{
AddString(iCamType, "数据超过协议包最大上限60000");
return CurrencyErrCode_ParaErr;
}
//发包
int iOnceSendSize = 1000;//每次发送的字节数
int iTotalPacketIndex = 0;//总包中的Index
while (true)
{
bool bLastPacket = true;//是否为最后一个包 最后一个包发送0xff作为标志
unsigned char ucCommand[1024] = { 0 };
ucCommand[0] = 0x80;
ucCommand[1] = 0xac;
if (iCamType == 0)
ucCommand[4] = 2;
else
ucCommand[4] = 1;
int iMiniPacketIndex = 0;//分包的Index
while (iTotalPacketIndex < totalPacket.size())
{
ucCommand[6 + iMiniPacketIndex] = totalPacket[iTotalPacketIndex];
iMiniPacketIndex++;
iTotalPacketIndex++;
if (iTotalPacketIndex == totalPacket.size())
break;
if (iTotalPacketIndex % iOnceSendSize == 0)
{
bLastPacket = false;
break;
}
}
if (bLastPacket)
{
int uiDataLength = iMiniPacketIndex + 2;
ucCommand[2] = (unsigned char)((uiDataLength >> 8) & 0xFF);
ucCommand[3] = (unsigned char)((uiDataLength) & 0xFF);
ucCommand[5] = 0xFF;
}
else
{
int uiDataLength = iOnceSendSize + 2;
ucCommand[2] = (unsigned char)((uiDataLength >> 8) & 0xFF);
ucCommand[3] = (unsigned char)((uiDataLength) & 0xFF);
ucCommand[5] = iTotalPacketIndex / iOnceSendSize - 1;
}
int iErrorCode = EmbeddedBulkWriteCommunication(iCamType, ucCommand);
if (iErrorCode)
return iErrorCode;
if (bLastPacket)
break;
}
}
//收包
{
std::map<int, u8string> packetMap;
u8string totalPacket;
unsigned char ucWriteCommand[1024] = { 0 };
ucWriteCommand[0] = 0x80;
ucWriteCommand[1] = 0xad;
ucWriteCommand[2] = 0x00;
ucWriteCommand[3] = 0x01;
if (iCamType == 0)
ucWriteCommand[4] = 2;
else
ucWriteCommand[4] = 1;
unsigned char ucReadCommand[1024] = { 0 };
int iGetResult = 0;
while (true)
{
memset(ucReadCommand, 0, 1024);
int iErrorCode = EmbeddedBulkReadCommunication(iCamType, ucWriteCommand, ucReadCommand);
if (iErrorCode)
return iErrorCode;
iGetResult = ucReadCommand[5];//0:为已完成 1:为未完成 其他为失败
if (iGetResult == 0x01)
{
Sleep(2);
continue;
}
int iPacketSize = (ucReadCommand[2] << 8) + ucReadCommand[3] - 3;
int iPacketIndex = ucReadCommand[6];
packetMap[iPacketIndex] = u8string((ucReadCommand)+7, iPacketSize);
if (iPacketIndex == 0xff)
break;
}
//解包
std::map<int, u8string>::iterator it;
for (it = packetMap.begin(); it != packetMap.end(); ++it)
totalPacket += it->second;
int iTotalPacketIndex = 0;//总包中的Index
//获取第几个IIC指令异常
if (totalPacket.size() < 2)
{
AddString(iCamType, "返回值数据长度校验失败");
return CurrencyErrCode_IICErr;
}
if (iErrorIndex != nullptr)
*iErrorIndex = (((unsigned int)totalPacket[0]) << 8) + (((unsigned int)totalPacket[1]) << 0);
iTotalPacketIndex += 2;
//解析读取的IIC数据
for (int i = 0; i < iCount; i++)
{
GeneralBatchIICData& currentData = data[i];
if (currentData.uiWRMode == 1)
{
unsigned int uiDataSize = 0;
switch (currentData.usType & 0xff) {
case 0x16:
uiDataSize = 2;
break;
case 0x32:
uiDataSize = 4;
break;
case 0x08:
default:
uiDataSize = 1;
break;
}
if ((iTotalPacketIndex + uiDataSize - 1) > totalPacket.size())
{
AddString(iCamType, "返回值数据长度校验失败");
return CurrencyErrCode_IICErr;
}
switch (currentData.usType & 0xff) {
case 0x16:
currentData.uiValue = (((unsigned int)totalPacket[iTotalPacketIndex]) << 8)
+ (((unsigned int)totalPacket[iTotalPacketIndex + 1]) << 0);
break;
case 0x32:
currentData.uiValue = (((unsigned int)totalPacket[iTotalPacketIndex]) << 24)
wifibotπ
- 粉丝: 2
- 资源: 3
最新资源
- 网神SecIPS 3600入侵防御系统用户手册v1.2.doc
- 网神SecIPS 3600入侵防御系统产品白皮书-P5000-TG13M【V16.5.1】.docx
- 网神SecIPS 3600入侵防御系统产品白皮书-P3000-TE23P【V16.5.1】.docx
- 网神SecIPS 3600入侵防御系统产品白皮书-P5000-TG13P【V16.5.1】.docx
- 网神SecIPS 3600入侵防御系统产品白皮书-P5000-TG23M【V16.5.1】.docx
- 网神SecIPS 3600入侵防御系统产品白皮书-P9000-TG43M【V16.5.1】.docx
- 网神SecIPS 3600入侵防御系统产品白皮书-P9000-TG63M【V16.5.1】.docx
- 网神SecIPS 3600入侵防御系统产品白皮书-P9000-TZ23M【V16.5.1】.docx
- 网神SecIPS 3600入侵防御系统产品白皮书-P9000-TX13M【V16.5.1】.docx
- php接口实例:完成请求接口以及接口本身的写法,成功完成接口的调用,apisend为请求方;apireceive为接收方,接收方通过common方法进行函数封装,便于多接口写法
- Record_2025-01-15-17-45-30.mp4
- 西门子PLC1200伺服库卡机器人12工位 包括西门子PLC1200程序,昆仑通态触摸屏程序,详细中文注释,电路图,设备操作说明,物料BOM PLC和一台库卡机器人profinet通讯 PTO模式控制
- 《该代码基于YOLOv8,将识别锥桶和行人,并将判断越界范围》(毕业设计,源码,教程)简单部署即可运行。功能完善、操作简单,适合毕设或课程设计.zip
- 《YOLOv8 基于视觉的口罩使用情况检测》(毕业设计,源码,教程)简单部署即可运行。功能完善、操作简单,适合毕设或课程设计.zip
- 新型DCDC拓扑,电压增益大,包含储能光伏控制
- 将本地文件批量发送到远程服务器的shell.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈