/*-------------------------------------------------------------------------------------- * @file ADS1110Setup.c * @author ZhangJing * @version base on stm32f0x * @date 2015.09.11 * @brief ADS1110驱动 ---------------------------------------------------------------------------------------*/ #include #include "stm32f10x_gpio.h" #include "TypeDefine.h" #include "IICSetup.h" #include "ADS1110ASetup.h" #include "ADS1110Setup.h" #include "SystemAlarm.h" uint16_t pressureFZero = 1097; //压力采集值零点值 uint16_t pressureFZero2 = 466; //压力2采集值零点值 uint16_t pressureCounts = 0; //压力采集次数 //uint16_t pressureF1[102]={ 0 }; //压力采集值数组,采集数据做滤波用 uint16_t pressureF1[400]={ 0 }; //压力采集值数组,采集数据做滤波用 uint16_t PressureF1_bf[10]={ 0 }; //压力备份数据数组 uint16_t PressureF1_bf2[10]={ 0 }; //压力备份数据数组 uint8_t Pressurebf_Cont=0; //压力备份次数 uint16_t average_Pressure=0; //压力平均值 uint16_t average_Pressure_bf=0; //压力平均值 uint16_t self_adaption_Pressure=0; //自适应压力值 uint16_t self_adaption_buf[5]={0}; //自适应压力值缓冲区 uint8_t self_adaption_cont=0; //自适应压力值缓冲区储存次数 uint8_t self_adaption_flag=0; //自适应压力参数处理完成标志,用于后面压力报警判断 uint16_t ces_cong=0; uint16_t tempPressure = 0; uint16_t tempPressure_2 = 0; uint8_t ces_flag1=0; //--------------外部变量声明--------------------- extern uint8_t self_adaption_Alarmcont; //自适应压力报警判断次数 /************************************************************************************* * Function: ADS1110Config * Object: 配置ADS1110 * 输入: 无 * 输出: 无 * 备注: 1、通过模拟IIC与ADS1110通信,进行初始化配置 * 2、uint8_t tempState = 0;临时变量 **************************************************************************************/ void ADS1110Config(void) { uint8_t tempState = 0; TWI_START(); tempState = TWI_SendByte(ADS1110_WR_ADDRESS); if( 1 != tempState ) { //发送终止IIC标志 TWI_STOP(); return; } TWI_SendNACK(); tempState = TWI_SendByte(ADS1110_CONFIG_REG); if( 1 != tempState ) { //发送终止IIC标志 TWI_STOP(); return; } TWI_SendNACK(); TWI_STOP(); } /************************************************************************************* * Function: RD_ADS * Object: 读ADS1110数据 * 输入: 无 * 输出: 转换后数据 * 备注: 1、将读取回来的数据,通过uint16_t W_B1byte_high, W_B1byte_low, W_B1_word; * 这些变量进行计算,并返回转换后的电压值 **************************************************************************************/ uint16_t RD_ADS(void) { // u8 temp; uint16_t W_B1byte_high, W_B1byte_low, W_B1_word; TWI_START(); TWI_SendByte(ADS1110_RD_ADDRESS);//0x90 TWI_SendNACK(); // // if(!temp) // { W_B1byte_high /*= TMR_H*/ = TWI_ReceiveByte(); TWI_SendACK(); W_B1byte_low /*= TMR_L*/ = TWI_ReceiveByte(); TWI_SendACK(); W_B1_word = TWI_ReceiveByte(); TWI_STOP(); W_B1_word = ((W_B1byte_high << 8)+ W_B1byte_low); // if (W_B1_word > 0x7fff) // W_B1_word = 0; return W_B1_word; // } // else // return 0x0000; } /************************************************************************************* * Function: ContactForceUpdate * Object: 读取触力传感器的值 * 输入: 无 * 输出: 无 * 备注: 1、根据TaskSchedulerFlag.sensorPWPressureFlag标志位来判断是否需要采集压力值 * 2、根据TaskSchedulerFlag.forceConvertFlag标志位来判断是启动转换还是读取AD采集的值 * 3、float tempPressure = 0;临时变量,做压力计算 * 4、压力值必须先启动转换再进行读取 * 5、压力值读取完成进行大小排序,取最大值作为本次采集值 **************************************************************************************/ void ContactForceUpdate( void ) { //float tempPressure = 0; uint16_t i,j; tempPressure=0; tempPressure_2=0; if( TaskSchedulerFlag.sensorPWPressureFlag == TASK_FLAG_SET ) { if( TaskSchedulerFlag.forceConvertFlag == TASK_FLAG_CLEAR )//启动转换 { ADS1110Config(); //ADS1110AConfig(); TaskSchedulerFlag.forceConvertFlag = TASK_FLAG_WAIT; } else if( TaskSchedulerFlag.forceConvertFlag == TASK_FLAG_SET )//读取压力值 { //读取A/D压力采集值 tempPressure_2 = RD_ADS(); TaskSchedulerFlag.forceConvertFlag = TASK_FLAG_CLEAR; if( tempPressure_2 > 80 ) { ces_flag1=1; return; } else { pressureF1[pressureCounts] = (uint16_t)tempPressure_2; pressureCounts++; } /* tempPressure *= 9.8;//算出压力值 F=mg g=9.8N/Kg tempPressure = tempPressure / 9.68; realTimeData.pressure = tempPressure;//压强值*/ /* tempPressure = RD2_ADS(); //如果采集值小于零点值,则将新采集的值作为零点值 if( ( tempPressure < pressureFZero2 ) && ( tempPressure > 400) ) { pressureFZero2 = tempPressure; } if( tempPressure > 400 )//零点值不会小于400,如果没有压力传感器则会在400以下 { tempPressure -= pressureFZero2;//采集值-零点值=压力值 } else { tempPressure = 0; } realTimeData.pressureF2 = tempPressure; tempPressure *= 9.8;//算出压力值 F=mg g=9.8N/Kg tempPressure = tempPressure / 9.68; realTimeData.pressure2 = tempPressure;*/ //TaskSchedulerFlag.forceConvertFlag = TASK_FLAG_CLEAR; //if( pressureF1[pressureCounts] > 9999 ) /*if( pressureF1[pressureCounts] > 80 )//2017.3.22修改压力最大值为80 { pressureF1[pressureCounts] = 0; return ; }*/ // } } else { if(( pressureCounts != 0 ) || (ces_flag1 == 1))//只要采集值不为零说明刚有采集值就做比较 { //报警判断相关结构赋值 ces_flag1=0; SysAlarmJudge.JamFaultJudgeFlag = TASK_FLAG_SET; //SysAlarmJudge.BubbleFaultJudgeFlag = TASK_FLAG_SET; SysAlarmJudge.NonePillCaseJudgeFlag = TASK_FLAG_SET; //TaskSchedulerFlag.testDispFlag = TASK_FLAG_SET; for( i = 1; i < pressureCounts; i++ ) { tempPressure = pressureF1[i]; for( j = 0; j < ( pressureCounts + 1 - i ); j++ ) { if( pressureF1[j] > pressureF1[j + 1] ) { tempPressure = pressureF1[j]; pressureF1[j] = pressureF1[j + 1]; pressureF1[j + 1] = tempPressure; } } } // if( pressureCounts >28 )//只要采集值不为零说明刚有采集值就做比较 { realTimeData.pressureF = pressureF1[pressureCounts - 1];//取最大值 } if( realTimeData.pressureF > 80 ) { realTimeData.pressureF = 0; } (void) memset (&pressureF1, 0, sizeof(pressureF1)); //将pressureF1数据清零 ces_cong=pressureCounts; pressureCounts = 0; //***********************求自适应的压力参数**************************** if( start_flag ==1) //连续取值五次,求最大值 { uint16_t t=0; self_adaption_buf[self_adaption_cont] = realTimeData.pressureF; // if(self_adaption_Pressure < realTimeData.pressureF) // self_adaption_Pressure = realTimeData.pressureF; self_adaption_cont++; if( self_adaption_cont > 4) { for(j=1;j<5;j++) //升序排列 滤波去掉最大值 { for(i=0;i<5-j;i++) { if(self_adaption_buf[i] > self_adaption_buf[i+1]) { t=self_adaption_buf[i+1]; self_adaption_buf[i+1] = self_adaption_buf[i]; self_adaption_buf[i] = t; } } } self_adaption_Pressure = self_adaption_buf[3]; self_adaption_cont=0; start_flag=0; self_adaption_flag=1; //自适应压力参数处理完成标志,用于后面压力报警判断 self_adaption_Alarmcont=0; } } //******************************************************************** /* //-----------对于堵塞报警,算法改为:每十个周期,去掉一个最小值,一个最大值,求平均值,20170506 if(Pressurebf_Cont<10) { PressureF1_bf[Pressurebf_Cont] = realTimeData.pressureF; Pressurebf_Cont++; } else { uint8_t t=0,i=0,j=0,k=0,w=0,z=0,x=0; for(x=0;x<10;x++) { PressureF1_bf2[x] = PressureF1_bf[x]; //把记录的十组数据备份,为后面回复数据做准备 } for(j=1;j<10;j++) //升序排列 { for(i=0;i<10-j;i++) { if(PressureF1_bf[i] > PressureF1_bf[i+1]) { t=PressureF1_bf[i+1]; PressureF1_bf[i+1] = PressureF1_bf[i]; PressureF1_bf[i] = t; } } } average_Pressure=0; //求平均值前清零 for(k=1;k<9;k++)//求平均值 { average_Pressure += PressureF1_bf[k]; } average_Pressure_bf = ((average_Pressure*5)/4);//(average_Pressure*10/8);参数放大10倍 for(z=0;z<10;z++) { PressureF1_bf[z] = PressureF1_bf2[z]; //把原始数据还原,为下次采集数据移除数据做准备 } for(w=0;w<9;w++)//向低位移位一位 { PressureF1_bf[w]=PressureF1_bf[w+1]; } Pressurebf_Cont=9;//排序完成,清除采集备份次数 } //-----------------------------------------------------------------------*/ } } }