706 lines
20 KiB
C
706 lines
20 KiB
C
#include "spi.h"
|
||
#include "APPDEF.H"
|
||
#include "math.h"
|
||
#include "string.h"
|
||
#include "stdio.h"
|
||
// AD7190寄存器地址定义
|
||
#define AD7190_REG_COMM 0x00 << 3
|
||
#define AD7190_REG_STAT 0x00 << 3
|
||
#define AD7190_REG_MODE 0x01 << 3
|
||
#define AD7190_REG_CONF 0x02 << 3
|
||
#define AD7190_REG_DATA 0x03 << 3
|
||
#define AD7190_REG_GPOC 0x05 << 3
|
||
|
||
// AD7190命令定义
|
||
#define AD7190_CMD_NOP 0xFF
|
||
#define AD7190_CMD_WR 0x00
|
||
#define AD7190_CMD_RD 0x40
|
||
|
||
// AD7190配置寄存器位掩码
|
||
#define AD7190_CONF_CHOP 0x800000
|
||
#define AD7190_CONF_REFSEL2 0x100000
|
||
// AD7190配置寄存器通道选择
|
||
#define AD7190_CONF_CH7 0x008000
|
||
#define AD7190_CONF_CH6 0x004000
|
||
#define AD7190_CONF_CH5 0x002000
|
||
#define AD7190_CONF_CH4 0x001000
|
||
#define AD7190_CONF_CH3 0x000800
|
||
#define AD7190_CONF_CH2 0x000400
|
||
#define AD7190_CONF_CH1 0x000200
|
||
#define AD7190_CONF_CH0 0x000100
|
||
// AD7190配置寄存器
|
||
#define AD7190_CONF_BURNOUT 0x000080
|
||
#define AD7190_CONF_REFDET 0x000040
|
||
#define AD7190_CONF_BUF 0x000010
|
||
#define AD7190_CONF_UB 0x000008
|
||
// AD7190配置寄存器增益定义
|
||
#define AD7190_CONF_GAIN_1 0x000000
|
||
#define AD7190_CONF_GAIN_8 0x000003
|
||
#define AD7190_CONF_GAIN_16 0x000004
|
||
#define AD7190_CONF_GAIN_32 0x000005
|
||
#define AD7190_CONF_GAIN_64 0x000006
|
||
#define AD7190_CONF_GAIN_128 0x000007
|
||
|
||
// AD7190配置寄存器工作模式定义
|
||
#define AD7190_CONF_MODE_CONT 0x000000
|
||
#define AD7190_CONF_MODE_ZEROSEL 0x800000
|
||
#define AD7190_CONF_MODE_FullSEL 0xA00000
|
||
#define AD7190_CONF_MODE_FS9_0 0x0003FF // 4.7Hz
|
||
#define AD7190_CONF_MODE_FS9_02 0x0001E0//10Hz
|
||
#define AD7190_CONF_MODE_FS9_03 0x000096//50Hz
|
||
|
||
#define AD7190_CONF_MODE_InCLK 0x080000// 4.92 MHz内部时钟 MCLK2引脚为三态
|
||
// AD7190 电桥开关
|
||
#define AD7190_GPOCON_BDPSW 0x40
|
||
|
||
void AD7190_WriteRegister(uint8_t regAddr, uint32_t regValue)
|
||
{
|
||
SPI1_ReadWrite(AD7190_CMD_WR | regAddr);
|
||
SPI1_ReadWrite((regValue >> 16) & 0xFF);
|
||
SPI1_ReadWrite((regValue >> 8) & 0xFF);
|
||
SPI1_ReadWrite(regValue & 0xFF);
|
||
}
|
||
uint32_t AD7190_ReadRegister(uint8_t regAddr)
|
||
{
|
||
uint32_t regValue = 0;
|
||
|
||
SPI1_ReadWrite(AD7190_CMD_RD | regAddr);
|
||
regValue = SPI1_ReadWrite(0xFF);
|
||
regValue = (regValue << 8) + SPI1_ReadWrite(0xFF);
|
||
regValue = (regValue << 8) + SPI1_ReadWrite(0xFF);
|
||
|
||
return regValue;
|
||
}
|
||
void AD7190_WriteRegisterOnce(uint8_t regAddr, uint8_t regValue)
|
||
{
|
||
SPI1_ReadWrite(AD7190_CMD_WR | regAddr);
|
||
SPI1_ReadWrite(regValue);
|
||
}
|
||
uint8_t AD7190_ReadRegisterOnce(uint8_t regAddr)
|
||
{
|
||
uint32_t regValue = 0;
|
||
SPI1_ReadWrite(AD7190_CMD_RD | regAddr);
|
||
regValue = SPI1_ReadWrite(0xFF);
|
||
return regValue;
|
||
}
|
||
bool AD7190_WaitForReady(uint32_t timeout)
|
||
{
|
||
uint32_t count = 0;
|
||
|
||
while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6) && (count < timeout))
|
||
{
|
||
delay_us(1);
|
||
count++;
|
||
}
|
||
|
||
if (count >= timeout)
|
||
{
|
||
return false;
|
||
}
|
||
else
|
||
{
|
||
return true;
|
||
}
|
||
}
|
||
//extern uint16_t Read_Internal_Temperature();
|
||
//// AD7190函数:读取AD转换结果
|
||
//float V25 = 1.43; // 25 度时的传感器电压(mV)
|
||
// float Avg_Slope = 4.3; // 传感器电压与温度之间的平均斜率(mV/°C)
|
||
// // 获取 ADC 参考电压值(一般为 3.3V)
|
||
// float Vref = 3.3; // 参考电压值(V)
|
||
//float TemperatureIn;
|
||
|
||
uint8_t ErrCount;
|
||
uint16_t DifErrCount;
|
||
uint32_t lastdata = 0;
|
||
uint32_t UseuLBuf[20];
|
||
uint32_t UseuLBuf2[20];
|
||
uint16_t BufIndex = 0;
|
||
// 计算一组数字的平均值
|
||
float calculateAverage(uint32_t arr[], int size)
|
||
{
|
||
double sum = 0.0;
|
||
|
||
// 计算总和
|
||
int i;
|
||
for (i = 0; i < size; i++)
|
||
{
|
||
sum += arr[i];
|
||
}
|
||
|
||
// 计算平均值
|
||
double average = sum / size;
|
||
|
||
return average;
|
||
}
|
||
|
||
void bubbleSort(uint32_t *arr, int n) {
|
||
int i, j, temp;
|
||
for (i = 0; i < n-1; i++) {
|
||
for (j = 0; j < n-i-1; j++) {
|
||
if (arr[j] > arr[j+1]) {
|
||
// 交换 arr[j] 和 arr[j+1]
|
||
temp = arr[j];
|
||
arr[j] = arr[j+1];
|
||
arr[j+1] = temp;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
***********************************************************
|
||
* @brief printf函数默认打印输出到显示器,如果要输出到串口,
|
||
必须重新实现fputc函数,将输出指向串口,称为重定向
|
||
* @param
|
||
* @return
|
||
***********************************************************
|
||
*/
|
||
int fputc(int ch, FILE *f)
|
||
{
|
||
while (!(READ_BIT(USART1->SR, USART_SR_TXE))) {
|
||
delay_us(100);
|
||
}
|
||
USART1->DR = ch;
|
||
return ch;
|
||
}
|
||
|
||
|
||
float average;
|
||
float center;
|
||
int ErrcountAdd = 0;
|
||
int DifErrCountAdd = 0;
|
||
uint32_t AD7190_ReadData( void )
|
||
{
|
||
uint32_t data = 0;
|
||
|
||
if(AD7190_WaitForReady(50000))
|
||
{
|
||
data = AD7190_ReadRegister(AD7190_REG_DATA);
|
||
if(fabs((int)data - (int)lastdata) > 100000 )
|
||
{
|
||
DifErrCount ++;
|
||
DifErrCountAdd++;
|
||
}
|
||
else
|
||
{
|
||
DifErrCount = 0;
|
||
}
|
||
lastdata = data;
|
||
if((data > 8388608) || (data < 100 ))
|
||
{
|
||
ErrCount++;
|
||
ErrcountAdd++;
|
||
}
|
||
else
|
||
{
|
||
ErrCount = 0;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ErrCount++;
|
||
ErrcountAdd++;
|
||
}
|
||
if(ErrCount > 3 || DifErrCount > 20)
|
||
{
|
||
uint32_t modeReg;
|
||
|
||
SPI1_Configuration();
|
||
SPI1_ReadWrite(0xFF);
|
||
SPI1_ReadWrite(0xFF);
|
||
SPI1_ReadWrite(0xFF);
|
||
SPI1_ReadWrite(0xFF);
|
||
SPI1_ReadWrite(0xFF); // 40个脉冲复位ADC
|
||
osDelay(50);
|
||
// 配置寄存器:通道选择、参考电压源、增益和工作模式
|
||
// 打开PSW
|
||
uint8_t GPOC = AD7190_ReadRegisterOnce(AD7190_REG_GPOC);
|
||
GPOC |= AD7190_GPOCON_BDPSW;
|
||
AD7190_WriteRegisterOnce(AD7190_REG_GPOC, GPOC);
|
||
osDelay(5);
|
||
uint32_t config = AD7190_CONF_GAIN_128 | AD7190_CONF_UB | AD7190_CONF_BUF | AD7190_CONF_CH0;// 0x0000011F;
|
||
AD7190_WriteRegister(AD7190_REG_CONF, config);
|
||
osDelay(5);
|
||
|
||
// 连续转换模式
|
||
modeReg = AD7190_CONF_MODE_FS9_0 | AD7190_CONF_MODE_InCLK;
|
||
AD7190_WriteRegister(AD7190_REG_MODE, modeReg);
|
||
|
||
|
||
ErrCount = 0;
|
||
osDelay(500);
|
||
if(AD7190_WaitForReady(50000))
|
||
{
|
||
data = AD7190_ReadRegister(AD7190_REG_DATA);
|
||
}
|
||
|
||
}
|
||
return data;
|
||
}
|
||
|
||
// 定义卡尔曼滤波器的参数结构体
|
||
typedef struct
|
||
{
|
||
double x; // 状态估计值
|
||
double P; // 状态协方差
|
||
double Q; // 过程噪声协方差
|
||
double R; // 观测噪声协方差
|
||
double K; // 卡尔曼增益
|
||
} KalmanFilter;
|
||
KalmanFilter kf2;
|
||
|
||
// 初始化卡尔曼滤波器
|
||
void kalman_filter_init2(KalmanFilter *kf, float initial_x, float initial_P, float process_noise, float measurement_noise)
|
||
{
|
||
kf->x = initial_x;
|
||
kf->P = initial_P;
|
||
kf->Q = process_noise;
|
||
kf->R = measurement_noise;
|
||
}
|
||
|
||
// 更新卡尔曼滤波器状态
|
||
void kalman_filter_update2(KalmanFilter *kf, float measurement)
|
||
{
|
||
// 预测步骤
|
||
float x_pred = kf->x; // 预测的状态值
|
||
float P_pred = kf->P + kf->Q; // 预测的状态协方差
|
||
|
||
// 更新步骤
|
||
kf->K = P_pred / (P_pred + kf->R); // 计算卡尔曼增益
|
||
kf->x = x_pred + kf->K * (measurement - x_pred); // 更新状态估计值
|
||
kf->P = (1 - kf->K) * P_pred; // 更新状态协方差
|
||
}
|
||
|
||
|
||
uint8_t FollowCount = 0; // 零点跟踪计数
|
||
uint8_t TimeCount = 0; // 蠕变时间计数
|
||
uint32_t FliterCount = 0; // 长期抑制计数
|
||
uint16_t SetZeroCount = 0; // 卸载归零计数
|
||
|
||
int32_t ADvalue2 = 0; // ADC采样原始值
|
||
|
||
double ADvalue2filter = 0.0f; // ADC采样卡尔曼滤波值
|
||
double ADvalue2filterOld = 0; // 上次ADC采样卡尔曼滤波值
|
||
|
||
double WeightData2Temp = 0.0f; // 本次ADvalue2filter计算重量值
|
||
double WeightData2TempOld; // 上次ADvalue2filter计算重量值
|
||
|
||
double WeightData2Finally = 0.0f; // 最终输出前重量值
|
||
|
||
double UninstiallRefWeight= 0.0f; // 卸载重物时的重量值
|
||
|
||
double WeightZeroOld = 0; // 上次稳定状态时零点值
|
||
struct uCalibrateWeight CalibrateWeight2; //传感器 斜率 零点
|
||
|
||
double WeightData2 = 0.0f; // 最终输出重量值
|
||
bool weightChanging = false; // 传感器稳定标志
|
||
bool weight11g = false; // 传感器稳定标志
|
||
float ZeroWeightOld;
|
||
float ZeroWeightChange;
|
||
|
||
float LowFecAlpha = 0.95f; // 超低频波动抑制系数,发生突变时偏向跟踪新值,相对稳定时跟踪旧值
|
||
float WeightRefStart = 0;
|
||
|
||
uint8_t i;
|
||
|
||
#define ChangeMax 10
|
||
#define ZeroTrackMax 0.050f
|
||
#define FollowMax 0.030f
|
||
#define FliterCountMax 200
|
||
#define FollowDlteaMax 0.001f
|
||
#define FollowAlpha 0.9999f // 长期数据跟踪系数
|
||
void AD7190_Run(const void *p_arg)
|
||
{
|
||
uint8_t FilterQOld, SensorQOld, ZeroTrackOld, RuBianLiangOld, ruBianTimeOld;
|
||
int8_t RubianLiang, RubianTime;
|
||
float ZeroTrackTime, ZeroTrackRange;
|
||
|
||
osDelay(600);
|
||
ADvalue2 = AD7190_ReadData();
|
||
osDelay(200);
|
||
ADvalue2 = AD7190_ReadData();
|
||
ADvalue2filterOld = ADvalue2filter = ADvalue2;
|
||
kalman_filter_init2(&kf2, ADvalue2, 1.0, 0.001, 0.1);
|
||
WeightZeroOld = CalibrateWeight2.WeightZero;
|
||
for (;;)
|
||
{
|
||
if (FilterQOld != Set.FilterQ)
|
||
{
|
||
FilterQOld = Set.FilterQ;
|
||
switch (Set.FilterQ) // 滤波器信任度 信任度越高 反应越慢数据显示越稳定
|
||
{
|
||
case 0:
|
||
kf2.Q = 0.1;
|
||
break;
|
||
case 1:
|
||
kf2.Q = 0.08;
|
||
break;
|
||
case 2:
|
||
kf2.Q = 0.06;
|
||
break;
|
||
case 3:
|
||
kf2.Q = 0.04;
|
||
break;
|
||
case 4:
|
||
kf2.Q = 0.02;
|
||
break;
|
||
case 5:
|
||
kf2.Q = 0.009;
|
||
break;
|
||
case 6:
|
||
kf2.Q = 0.007;
|
||
break;
|
||
case 7:
|
||
kf2.Q = 0.005;
|
||
break;
|
||
case 8:
|
||
kf2.Q = 0.003;
|
||
break;
|
||
case 9:
|
||
kf2.Q = 0.001;
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
if (SensorQOld != Set.SensorQ)
|
||
{
|
||
SensorQOld = Set.SensorQ;
|
||
switch (Set.SensorQ) // 传感器信任度 信任度越高 反应越迅速,数据波动越大 显示越不稳定
|
||
{
|
||
case 0:
|
||
kf2.R = 0.5;
|
||
break;
|
||
case 1:
|
||
kf2.R = 0.3;
|
||
break;
|
||
case 2:
|
||
kf2.R = 0.1;
|
||
break;
|
||
case 3:
|
||
kf2.R = 0.08;
|
||
break;
|
||
case 4:
|
||
kf2.R = 0.06;
|
||
break;
|
||
case 5:
|
||
kf2.R = 0.04;
|
||
break;
|
||
case 6:
|
||
kf2.R = 0.02;
|
||
break;
|
||
case 7:
|
||
kf2.R = 0.009;
|
||
break;
|
||
case 8:
|
||
kf2.R = 0.005;
|
||
break;
|
||
case 9:
|
||
kf2.R = 0.001;
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
if (ZeroTrackOld != Set.ZeroTrack) // 零点跟踪 跟踪级别越高 原始数据发生缓慢变化时,最终数据不会发生变化的可能性越大。例如 当跟踪级别设置为9时,那么如果原始数据在4秒内变化小于2.5mg,那么最终数据不会发生变化。原理是cpu会将这4秒内变化的数据叠加到零点上,相当于动态调零了。
|
||
{
|
||
ZeroTrackOld = Set.ZeroTrack;
|
||
switch (ZeroTrackOld)
|
||
{
|
||
case 0:
|
||
ZeroTrackTime = 20; // 连续20秒
|
||
ZeroTrackRange = 0; // 相邻两次采样数据小于0.000g
|
||
break;
|
||
case 1:
|
||
ZeroTrackTime = 15;
|
||
ZeroTrackRange = 0.0005;
|
||
break;
|
||
case 2:
|
||
ZeroTrackTime = 10;
|
||
ZeroTrackRange = 0.0005;
|
||
break;
|
||
case 3:
|
||
ZeroTrackTime = 7;
|
||
ZeroTrackRange = 0.0005;
|
||
break;
|
||
case 4:
|
||
ZeroTrackTime = 4;
|
||
ZeroTrackRange = 0.0005;
|
||
break;
|
||
case 5:
|
||
ZeroTrackTime = 4;
|
||
ZeroTrackRange = 0.0008;
|
||
break;
|
||
case 6:
|
||
ZeroTrackTime = 4;
|
||
ZeroTrackRange = 0.001;
|
||
break;
|
||
case 7:
|
||
ZeroTrackTime = 4;
|
||
ZeroTrackRange = 0.0015;
|
||
break;
|
||
case 8:
|
||
ZeroTrackTime = 4;
|
||
ZeroTrackRange = 0.002;
|
||
break;
|
||
case 9:
|
||
ZeroTrackTime = 4;
|
||
ZeroTrackRange = 0.0025;
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
if (ruBianTimeOld != Set.RuBianTime) // 蠕变时间 级别越高 蠕变时间越短,蠕变越快 零为不蠕变
|
||
{
|
||
ruBianTimeOld = Set.RuBianTime;
|
||
switch (Set.RuBianTime)
|
||
{
|
||
case 0:
|
||
RubianTime = 100;
|
||
break;
|
||
case 1:
|
||
RubianTime = 60;
|
||
break;
|
||
case 2:
|
||
RubianTime = 30;
|
||
break;
|
||
case 3:
|
||
RubianTime = 20;
|
||
break;
|
||
case 4:
|
||
RubianTime = 15;
|
||
break;
|
||
case 5:
|
||
RubianTime = 10;
|
||
break;
|
||
case 6:
|
||
RubianTime = 8;
|
||
break;
|
||
case 7:
|
||
RubianTime = 6;
|
||
break;
|
||
case 8:
|
||
RubianTime = 4;
|
||
break;
|
||
case 9:
|
||
RubianTime = 2;
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
if (RuBianLiangOld != Set.RuBianLiang) //蠕变量 可分正向蠕变和反向蠕变 零为不蠕变 当零点跟踪为0时 调零后观察一段时间的数据变化 如果数据持续变化为负数 则为负蠕变。反之为正蠕变。 负蠕变调整蠕变量为负数级别(谨慎调整 建议不调整)
|
||
{
|
||
RuBianLiangOld = Set.RuBianLiang;
|
||
switch (Set.RuBianLiang)
|
||
{
|
||
case 0:
|
||
RubianLiang = -5;
|
||
break;
|
||
case 1:
|
||
RubianLiang = -4;
|
||
break;
|
||
case 2:
|
||
RubianLiang = -3;
|
||
break;
|
||
case 3:
|
||
RubianLiang = -2;
|
||
break;
|
||
case 4:
|
||
RubianLiang = -1;
|
||
break;
|
||
case 5:
|
||
RubianLiang = 0;
|
||
break;
|
||
case 6:
|
||
RubianLiang = 1;
|
||
break;
|
||
case 7:
|
||
RubianLiang = 2;
|
||
break;
|
||
case 8:
|
||
RubianLiang = 3;
|
||
break;
|
||
case 9:
|
||
RubianLiang = 4;
|
||
break;
|
||
case 10:
|
||
RubianLiang = 5;
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
|
||
osDelay(200);
|
||
ADvalue2 = AD7190_ReadData(); //4.7Hz 213ms
|
||
kalman_filter_update2(&kf2, ADvalue2); // 更新步骤
|
||
if(fabs(ADvalue2filter - kf2.x) < ChangeMax )
|
||
{
|
||
LowFecAlpha = 0.95; // 数据处于稳定状态 未有重量突变或小幅度连续单向改变时信任上次值
|
||
}
|
||
else
|
||
{
|
||
LowFecAlpha = 0.5; // 数据处于较大波动状态 有重量突变或小幅度连续单向改变时信任本次值
|
||
}
|
||
ADvalue2filter = kf2.x *(1-LowFecAlpha)+ADvalue2filter*LowFecAlpha;
|
||
// if(pageNum != 1)
|
||
// {
|
||
|
||
// if(WeightData2TempOld - WeightData2Temp > 0.500f) // 卸载重物
|
||
// {
|
||
// if(UninstiallRefWeight < 0.005f) // 如果未触发归零条件
|
||
// {
|
||
// UninstiallRefWeight = WeightData2TempOld;
|
||
// WeightZeroOld = CalibrateWeight2.WeightZero; // 备份零点原始值,以备不稳定状态下重新加载重物导致数据不准确
|
||
// }
|
||
// }
|
||
// else if(WeightData2TempOld - WeightData2Temp < -0.500f)//加载重物
|
||
// {
|
||
// UninstiallRefWeight = 0.0f;
|
||
// if( WeightZeroOld != CalibrateWeight2.WeightZero)
|
||
// {
|
||
// CalibrateWeight2.WeightZero = WeightZeroOld; // 置零未完成或零点跟踪未完成,恢复至改变前零点值,防止数据不准确
|
||
// }
|
||
// SetZeroCount = 0;
|
||
// }
|
||
// if(UninstiallRefWeight > 0.005f) // 卸载重物后接近归零时进行归零操作
|
||
// {
|
||
// if(SetZeroCount++ > 50 ) // 归零后重置触发归零条件
|
||
// {
|
||
//
|
||
// UninstiallRefWeight = 0.0f;
|
||
// WeightZeroOld = CalibrateWeight2.WeightZero;
|
||
// SetZeroCount = 0;
|
||
// }
|
||
// if(fabs(WeightData2Temp) < 0.100f && fabs(WeightData2Temp) > 0.004f) // 符合归零区间范围则缓慢归零
|
||
// {
|
||
// SetZeroCount = 0;
|
||
// CalibrateWeight2.WeightZero += WeightData2Temp / CalibrateWeight2.WeightSlope / 10;
|
||
// ZeroWeightChange = CalibrateWeight2.WeightSlope * (ADvalue2filter - CalibrateWeight2.WeightZero);
|
||
// }
|
||
// ZeroWeightOld = CalibrateWeight2.WeightSlope * (ADvalue2filter - WeightZeroOld);
|
||
// if( fabs(ZeroWeightOld) <= fabs(ZeroWeightChange) )
|
||
// {
|
||
// weight11g=0;
|
||
// CalibrateWeight2.WeightZero = WeightZeroOld;
|
||
// }
|
||
// else
|
||
// {
|
||
// weight11g=1;
|
||
// }
|
||
|
||
// }
|
||
// }
|
||
|
||
WeightData2TempOld = WeightData2Temp;
|
||
WeightData2Temp = CalibrateWeight2.WeightSlope * (ADvalue2filter - CalibrateWeight2.WeightZero);
|
||
|
||
// printf("%f,%f,%f,%.4f\n",Temperature,ADvalue2filter,WeightData2Temp,WeightData2Finally);
|
||
|
||
if( RubianLiang != 0 ) // 蠕变
|
||
{
|
||
if (TimeCount++ > 4 * RubianTime) // 动态称重时蠕变跟踪
|
||
{
|
||
TimeCount = 0;
|
||
if (CalibrateWeight2.WeightZero == WeightZeroOld)
|
||
{
|
||
CalibrateWeight2.WeightZero += RubianLiang;
|
||
}
|
||
WeightZeroOld = CalibrateWeight2.WeightZero;
|
||
}
|
||
}
|
||
|
||
if (fabs(WeightData2TempOld - WeightData2Temp) < ZeroTrackRange && fabs(WeightData2Temp) < ZeroTrackMax && ( pageNum != 1)) // 符合跟踪范围 型评 当示值为零或相当于毛重为0时 负的净重值,且未运行,且水分测定仪处于平衡稳定状态 才允许运行
|
||
{
|
||
if (FollowCount++ > 4 * ZeroTrackTime) // 零点动态跟踪
|
||
{
|
||
FollowCount = 0;
|
||
TimeCount = 0;
|
||
CalibrateWeight2.WeightZero += ADvalue2filter - ADvalue2filterOld;
|
||
WeightZeroOld = CalibrateWeight2.WeightZero;
|
||
ADvalue2filterOld = ADvalue2filter;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
FollowCount = 0;
|
||
ADvalue2filterOld = ADvalue2filter;
|
||
}
|
||
|
||
if ( fabs(WeightData2Temp) > ZeroTrackMax && fabs(WeightData2TempOld - WeightData2Temp) < FollowDlteaMax && fabs(WeightData2Temp - WeightRefStart) < FollowMax && ( pageNum != 1)) //重量不变且大于零点跟踪范围未加热进行长期数据跟踪
|
||
{
|
||
if(FliterCount < FliterCountMax)
|
||
FliterCount++;
|
||
else
|
||
FliterCount = FliterCountMax;
|
||
WeightData2Finally = WeightData2Finally + (WeightData2Temp - WeightData2Finally) * ( 1.00000f - FollowAlpha * FliterCount / FliterCountMax);
|
||
}
|
||
else
|
||
{
|
||
WeightData2Finally = WeightRefStart = WeightData2Temp;
|
||
FliterCount = 0;
|
||
}
|
||
|
||
|
||
if (fabs(WeightData2 - WeightData2Finally) > 0.006f) // 变化大于50mg/s 置位传感器不稳定标志
|
||
{
|
||
weightChanging = 1;
|
||
}
|
||
else
|
||
{
|
||
weightChanging = 0;
|
||
}
|
||
|
||
|
||
if (fabs(WeightData2 - WeightData2Finally) > 0.0002f) // 数据滤波
|
||
{
|
||
WeightData2 = (int32_t)(WeightData2Finally * 10000) / 10000.0f;
|
||
}
|
||
else if(fabs(WeightData2Finally) < 0.001f)
|
||
{
|
||
WeightData2 = (int32_t)(WeightData2Finally * 10000) / 10000.0f;
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
osThreadDef(AD7190_Run, osPriorityNormal, 1, 0);
|
||
// AD7190函数:初始化AD7190
|
||
void AD7190_Init()
|
||
{
|
||
uint32_t modeReg;
|
||
|
||
SPI1_Configuration();
|
||
SPI1_ReadWrite(0xFF);
|
||
SPI1_ReadWrite(0xFF);
|
||
SPI1_ReadWrite(0xFF);
|
||
SPI1_ReadWrite(0xFF);
|
||
SPI1_ReadWrite(0xFF); // 40个脉冲复位ADC
|
||
osDelay(50);
|
||
// 配置寄存器:通道选择、参考电压源、增益和工作模式
|
||
// 打开PSW
|
||
uint8_t GPOC = AD7190_ReadRegisterOnce(AD7190_REG_GPOC);
|
||
GPOC |= AD7190_GPOCON_BDPSW;
|
||
AD7190_WriteRegisterOnce(AD7190_REG_GPOC, GPOC);
|
||
osDelay(5);
|
||
uint32_t config = AD7190_CONF_GAIN_128 | AD7190_CONF_UB | AD7190_CONF_BUF | AD7190_CONF_CH0;// 0x0000011F;
|
||
AD7190_WriteRegister(AD7190_REG_CONF, config);
|
||
osDelay(5);
|
||
modeReg = AD7190_CONF_MODE_FS9_0 ;// 滤波器最低速率输出 执行上电校准
|
||
AD7190_WriteRegister(AD7190_REG_MODE, modeReg);
|
||
osDelay(5);
|
||
//连续转换模式
|
||
modeReg = AD7190_CONF_MODE_FS9_0 | AD7190_CONF_MODE_InCLK;
|
||
AD7190_WriteRegister(AD7190_REG_MODE, modeReg);
|
||
|
||
CalibrateWeight2.WeightSlope = 0.0001530345f;
|
||
// CalibrateWeight2.WeightZero = 745430;
|
||
|
||
osThreadCreate(osThread(AD7190_Run), NULL);
|
||
}
|