Files
checker_slave/source/elec_det/driver/XTDriver.c
ranchuan bff9b1b774 V2.05
重写延时等待函数,解决与模块之间通信间隔有可能过短的问题
    修改硬件版本号时自动修改can波特率
2023-11-13 17:34:05 +08:00

1280 lines
30 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "XTDriver.h"
#include "hardware/adc_cfg.h"
#include "hardware/timer_cfg.h"
volatile uint32_t XT_SquareCount = 0; //发送载波个数
volatile uint16_t XT_FreeBackMaxCur,XT_FreeBackMinCur,XT_FreeBackMaxTime,XT_FreeBackMinTime,XT_CommEndMaxCur;
volatile 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采集标志
volatile uint32_t XT_ADC_BaseValue = 0; //ADC采集最低电压
volatile 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
//delay_ms(5);
delay_wait_untill_ms(5);
}
static void XT_CommEnd()
{
uint16_t us_temp;
//StartDelayTime();
TimerCount_Off();
delay_wait_start();
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<DownLength;i++)
{
temp = DownData[i] ;
for(j=0;j<8;j++)
{
XT_SendBit( (temp >> 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(1)
{
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;
if(ul_runtime >= timeoutcnt){
// time out
rtv = 2;
break;
}
}
LED1_Out_Off;
XTBUS_IDLE;
Power_SetSampleCurrentRange(Current_Max);
XT_CommEnd();
if(rtv){
rtv=!0;
}
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<length;i++)
{
for(j=0;j<8;j++)
{
temp = (data[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]<<i;
}
return c;
}
uint8_t XT_Power_Init()
{
uint8_t errorcode=0;
if(PowerCalibration_set(XTREGISTERVOLTAGE, XTCOMMMEDIUMVOLTAGE))
{
errorcode |= 0x1;
}
if(PowerCalibration_set(XTCOMMHIGHVOLTAGE, XTCOMMMEDIUMVOLTAGE))
{
errorcode |= 0x2;
}
if(PowerCalibration_set(XTCHARGEINSTRUCTIONVOLTAGE, XTCOMMMEDIUMVOLTAGE))
{
errorcode |= 0x4;
}
if(PowerCalibration_set(XTCHARGEVOLTAGE, XTCOMMMEDIUMVOLTAGE))
{
errorcode |= 0x8;
}
Power_SetSampleCurrentRange(Current_Max);
return errorcode;
}
void XT_BUS_CTRL( uint8_t NewState )
{
PowerCalibration_set(XTCOMMHIGHVOLTAGE, XTCOMMMEDIUMVOLTAGE);
if(NewState){
XTBUS_ON;
}else{
XTBUS_OFF;
}
}
//函数名称:写现场值
//函数参数:
//函数功能UID正确且CRC校验通过时将编号值、延期值、孔位值写入EEPROM。载波反馈1表示收到指令。编号值长度为2字节延期值长度为3字节孔位值长度为2字节。
//函数返回:雷管是否接收成功 0接收失败 / 1接收成功
uint8_t XT_Write_Field(uint8_t *uid, uint8_t uidlen, uint8_t *field)
{
uint8_t SData[22],RData[1];
SData[0] = XT_CMDA_WRITE_FIELD;
memcpy(SData+1,uid,uidlen);
memcpy(SData+1+uidlen,field,7);
SData[uidlen+8] = XT_CalCRC(SData,uidlen+8);
XT_SendData(SData,9+uidlen);
XT_ReceiveData(RData,1);
if(*RData & 0x80)
return 0;
else
return 1;
}
//函数名称:读现场值
//函数参数:
//函数功能UID正确且CRC校验通过时读出编号值、延期值、孔位值、状态字节。编号值长度为2字节延期值长度为3字节孔位值长度为2字节状态字节为1字节。反馈完成后会继续反馈一位1作为结束符。
//函数返回field存储编号值、延期值、孔位值、状态字节 0接收失败 / 1接收成功
uint8_t XT_Read_Field(uint8_t *uid, uint8_t uidlen, uint8_t *field)
{
uint8_t SData[15];
SData[0] = XT_CMDA_READ_FIELD;
memcpy(SData+1,uid,uidlen);
SData[uidlen+1] = XT_CalCRC(SData,uidlen+1);
XT_SendData(SData,uidlen+2);
XT_ReceiveData(field,66);
if(*(field+8) & 0x80)
return 0;
else
return 1;
}
//函数名称:读管壳码
//函数参数:
//函数功能UID正确且CRC校验通过时读出管壳码。管壳码长度为13字节。反馈完成后会继续反馈一位1作为结束符。
//函数返回:管壳码 0接收失败 / 1接收成功
uint8_t XT_Read_Shell(uint8_t *uid, uint8_t uidlen, uint8_t *shell)
{
uint8_t SData[15];
SData[0] = XT_CMDA_READ_SHELL;
memcpy(SData+1,uid,uidlen);
SData[uidlen+1] = XT_CalCRC(SData,uidlen+1);
XT_SendData(SData,uidlen+2);
//XT_ReceiveInit(106,1);
XT_ReceiveData(shell,106);
if(*(shell+13) & 0x80)
return 0;
else
return 1;
}
//函数名称:读测量参数值
//函数参数:
//函数功能UID正确且CRC校验通过时读出CCSC、AMP、R1、Rdson。这4个字段的长度均为1字节。反馈完成后会继续反馈一位1作为结束符。
//函数返回CCSC、AMP、R1、Rdson 0接收失败 / 1接收成功
uint8_t XT_Read_Param(uint8_t *uid, uint8_t uidlen, uint8_t *param)
{
uint8_t SData[15];
SData[0] = XT_CMDA_READ_PARAM;
memcpy(SData+1,uid,uidlen);
SData[uidlen+1] = XT_CalCRC(SData,uidlen+1);
XT_SendData(SData,uidlen+2);
//XT_ReceiveInit(34,1);
XT_ReceiveData(param,34);
if(*(param+4) & 0x80)
return 0;
else
return 1;
}
//函数名称:测量药头电阻
//函数参数:
//函数功能UID正确且CRC校验通过时打开药头电阻测量电路开关。
// 等待40个载波后发出ADC复位信号再经过1个载波后
// 发出开始ADC采样信号随后的8个载波中反馈ADC采样的值。
// 然后再发出ADC复位信号如上重复三次
//函数返回ADC采样值
uint8_t XT_Measure_Res(uint8_t *uid, uint8_t uidlen, uint8_t *adcvalue)
{
uint8_t SData[15],RData[9];
SData[0] = XT_CMDA_MEASURE_RES;
memcpy(SData+1,uid,uidlen);
SData[uidlen+1] = XT_CalCRC(SData,uidlen+1);
XT_SendData(SData,uidlen+2);
//XT_ReceiveInit(70,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;
}
//函数名称:测量储能电容
//函数参数:
//函数功能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指定的档位
// 将当前充满电标志位复位,并打开充电开关,关闭放电开关进行充电。充电完成时发出反馈,并将曾充满电标志位、当前充满电标志位置位。
// LEVEL0x11-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指定的档位将当前充满电标志位复位
// 并打开充电开关,关闭放电开关进行充电。充电完成时将曾充满电标志位、当前充满电标志位置位。
// LEVEL0x11-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;
}