#include "XTDriver.h" #include "hardware/adc_cfg.h" #include "hardware/timer_cfg.h" uint32_t XT_SquareCount = 0; //发送载波个数 uint16_t XT_FreeBackMaxCur,XT_FreeBackMinCur,XT_FreeBackMaxTime,XT_FreeBackMinTime,XT_CommEndMaxCur; uint8_t XT_EnFreeBack_Test,XT_CommEnd_CurEn; volatile uint8_t XT_SendSquareFlag = 1; //发送方波标志 volatile uint8_t XT_ReadUIDFlag = 1; //扫描标志 #if XT_Read_AD_Sample_C > FIREBUS_ADC_BUF_LEN #error "JQDriver.c Firbus AD Sample BUFFER SIZE LIMIT" #else volatile uint16_t* XT_ADC_Buf = FireBus_ADC_Buf;//AD采样缓存区 #endif volatile uint8_t XT_ADCCollectStartFlag = 1; //ADC采集标志 uint32_t XT_ADC_BaseValue = 0; //ADC采集最低电压 uint32_t XT_ADC_CollectValue_sum = 0; //ADC采集电压和 #define XT_FreeBack_Noise 800 //static uint32_t XT_ADCCollectIncrementValue = XTCollectIncrementValue; //static uint32_t XT_ADCCollectSumValue = XTCollectSumValue; //static uint32_t XT_TIMCollectTimerOverflowUs = XTCollectTimerOverflowUs; //static uint32_t XT_ADCSingleCollectAckValue = XTSingleCollectAckValue; //static CurrentSample_Range_eu XT_CollectResistance = XTCollectResistance; /* @brief 通信反码信息初始化 */ void XT_FreeBack_Prapare(uint8_t enable_flag) { XT_FreeBackMaxCur = 0; XT_FreeBackMaxTime = 0; XT_FreeBackMinCur = 0xFFFF; XT_FreeBackMinTime = 0xFFFF; XT_EnFreeBack_Test = enable_flag; } static void XT_CommBegin() { CurrentSampleR_Def; WaitDelayEnd(50);//5ms } static void XT_CommEnd() { uint16_t us_temp; StartDelayTime(); if(XT_CommEnd_CurEn > 0) { delay_os_ms(10); us_temp = ADC_Comm1p6mA_EndCur(); if(us_temp > XT_CommEndMaxCur) { XT_CommEndMaxCur = us_temp; } } CurrentSampleR_Def; } static void XT_SendBit(uint8_t bit) { uint8_t i; if( bit == XTBIT0 ) { for(i=0;i<5;i++) { XTBUS_W_0; delay_us(XT_DAT_PLUS_T); XTBUS_W_1; delay_us(XT_DAT_PLUS_T); } delay_us(XT_BIT_DELAY); //位结束符 } else if( bit == XTBIT1) { for(i=0;i<3;i++) { XTBUS_W_0; delay_us(XT_DAT_PLUS_T); XTBUS_W_1; delay_us(XT_DAT_PLUS_T); } delay_us(XT_BIT_DELAY); //位结束符 } } static void XT_SendData(uint8_t *DownData, uint8_t DownLength) { uint8_t temp,i,j; XT_CommBegin(); //发送数据 for(i=0;i> 7) & 0x01 ); temp <<= 1; } } } volatile uint8_t XT_Trim_Flag = 0; static void XT_TrimPlusCallback(uint8_t flag) { if(flag == 1) { XTBUS_W_0; }else if(flag > 1){ XTBUS_W_1; } XT_Trim_Flag = flag; } static void XT_SendTrimSquare(uint16_t cycle,uint16_t duty, uint32_t count) { delay_us(XTCmdAndSquareUs); FireBus_ClkAmend(cycle,duty,count,XT_TrimPlusCallback); XT_Trim_Flag = 0; while(XT_Trim_Flag != 3) { delay_ms(20); } } /* @brief 直接反馈模式 @param timeoutcnt 回读超时时间 单位0.1ms @param ConfirmAckCount ADC 采样确认个数 @param *executiontime */ static uint8_t XT_Get_Ack(uint32_t timeoutcnt, uint8_t ConfirmAckCount,uint32_t *executiontime) { uint32_t FeekValue=0,count=0; uint32_t ul_readtime = 0,ul_runtime = 0; uint8_t rtv = 1; LED1_Out_On; TimerCount_Init(); Get100usCount(); Power_SetSampleRange_Seep(XTDriver_Sample_R,ADC_SPEED_HFAST); //延时700us delay_us(XTCmdAndSquareUs); // XT_ADC_BaseValue = 0; // while(us_temp < 64) // { // XT_ADC_BaseValue += ADC_GetCurADCFast(); // } // XT_ADC_BaseValue = (XT_ADC_BaseValue>>6) + XT_FreeBack_Noise; XT_ADC_BaseValue = XT_FreeBack_Noise; while(ul_runtime < timeoutcnt) { FeekValue = ADC_GetCurADCFast(); if(FeekValue >= XT_ADC_BaseValue) { count++; } else { count=0; } if(count>=ConfirmAckCount) { *executiontime = ul_readtime + GetCountTimerCnt(); rtv = 0; break; } ul_runtime = GetCountTimerCnt(); if(ul_runtime > 60000) { ul_readtime += Get100usCount(); ul_runtime = 0; } ul_runtime = ul_readtime+ul_runtime; } LED1_Out_Off; XTBUS_IDLE; Power_SetSampleCurrentRange(Current_Max); XT_CommEnd(); return rtv; } static void XT_ReceiveData(uint8_t *UpData, uint32_t ReceiveBitLength) { uint8_t uc_data; uint32_t ul_readcount,ul_adv_sum; uint16_t us_adccount ,us_index,us_ack_count; XTBUS_RWIDLE; delay_us(XTCmdAndSquareUs); Power_SetSampleRange_Seep(XTDriver_Sample_R,ADC_SPEED_HIGH); UpData[0] = 0; XTBUS_WR_0; delay_us(500); ul_readcount = 0; while( ul_readcount < ReceiveBitLength) { if((ul_readcount & 0x07) == 0) { uc_data = 0; } XTBUS_WR_1; delay_us(120); for(us_adccount = 0; us_adccount < XT_Read_AD_Sample_C; us_adccount++) { XT_ADC_Buf[us_adccount] = ADC_GetCurADCFast(); } XTBUS_WR_0; for(us_index = 3; us_index < us_adccount; us_index ++) { if((XT_ADC_Buf[us_index] < XT_FreeBack_Noise) && (XT_ADC_Buf[us_index-1] < XT_FreeBack_Noise)) { break; } if((XT_ADC_Buf[us_index] < XT_ADC_Buf[us_index-2] ) && (XT_ADC_Buf[us_index-1] < XT_ADC_Buf[us_index-3])) { break; } } if(us_index >= us_adccount) { delay_us(450); continue; } us_ack_count = 0; ul_adv_sum = 0; while(us_index < us_adccount) { if(XT_ADC_Buf[us_index] > XT_FreeBack_Noise) { ul_adv_sum += XT_ADC_Buf[us_index]; us_ack_count++; }else if(us_ack_count < 2)//连续两个大于2启动检测 { ul_adv_sum = 0; us_ack_count = 0; } us_index++; } if(us_ack_count > 10) { ul_adv_sum = ul_adv_sum / us_ack_count; if( XT_EnFreeBack_Test > 0 ) { if(XT_FreeBackMaxCur == 0) { XT_FreeBackMaxCur = XT_FreeBackMinCur = ul_adv_sum; }else if(ul_adv_sum > XT_FreeBackMaxCur){ XT_FreeBackMaxCur = ul_adv_sum; }else if(ul_adv_sum < XT_FreeBackMinCur){ XT_FreeBackMinCur = ul_adv_sum; } if(XT_FreeBackMaxTime == 0) { XT_FreeBackMaxTime = XT_FreeBackMinTime = us_ack_count; }else if(us_ack_count > XT_FreeBackMaxTime) { XT_FreeBackMaxTime = us_ack_count; }else if(us_ack_count < XT_FreeBackMinTime){ XT_FreeBackMinTime = us_ack_count; } } uc_data |= (0x80 >> (ul_readcount & 0x07)); } UpData[ul_readcount>>3] = uc_data; ul_readcount++; delay_us(300); } XTBUS_RWIDLE XT_CommEnd(); } static void XT_ScanUID(uint8_t *UpData, uint32_t ReceiveBitLength) { uint8_t uc_data; uint32_t ul_readcount; uint16_t us_adccount,us_index2,us_index3; uint16_t us_ack_count; uint16_t us_sum1,us_sum2,us_minSum = 0xFFFF; XTBUS_RWIDLE; delay_us(XTCmdAndSquareUs); Power_SetSampleRange_Seep(XTDriver_Sample_R,ADC_SPEED_HFAST); UpData[0] = 0; XTBUS_WR_0; delay_us(500); ul_readcount = 0; while( ul_readcount < ReceiveBitLength) { if((ul_readcount & 0x07) == 0) { uc_data = 0; } XTBUS_WR_1; delay_us(120); us_sum1 = 0; us_sum2 = 0; for(us_adccount = 0; us_adccount < 8; us_adccount++) { XT_ADC_Buf[us_adccount] = ADC_GetCurADCFast(); if(us_adccount < 4) { us_sum1 += XT_ADC_Buf[us_adccount]; us_index2 = us_adccount; }else{ us_sum2 += XT_ADC_Buf[us_adccount]; us_index3 = us_adccount; } } us_ack_count = 0; while(us_adccount < 160 && us_ack_count < 5) { if(us_sum1 < us_minSum) { us_minSum = us_sum1; } if(us_sum2 > (us_minSum + (XT_FreeBack_Noise << 2))) { us_ack_count++; }else{ us_ack_count = 0; } us_sum1 -= XT_ADC_Buf[(us_index2-3)&0x07]; us_sum2 -= XT_ADC_Buf[(us_index3-3)&0x07]; us_adccount++; XT_ADC_Buf[us_adccount & 0x07] = ADC_GetCurADCFast(); us_index2++; us_index3++; us_sum1 += XT_ADC_Buf[us_index2&0x07]; us_sum2 += XT_ADC_Buf[us_index3&0x07]; } if(us_ack_count < 5) { delay_us(600); XTBUS_WR_0; delay_us(300); }else{ XTBUS_WR_0; delay_us(800); uc_data |= (0x80 >> (ul_readcount & 0x07)); } UpData[ul_readcount>>3] = uc_data; ul_readcount++; } XTBUS_RWIDLE XT_CommEnd(); } static uint8_t XT_CalCRC(uint8_t data[], uint8_t length) { uint8_t c=0,temp,crc[8] = {0},nextcrc[8] = {0}; uint8_t i,j,k; for(i=0;i> (7-j)) & 0x1; nextcrc[0] = temp ^ crc[7]; nextcrc[1] = temp ^ crc[0] ^ crc[7]; nextcrc[2] = temp ^ crc[1] ^ crc[7]; nextcrc[3] = crc[2]; nextcrc[4] = crc[3]; nextcrc[5] = crc[4]; nextcrc[6] = crc[5]; nextcrc[7] = crc[6]; for(k=0;k<8;k++) { crc[k] = nextcrc[k]; } } } for(i=0;i<8;i++) { c += crc[i]<>6); *(adcvalue+1) = (RData[6]<<4) + (RData[7]>>4); *(adcvalue+2) = (RData[7]<<6) + (RData[8]>>2); return 0; } //函数名称:测量储能电容 //函数参数: //函数功能:UID正确且CRC校验通过时,将电容电压比较器档位设定为LEVEL指定的档位, // 并打开恒流源开关,关闭放电开关进行充电。充电完成时发出反馈,并关闭恒流源开关,打开放电开关。 //函数返回:充电时间 uint8_t XT_Measure_Cap(uint8_t *uid, uint8_t uidlen, uint8_t level, uint32_t *chargetime) { uint8_t SData[16]; SData[0] = XT_CMDA_MEASURE_CAP; memcpy(SData+1,uid,uidlen); SData[uidlen+1] = level; SData[uidlen+2] = XT_CalCRC(SData,uidlen+2); XT_SendData(SData,uidlen+3); return XT_Get_Ack(*chargetime, XTConfirmAckCount, chargetime); } //函数名称:单发充电 //函数参数: //函数功能:UID正确且CRC校验通过时,将电容电压比较器档位设定为LEVEL指定的档位, // 将当前充满电标志位复位,并打开充电开关,关闭放电开关进行充电。充电完成时发出反馈,并将曾充满电标志位、当前充满电标志位置位。 // LEVEL:0x11-1V、0x22-4V、0x33-6V、0x44-10V、0x55-12V、0x66-14V、0x77-18V、0x88-22V、0x99-26V //函数返回:是否充满 uint8_t XT_Charge_One(uint8_t *uid,uint8_t uidlen, uint8_t level,uint16_t busvoltage, uint8_t isgetack) { uint8_t SData[16]; uint32_t chargetime=0; uint8_t chargeresult =1; SData[0] = XT_CMDA_CHARGE; memcpy(SData+1,uid,uidlen); SData[uidlen+1] = level; SData[uidlen+2] = XT_CalCRC(SData,uidlen+2); XT_SendData(SData,uidlen+3); PowerCalibration_set(busvoltage,XTCOMMMEDIUMVOLTAGE); //修改总线电压 if(!isgetack || level == 0x00) { return 0; } //XT_GetAckInit(); chargeresult = XT_Get_Ack(XTSingleCollectAckTimerOverflowCnt, XTConfirmAckCount, &chargetime); return chargeresult; } /****************************************** * * B类指令(广播指令) * *******************************************/ //函数名称:清除已读状态 //函数参数: //函数功能:UID已读标志位复位。 //函数返回: void XT_Clear_Read(void) { uint8_t SData[2]; SData[0] = XT_CMDB_CLEAR_READH; SData[1] = XT_CMDB_CLEAR_READL; XT_SendData(SData,2); } //函数名称:起爆 //函数参数: //函数功能:若起爆密码验证通过标志位、延期标定完成标志位、曾充满电标志位均为1, // 则设置电容电压比较器档位为最低档位,并进入延期状态。延期倒计时归零时,进行起爆前反馈,然后逐位翻转起爆控制信号。之后进行起爆后反馈。若上述标志位不均为1,则对芯片进行复位,效果同软件复位指令相同 //函数返回: void XT_Fire() { uint8_t SData[2]; SData[0] = XT_CMDB_FIREH; SData[1] = XT_CMDB_FIREL; XT_SendData(SData,2); } uint8_t XT_FireandCheck(uint8_t *delay) //delay 3字节 最大的延期时间 { uint8_t SData[2]; uint8_t fireresult = 1; uint32_t timeout=0; uint32_t delay_max=0; delay_max = (*delay<<16) + (*(delay+1)<<8) + (*(delay+2)); timeout = delay_max*10+5000; SData[0] = XT_CMDB_FIREH; SData[1] = XT_CMDB_FIREL; XT_SendData(SData,2); fireresult = XT_Get_Ack(timeout, 2, &delay_max); return fireresult; } uint8_t XT_MeasureFire(uint32_t *delay) { uint8_t SData[2]; uint8_t fireresult = 1; uint32_t timeout=0; uint32_t delay_max=0; delay_max = *delay+2; timeout = delay_max*10+5000; SData[0] = XT_CMDB_FIREH; SData[1] = XT_CMDB_FIREL; XT_SendData(SData,2); fireresult = XT_Get_Ack(timeout, 2, delay); return fireresult; } //函数名称:初始化 //函数参数: //函数功能:初始化寄存器。 //函数返回: void XT_Init(uint8_t regdata) { uint8_t SData[3]; SData[0] = XT_CMDB_INITH; SData[1] = XT_CMDB_INITL; SData[2] = regdata; XT_SendData(SData,3); } //函数名称:软件复位 //函数参数: //函数功能:对芯片进行复位,2,000时钟周期后可以继续接收指令。 //函数返回: void XT_Reset() { uint8_t SData[2]; SData[0] = XT_CMDB_RESETH; SData[1] = XT_CMDB_RESETL; XT_SendData(SData,2); } //函数名称:扫描 //函数参数: //函数功能:读出UID、编号值、延期值、孔位值、状态字节。使用防冲突机制,当重复发送该指令时,所有在线的雷管会按照UID顺序从大到小依次反馈。 // 指令码长度为2字节,UID长度为7~13字节,编号值长度为2字节,延期值长度为3字节,孔位值长度为2字节,状态字节长度为1字节 //函数返回:UID、编号值、延期值、孔位值、状态字节 uint8_t XT_Read_Uid(uint8_t *uid, uint8_t uidlen) { uint8_t SData[2]; SData[0] = XT_CMDB_READ_UIDH; SData[1] = XT_CMDB_READ_UIDL; XT_SendData(SData,2); //XT_ReceiveData(uid,((uint32_t)uidlen<<3)+66); XT_ScanUID(uid,((uint32_t)uidlen<<3)+66); if(*(uid+uidlen+8) & 0x80) return 0; else return 1; } //函数名称:快速延期标定 //函数参数: //函数功能:翻转信号接收模块的识别极性,起爆器会以正常通信相反的极性发送该指令,以控制极性识别错误的雷管恢复正确极性。 //函数返回: void XT_Trim_Fast(void) { XT_Trim_Faset_Cycle(1000,500); } void XT_Trim_Faset_Cycle(uint16_t cycle,uint16_t duty) { uint8_t SData[2]; SData[0] = XT_CMDB_TRIM_FASTH; SData[1] = XT_CMDB_TRIM_FASTL; XT_SendData(SData,2); XT_SendTrimSquare(cycle,duty,1026); } //函数名称:完整延期标定 //函数参数: //函数功能:标定第1个方波下降沿至第(DELAY+1)个方波下降沿所对应的时钟周期数,并写入TIMER模块的计数器中。标定完成标志位置位。 //函数返回: void XT_Trim_Complete(uint32_t delay_max) { XT_Trim_Complete_Cycle(1000,500,delay_max); } void XT_Trim_Complete_Cycle(uint16_t cycle,uint16_t duty, uint32_t delay_max) { uint8_t SData[2]; SData[0] = XT_CMDB_TRIM_COMPLETEH; SData[1] = XT_CMDB_TRIM_COMPLETEL; XT_SendData(SData,2); XT_SendTrimSquare(cycle,duty,delay_max); } //函数名称:在线检测 //函数参数: //函数功能:指令后发送数量等于最大编号值的方波,每发雷管对方波进行计数,在计数到自己的编号值所对应的方波时,反馈1 //函数返回: uint8_t XT_Check_Online(uint16_t index_max, uint8_t *online) { uint8_t SData[2]; SData[0] = XT_CMDB_CHECK_ONLINEH; SData[1] = XT_CMDB_CHECK_ONLINEL; XT_SendData(SData,2); XT_ReceiveData(online, index_max+8); return 0; } //函数名称:验证起爆密码 //函数参数: //函数功能:验证起爆密码。验证正确时反馈并将起爆密码验证通过标志位置位,否则不反馈 //函数返回: uint8_t XT_Check_Bmid(uint8_t *bmid, uint8_t bmidlen) { uint8_t SData[10],RData[1]={0}; SData[0] = XT_CMDB_CHECK_BMIDH; SData[1] = XT_CMDB_CHECK_BMIDL; memcpy(SData+2,bmid,bmidlen); XT_SendData(SData,2+bmidlen); XT_ReceiveData(RData, 1); if(*RData & 0x80) return 0; else return 1; } //函数名称:获取全部验证状态 //函数参数: //函数功能:若曾充满电标志位、延期标定完成标志位、起爆密码验证通过标志位均为1则不反馈,否则反馈 //函数返回: uint8_t XT_Check_Fire_All(void) { uint8_t SData[2],RData[1]={0}; SData[0] = XT_CMDB_CHECK_FIRE_ALLH; SData[1] = XT_CMDB_CHECK_FIRE_ALLL; XT_SendData(SData,2); XT_ReceiveData(RData, 1); if(*RData & 0x80) return 1; else return 0; } //函数名称:逐发获取验证状态 //函数参数: //函数功能:指令后发送数量等于最大编号值的方波。 // 每发雷管对方波进行计数,在计数到自己的编号值所对应的方波时, // 若当前充满电标志位、延期标定完成标志位、起爆密码验证通过标志位均为1则反馈,否则不反馈 //函数返回: uint8_t XT_Check_Fire_Each(uint32_t index_max, uint8_t *check) { uint8_t SData[2]; SData[0] = XT_CMDB_CHECK_FIRE_EACHH; SData[1] = XT_CMDB_CHECK_FIRE_EACHL; XT_SendData(SData,2); XT_ReceiveData(check, index_max); return 0; } //函数名称:设置反馈电流大小 //函数参数: //函数功能:CRC校验通过时,将SETTING常驻寄存器的[3:2]位改为LEVEL所指定的档位。不改变EEPROM。若要改变EEPROM,应使用写配置区指令。 //函数返回: void XT_Set_Current(uint8_t level) { uint8_t SData[3]; SData[0] = XT_CMDB_SET_CURRENTH; SData[1] = level; SData[2] = XT_CalCRC(SData,2); XT_SendData(SData,3); } //函数名称:广播充电 //函数参数: //函数功能:CRC校验通过时,将电容电压比较器档位设定为LEVEL指定的档位,将当前充满电标志位复位, // 并打开充电开关,关闭放电开关进行充电。充电完成时将曾充满电标志位、当前充满电标志位置位。 // LEVEL:0x11-1V、0x22-4V、0x33-6V、0x44-10V、0x55-12V、0x66-14V、0x77-18V、0x88-22V、0x99-26V //函数返回: void XT_Charge_All(uint8_t level) { uint8_t SData[3]; SData[0] = XT_CMDB_CHARGE; SData[1] = level; SData[2] = XT_CalCRC(SData,2); XT_SendData(SData,3); } //函数名称:检查配置区 //函数参数: //函数功能:CRC校验通过时,若配置区中的UID/起爆密码长度及版本号两个字段同指令中的值相同则不反馈,否则反馈 //函数返回: uint8_t XT_Check_Config(uint8_t *config) { uint8_t SData[4],RData[1]={0}; SData[0] = XT_CMDB_CHECK_CONFIG; SData[1] = *(config); SData[2] = *(config+1); SData[3] = XT_CalCRC(SData,3); XT_SendData(SData,4); XT_ReceiveData(RData, 1); if(*RData & 0x80) return 1; else return 0; } /****************************************** * * C类指令(测试指令) * *******************************************/ //函数名称:写UID //函数参数: //函数功能:将UID写入EEPROM。写入完成后有反馈 //函数返回: uint8_t XT_Write_Uid(uint8_t *uid, uint8_t uidlen) { uint8_t SData[14]; uint32_t writetime=0; SData[0] = XT_CMDC_WRITE_UID; memcpy(SData+1,uid,uidlen); XT_SendData(SData,uidlen+1); return XT_Get_Ack(XTWriteBitTimerOverflowCnt, XTConfirmAckCount, &writetime); } //函数名称:写起爆密码 //函数参数: //函数功能:将起爆密码写入EEPROM。写入完成后有反馈 //函数返回: uint8_t XT_Write_Bmid(uint8_t *bmid, uint8_t bmidlen) { uint8_t SData[9]; uint32_t writetime=0; SData[0] = XT_CMDC_WRITE_BMID; memcpy(SData+1,bmid,bmidlen); XT_SendData(SData,bmidlen+1); return XT_Get_Ack(XTWriteBitTimerOverflowCnt, XTConfirmAckCount, &writetime); } //函数名称:写管壳码 //函数参数: //函数功能:将管壳码写入EEPROM。写入完成后有反馈 //函数返回: uint8_t XT_Write_Shell(uint8_t *shell) { uint8_t SData[14]; uint32_t writetime=0; SData[0] = XT_CMDC_WRITE_SHELL; memcpy(SData+1,shell,13); XT_SendData(SData,14); return XT_Get_Ack(XTWriteBitTimerOverflowCnt, XTConfirmAckCount, &writetime); } //函数名称:写现场值_C //函数参数: //函数功能:将编号值、延期值、孔位值写入EEPROM。写入完成后有反馈。编号值长度为2字节,延期值长度为3字节,孔位值长度为2字节 //函数返回: uint8_t XT_Write_Field_All(uint8_t *field) { uint8_t SData[8]; uint32_t writetime=0; SData[0] = XT_CMDC_WRITE_FIELD; memcpy(SData+1,field,13); XT_SendData(SData,8); return XT_Get_Ack(XTWriteBitTimerOverflowCnt, XTConfirmAckCount, &writetime); } //函数名称:写配置区 //函数参数: //函数功能:将LEN、SETTING、REV写入EEPROM及相应的常驻寄存器。写入完成后有反馈 //函数返回: uint8_t XT_Write_Config(uint8_t *config) { uint8_t SData[4]; uint32_t writetime=0; SData[0] = XT_CMDC_WRITE_CONFIG; memcpy(SData+1,config,3); XT_SendData(SData,4); return XT_Get_Ack(XTWriteBitTimerOverflowCnt, XTConfirmAckCount, &writetime); } //函数名称:写测量参数值 //函数参数: //函数功能:将CCSC、AMP、R1、Rdson写入EEPROM。写入完成后有反馈 //函数返回: uint8_t XT_Write_Param(uint8_t *param) { uint8_t i,SData[5]; uint32_t writetime=0; SData[0] = XT_CMDC_WRITE_PARAM; for(i=0;i<4;i++) { SData[i+1] = *(param+i); } memcpy(SData+1,param,4); XT_SendData(SData,5); return XT_Get_Ack(XTWriteBitTimerOverflowCnt, XTConfirmAckCount, &writetime); } //函数名称:测量储能电容C //函数参数: //函数功能:UID正确且CRC校验通过时,将电容电压比较器档位设定为LEVEL指定的档位,并打开恒流源开关,关闭放电开关进行充电。充电完成时发出反馈,并关闭恒流源开关,打开放电开关。 //函数返回:充电时间 uint8_t XT_Measure_Cap_All(uint8_t level, uint32_t *chargetime) { uint8_t SData[2]; SData[0] = XT_CMDC_MEASURE_CAP; SData[1] = level; XT_SendData(SData,2); return XT_Get_Ack(*chargetime, XTConfirmAckCount, chargetime); } //函数名称:锁定 //函数参数: //函数功能:向EEPROM中LOCK字段写入0x8B,锁定标志位置位。写入完成后有反馈。锁定后C类指令不再识别,仅可写入现场值 //函数返回: void XT_Lock(void) { uint8_t SData[1]; SData[0] = XT_CMDC_LOCK; XT_SendData(SData,1); delay_us(700); XTBUS_W_0; delay_us(500); XTBUS_W_1; delay_os_ms(50); } //函数名称:读测量参数值_C //函数参数: //函数功能:读出CCSC、AMP、R1、Rdson //函数返回: uint8_t XT_Read_Param_All(uint8_t *param) { uint8_t SData[1]; SData[0] = XT_CMDC_READ_PARAM; XT_SendData(SData,1); XT_ReceiveData(param, 34); if(*(param+4) & 0x80) return 0; else return 1; } //函数名称:读配置区 //函数参数: //函数功能:读出CKCFG、LEN、SETTING、REV //函数返回: uint8_t XT_Read_Config(uint8_t *config) { uint8_t SData[1]; SData[0] = XT_CMDC_READ_CONFIG; XT_SendData(SData,1); XT_ReceiveData(config, 34); if(*(config+4) & 0x80) return 0; else return 1; } //函数名称:读管壳码_C //函数参数: //函数功能:读出管壳码。管壳码长度为13字节。反馈完成后会继续反馈一位1作为结束符 //函数返回: uint8_t XT_Read_Shell_All(uint8_t *shell) { uint8_t SData[1]; SData[0] = XT_CMDC_READ_SHELL; XT_SendData(SData,1); XT_ReceiveData(shell, 106); if(*(shell+13) & 0x80) return 0; else return 1; } //函数名称:测量药头电阻_C //函数参数: //函数功能:收到指令时打开药头电阻测量电路开关。等待40个载波后,发出ADC复位信号,再经过1个载波后,发出开始ADC采样信号,随后的8个载波中反馈ADC采样的值。然后再发出ADC复位信号,如上重复三次 //函数返回: uint8_t XT_Measure_Res_All(uint8_t *adcvalue) { uint8_t SData[1],RData[9]={0}; SData[0] = XT_CMDC_MEASURE_RES; XT_SendData(SData,1); XT_ReceiveData(RData, 70); *adcvalue = (RData[5]<<2) + (RData[6]>>6); *(adcvalue+1) = (RData[6]<<4) + (RData[7]>>4); *(adcvalue+2) = (RData[7]<<6) + (RData[8]>>2); return 0; } uint8_t XT_Get_UID_R(uint8_t *uid, uint8_t uidlen) //算桥丝电阻 { uint8_t adcvalue[3]; uint16_t qsadc=0,count=1; XT_Measure_Res(uid,uidlen,adcvalue); qsadc = adcvalue[1]; if(adcvalue[0]>0x00 && adcvalue[0]<0xF0) { qsadc += adcvalue[0]; count++; } if(adcvalue[2]>0x00 && adcvalue[2]<0xF0) { qsadc += adcvalue[2]; count++; } qsadc = qsadc / count; return (qsadc & 0xFF); // if(qsadc < 0xF0) // return 0; // else // return 1; } uint8_t XT_Get_R() //算桥丝电阻 { uint8_t adcvalue[3]; uint16_t qsadc=0,count=1; XT_Measure_Res_All(adcvalue); qsadc = adcvalue[1]; if(adcvalue[0]>0x00 && adcvalue[0]<0xF0) { qsadc += adcvalue[0]; count++; } if(adcvalue[2]>0x00 && adcvalue[2]<0xF0) { qsadc += adcvalue[2]; count++; } qsadc = qsadc / count; return (qsadc & 0xFF); // if(qsadc < 0xF0) // return 0; // else // return 1; } uint8_t XT_Get_UID_C(uint8_t *uid, uint8_t uidlen, uint8_t level, uint32_t time_out,float *CapacitanceValue) //算储能电容 { uint8_t exeresult=1; uint32_t chargetime=time_out; uint8_t param[5]={0}; float CSCC=0; exeresult = XT_Measure_Cap(uid, uidlen, level, &chargetime); if(exeresult) { return 1; } __disable_irq(); delay_ms(10); __enable_irq(); exeresult = XT_Read_Param(uid,uidlen, param); if(exeresult) { return 1; } CSCC = 0.390625f * param[0] + 120; if(level == 0x11) { *CapacitanceValue = CSCC * chargetime /10000.0f; } else if(level == 0x22) { *CapacitanceValue = CSCC * chargetime / 40000.0f; } else if(level == 0x33) { *CapacitanceValue = CSCC * chargetime / 100000.0f; } return 0; } uint8_t XT_Get_C(uint8_t level,uint32_t time_out ,float *CapacitanceValue) //算储能电容 { uint8_t exeresult=1; uint32_t chargetime=time_out; uint8_t param[5]={0}; float CSCC=0; exeresult = XT_Measure_Cap_All(level, &chargetime); if(exeresult) { return 1; } delay_os_ms(20); exeresult = XT_Read_Param_All(param); if(exeresult) { return 1; } CSCC = 0.390625f * param[0] + 120; if(level == 0x11) { *CapacitanceValue = CSCC * chargetime /10000.0f; } else if(level == 0x22) { *CapacitanceValue = CSCC * chargetime / 40000.0f; } else if(level == 0x33) { *CapacitanceValue = CSCC * chargetime / 100000.0f; } return 0; }