打印

PH传感器的电压是如何转换为pH数值

[复制链接]
8761|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zerorobert|  楼主 | 2025-1-10 21:39 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
51xlf| | 2025-1-10 22:09 | 只看该作者
/*!
* @file DFRobot_PH.cpp
* @brief Arduino library for Gravity: Analog pH Sensor / Meter Kit V2, SKU: SEN0161-V2
*
* @CopyRight   Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
* @license     The MIT License (MIT)
* @author [Jiawei Zhang](jiawei.zhang@dfrobot.com)
* @version  V1.0
* @date  2018-11-06
* @url https://github.com/DFRobot/DFRobot_PH
*/


#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

#include "DFRobot_PH.h"
#include <EEPROM.h>

#define EEPROM_write(address, p) {int i = 0; byte *pp = (byte*)&(p);for(; i < sizeof(p); i++) EEPROM.write(address+i, pp);}
#define EEPROM_read(address, p)  {int i = 0; byte *pp = (byte*)&(p);for(; i < sizeof(p); i++) pp=EEPROM.read(address+i);}

#define PHVALUEADDR 0x00    //the start address of the pH calibration parameters stored in the EEPROM

char* DFRobot_PH::strupr(char* str) {
    if (str == NULL) return NULL;
    char *ptr = str;
    while (*ptr != ' ') {
        *ptr = toupper((unsigned char)*ptr);
        ptr++;
    }
    return str;
}

DFRobot_PH::DFRobot_PH()
{
    this->_temperature    = 25.0;
    this->_phValue        = 7.0;
    this->_acidVoltage    = 2032.44;    //buffer solution 4.0 at 25C
    this->_neutralVoltage = 1500.0;     //buffer solution 7.0 at 25C
    this->_voltage        = 1500.0;
}

DFRobot_PH::~DFRobot_PH()
{

}

void DFRobot_PH::begin()
{
    EEPROM_read(PHVALUEADDR, this->_neutralVoltage);  //load the neutral (pH = 7.0)voltage of the pH board from the EEPROM
    //Serial.print("_neutralVoltage:");
    //Serial.println(this->_neutralVoltage);
    if(EEPROM.read(PHVALUEADDR)==0xFF && EEPROM.read(PHVALUEADDR+1)==0xFF && EEPROM.read(PHVALUEADDR+2)==0xFF && EEPROM.read(PHVALUEADDR+3)==0xFF){
        this->_neutralVoltage = 1500.0;  // new EEPROM, write typical voltage
        EEPROM_write(PHVALUEADDR, this->_neutralVoltage);
    }
    EEPROM_read(PHVALUEADDR+4, this->_acidVoltage);//load the acid (pH = 4.0) voltage of the pH board from the EEPROM
    //Serial.print("_acidVoltage:");
    //Serial.println(this->_acidVoltage);
    if(EEPROM.read(PHVALUEADDR+4)==0xFF && EEPROM.read(PHVALUEADDR+5)==0xFF && EEPROM.read(PHVALUEADDR+6)==0xFF && EEPROM.read(PHVALUEADDR+7)==0xFF){
        this->_acidVoltage = 2032.44;  // new EEPROM, write typical voltage
        EEPROM_write(PHVALUEADDR+4, this->_acidVoltage);
    }
}

float DFRobot_PH::readPH(float voltage, float temperature)
{
    float slope = (7.0-4.0)/((this->_neutralVoltage-1500.0)/3.0 - (this->_acidVoltage-1500.0)/3.0);  // two point: (_neutralVoltage,7.0),(_acidVoltage,4.0)
    float intercept =  7.0 - slope*(this->_neutralVoltage-1500.0)/3.0;
    //Serial.print("slope:");
    //Serial.print(slope);
    //Serial.print(",intercept:");
    //Serial.println(intercept);
    this->_phValue = slope*(voltage-1500.0)/3.0+intercept;  //y = k*x + b
    return _phValue;
}


void DFRobot_PH::calibration(float voltage, float temperature,char* cmd)
{
    this->_voltage = voltage;
    this->_temperature = temperature;
    String sCmd = String(cmd);
    sCmd.toUpperCase();
    phCalibration(cmdParse(sCmd.c_str()));  // if received Serial CMD from the serial monitor, enter into the calibration mode
}

void DFRobot_PH::calibration(float voltage, float temperature)
{
    this->_voltage = voltage;
    this->_temperature = temperature;
    if(cmdSerialDataAvailable() > 0){
        phCalibration(cmdParse());  // if received Serial CMD from the serial monitor, enter into the calibration mode
    }
}

boolean DFRobot_PH::cmdSerialDataAvailable()
{
    char cmdReceivedChar;
    static unsigned long cmdReceivedTimeOut = millis();
    while(Serial.available()>0){
        if(millis() - cmdReceivedTimeOut > 500U){
            this->_cmdReceivedBufferIndex = 0;
            memset(this->_cmdReceivedBuffer,0,(ReceivedBufferLength));
        }
        cmdReceivedTimeOut = millis();
        cmdReceivedChar = Serial.read();
        if (cmdReceivedChar == '\n' || this->_cmdReceivedBufferIndex==ReceivedBufferLength-1){
            this->_cmdReceivedBufferIndex = 0;
            strupr(this->_cmdReceivedBuffer);
            return true;
        }else{
            this->_cmdReceivedBuffer[this->_cmdReceivedBufferIndex] = cmdReceivedChar;
            this->_cmdReceivedBufferIndex++;
        }
    }
    return false;
}

byte DFRobot_PH::cmdParse(const char* cmd)
{
    byte modeIndex = 0;
    if(strstr(cmd, "ENTERPH")      != NULL){
        modeIndex = 1;
    }else if(strstr(cmd, "EXITPH") != NULL){
        modeIndex = 3;
    }else if(strstr(cmd, "CALPH")  != NULL){
        modeIndex = 2;
    }
    return modeIndex;
}

byte DFRobot_PH::cmdParse()
{
    byte modeIndex = 0;
    if(strstr(this->_cmdReceivedBuffer, "ENTERPH")      != NULL){
        modeIndex = 1;
    }else if(strstr(this->_cmdReceivedBuffer, "EXITPH") != NULL){
        modeIndex = 3;
    }else if(strstr(this->_cmdReceivedBuffer, "CALPH")  != NULL){
        modeIndex = 2;
    }
    return modeIndex;
}

void DFRobot_PH::phCalibration(byte mode)
{
    char *receivedBufferPtr;
    static boolean phCalibrationFinish  = 0;
    static boolean enterCalibrationFlag = 0;
    switch(mode){
        case 0:
        if(enterCalibrationFlag){
            Serial.println(F(">>>Command Error<<<"));
        }
        break;

        case 1:
        enterCalibrationFlag = 1;
        phCalibrationFinish  = 0;
        Serial.println();
        Serial.println(F(">>>Enter PH Calibration Mode<<<"));
        Serial.println(F(">>>Please put the probe into the 4.0 or 7.0 standard buffer solution<<<"));
        Serial.println();
        break;

        case 2:
        if(enterCalibrationFlag){
            if((this->_voltage>1322)&&(this->_voltage<1678)){        // buffer solution:7.0{
                Serial.println();
                Serial.print(F(">>>Buffer Solution:7.0"));
                this->_neutralVoltage =  this->_voltage;
                Serial.println(F(",Send EXITPH to Save and Exit<<<"));
                Serial.println();
                phCalibrationFinish = 1;
            }else if((this->_voltage>1854)&&(this->_voltage<2210)){  //buffer solution:4.0
                Serial.println();
                Serial.print(F(">>>Buffer Solution:4.0"));
                this->_acidVoltage =  this->_voltage;
                Serial.println(F(",Send EXITPH to Save and Exit<<<"));
                Serial.println();
                phCalibrationFinish = 1;
            }else{
                Serial.println();
                Serial.print(F(">>>Buffer Solution Error Try Again<<<"));
                Serial.println();                                    // not buffer solution or faulty operation
                phCalibrationFinish = 0;
            }
        }
        break;

        case 3:
        if(enterCalibrationFlag){
            Serial.println();
            if(phCalibrationFinish){
                if((this->_voltage>1322)&&(this->_voltage<1678)){

                    EEPROM_write(PHVALUEADDR, this->_neutralVoltage);
                }else if((this->_voltage>1854)&&(this->_voltage<2210)){
                    EEPROM_write(PHVALUEADDR+4, this->_acidVoltage);
                }
                Serial.print(F(">>>Calibration Successful"));
            }else{
                Serial.print(F(">>>Calibration Failed"));
            }
            Serial.println(F(",Exit PH Calibration Mode<<<"));
            Serial.println();
            phCalibrationFinish  = 0;
            enterCalibrationFlag = 0;
        }
        break;
    }
}

使用特权

评论回复
板凳
lsc501| | 2025-2-14 11:12 | 只看该作者

PH传感器的电压是如何转换为pH数值

/******************************************************************************
* Copyright (C) 2018, Huada Semiconductor Co.,Ltd All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer:
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACOOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file main.c
**
** A detailed description is available at
** @link Sample Group Some description @endlink
**
**   - 2024-09-06 v3 修改温补计算
**
******************************************************************************/

/******************************************************************************
* Include files
******************************************************************************/
#include <stdio.h>
#include <math.h>
#include "wdt.h"
#include "adc.h"
#include "ddl.h"
#include "hdiv.h"
#include "bt.h"
#include "uart.h"
#include "gpio.h"
#include "sysctrl.h"
#include "flash.h"
#include "bgr.h"
#include "modbus_reg.h"
/******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
#define Firmware 3                 //固件版本号
#define Hardware 1                  //硬件版本号

#define SECTOR_SIZE 0x200

//修改批次号或sn
#define PASS_LO ('i'*256+'t')
#define PASS_HI ('e'*256+'d')

//恢复出厂
#define PASS_UN_LO ('i'*256+'n')
#define PASS_UN_HI ('u'*256+'n')

#define PASS_IN_LO ('i'*256+'t')
#define PASS_IN_HI ('i'*256+'n')

#define u32Addr 0xFE00UL

#define PH_4_CAL       4.0f
#define PH_7_CAL       7.0f
#define PH_10_01_CAL 10.01f

//数组0也要参与计算
#define SAMPLE_PERIOD 0.1  // 采样间隔
/******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/

/******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
typedef struct
{
    float f_pHt;
    float f_ph_offset;
    float f_ph_zero;
    float f_ph_step;
    float f_t_offset;
    uint8_t modbus_id;
    uint32_t Baud_rate;
    uint16_t manual_t;
    uint16_t auto_com;
    uint16_t sn;
    uint16_t cn;
    float f_ph_zero_bak;
    float f_ph_step_bak;
} save_data_type;

/*---------------------------*/
/*映射flash空间的公共体      */
/*---------------------------*/
typedef union
{
    unsigned char save[SECTOR_SIZE];
    save_data_type save_data;
} flash;

/******************************************************************************
* Local function prototypes ('static')
* 局部函数原型(“静态”)
******************************************************************************/
static void Error_Handle()
{
    while(1);
}
/******************************************************************************
* Local variable definitions ('static')                                      *
******************************************************************************/
flash ee;
volatile int adc_n = 0;
volatile unsigned long u32AdcRestult0;
volatile unsigned long u32AdcRestult2;
volatile unsigned long u32AdcRestult3;
volatile unsigned long u32AdcRestult4;
volatile unsigned long u32AdcRestult5;
uint16_t u16AdcRestult[5][256+2];
volatile uint16_t tx_crc16 = 0xFFFF;

static uint8_t u8TxCnt=0,u8Txmax=0;
volatile uint8_t u8RxData[BUF_LENG];
volatile uint8_t u8TxData[BUF_LENG];
volatile uint8_t u8RxCnt=0;
volatile uint16_t modbus_4000_reg[MODBUS_REG_LENG];
volatile signed short modbus_3000x_reg[5];

unsigned char uart_delay = 0;        //串口的timeout定时计数
uint8_t addess = 0;
uint8_t command = 0xFF;
uint16_t data_leng = 0;
uint16_t data_address = 0;
boolean_t b_modbus_rx_ok = FALSE;
boolean_t b_modbus_command_16 = FALSE;                //modbus功能字16一次设置完成
boolean_t Broadcast_address = FALSE;                  //广播地址
volatile uint16_t crc = 0xFFFF;
boolean_t b_adc_busy = FALSE;
/*****************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
void read_ad(void);
void Uart1_Rx(void);
void Uart1_Tx(void);
void send(uint8_t UARTx,int tx_leng);
void calccrc(uint8_t crcbuf);
void bubbleSort(float arr[], int size);
//void App_ClkInit(void);
void App_Rch4MHzTo24MHz(void);
//void App_Timer0Cfg(uint16_t u16Period);
void tx_calccrc(uint8_t crcbuf);
static void GIO_Init(void);
void App_AdcPortInit(void);
void App_AdcInit(void);
//void App_AdcJqrCfg(void);
void App_AdcSQRCfg(void);//< ADC 顺序扫描 功能配置
boolean_t init_data(void);
void IapProgram(unsigned char dat[]);
static void App_WdtInit(void);
void App_UartCfg(void);
void App_PortInit(void);

/**
******************************************************************************
** \brief  Main function of project
**
** \return uint32_t return value, if needed
**
** This sample
**
******************************************************************************/
int main(void)
{
    static long i = 0;
    en_result_t enRc = Ok;
    float vin = 0,pH = 7.0,f_pH_t = 25.0;
    volatile int I16_ph;
    volatile float f_t = 0.0;
    stc_div_unsigned_result_t stcDivResult[5];
    FloatToUint fu4;
    U16ToU8 Byte2;
    volatile static int edit_n = 0;
    float pH_zero = 768.0f,pH_step = 88.5f;//放大1.5后的理论值
    float pH1 = 7.0f,pH2 = 7.0f;
    float U1 = 1536.0f,U2 = 1536.0f;
    volatile char  cal_n = 0;
    uint32_t u32_adc_acc = 0u;
    float pH_buf[15] = {7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
    float t_buf[15] = {25.0};
    volatile uint8_t buf_n = 0;
    float sort_arr[15];
    float t_sort_buf[15];
    float ubuf[15];
    volatile uint8_t ubuf_n = 0;
    volatile uint8_t t_sort_n = 0;
    volatile uint8_t u_sort_n = 0;
    float u_sort_buf[15];
    volatile double d_u500mv=0.0,d_u1000mv=0.0;
    volatile double d_utmv = 0.0,d_itma;
    volatile double d_ptn = 1000.0;
    unsigned long u32_ut = 0u;

    GIO_Init();

    Gpio_ClrIO(STK_WR_PORT, STK_WR_PIN);

    ///< ADC采样端口初始化
    App_AdcPortInit();

    App_Rch4MHzTo24MHz();

    for(i = 0; i < SECTOR_SIZE; i++)
    {
        if(0xFF != *(volatile uint8_t *)(u32Addr + i))
        {
            break;
        }
    }
    if(i==SECTOR_SIZE)
    {
        ee.save_data.modbus_id = addess = 1;
        ee.save_data.f_ph_zero = pH_zero;
        ee.save_data.f_ph_step = pH_step;
        ee.save_data.Baud_rate = 9600;
        ee.save_data.f_pHt = 25.0;
        ee.save_data.manual_t = 25.0;

        IapProgram(&ee.save[0]);
    }

    init_data();

    addess = ee.save_data.modbus_id;
    pH_zero = ee.save_data.f_ph_zero;
    pH_step = ee.save_data.f_ph_step;

    modbus_4000_reg[MODBUS_HW]= (uint16_t)Hardware;
    modbus_4000_reg[MODBUS_FW]= (uint16_t)Firmware;
    modbus_4000_reg[MODBUS_ID]= (uint16_t)addess;
    modbus_4000_reg[MODBUS_BAUD] = (uint16_t)ee.save_data.Baud_rate;
    modbus_4000_reg[MODBUS_CAL_L] = modbus_4000_reg[MODBUS_CAL_H] = 0x0000;
    modbus_4000_reg[MODBUS_CAL_1PH_L] = modbus_4000_reg[MODBUS_CAL_1PH_H] = 0x0000;
    modbus_4000_reg[MODBUS_CAL_1PHU_L] = modbus_4000_reg[MODBUS_CAL_1PH_H] = 0x0000;
    modbus_4000_reg[MODBUS_CAL_2PH_L] = modbus_4000_reg[MODBUS_CAL_2PH_H] = 0x0000;
    modbus_4000_reg[MODBUS_CAL_2PHU_L] = modbus_4000_reg[MODBUS_CAL_2PHU_H] = 0x0000;
    modbus_4000_reg[MODBUS_CAL_SUCC] = 0x0000;
    modbus_4000_reg[MODBUS_PASS_L] = 0x0000;
    modbus_4000_reg[MODBUS_PASS_H] = 0x0000;
    modbus_4000_reg[MODBUS_SN] = ee.save_data.sn;
    modbus_4000_reg[MODBUS_CN] = ee.save_data.cn;

    modbus_4000_reg[MODBUS_MANUAL_T] = ee.save_data.manual_t;
    if(ee.save_data.auto_com==0x00AA)
    {
        //自动温度补偿
        modbus_4000_reg[MODBUS_AUTO_T_PH] = 0x00AA;
    }
    else
    {
        //手动温度补偿
        modbus_4000_reg[MODBUS_AUTO_T_PH] = 0x0055;
        ee.save_data.auto_com = 0x0055 ;
    }

    fu4.f_data = ee.save_data.f_ph_zero_bak;
    modbus_4000_reg[MODBUS_BAK_ZL] = fu4.u16_data[1];
    modbus_4000_reg[MODBUS_BAK_ZH] = fu4.u16_data[0];
    fu4.f_data = ee.save_data.f_ph_step_bak;
    modbus_4000_reg[MODBUS_BAK_SL] = fu4.u16_data[1];
    modbus_4000_reg[MODBUS_BAK_SH] = fu4.u16_data[0];

    //去除零点放大和偏置,放大了1.5倍,在原始信号中有512mV偏置
    fu4.f_data = pH_zero / 1.5 - 512.0;
    modbus_4000_reg[MODBUS_PH_ZERO_L] = fu4.u16_data[1];
    modbus_4000_reg[MODBUS_PH_ZERO_H] = fu4.u16_data[0];
    fu4.f_data = pH_step / 1.5;
    modbus_4000_reg[MODBUS_PH_STEP_L] = fu4.u16_data[1];
    modbus_4000_reg[MODBUS_PH_STEP_H] = fu4.u16_data[0];
    fu4.f_data = ee.save_data.f_ph_offset;
    modbus_4000_reg[MODBUS_OFFSET_L] = fu4.u16_data[1];
    modbus_4000_reg[MODBUS_OFFSET_H] = fu4.u16_data[0];

    fu4.f_data = ee.save_data.f_t_offset;
    modbus_4000_reg[MODBUS_T_OFFSET_L] = fu4.u16_data[1];
    modbus_4000_reg[MODBUS_T_OFFSET_H] = fu4.u16_data[0];

    fu4.f_data = ee.save_data.f_pHt;
    modbus_4000_reg[MODBUS_CAL_T_L] = fu4.u16_data[1];
    modbus_4000_reg[MODBUS_CAL_T_H] = fu4.u16_data[0];

    //< ADC模块 初始化
    App_AdcInit();
//    App_Timer0Cfg(8000);   //Timer0配置初始化(周期 = 8000*(1/48M)*256 = 256ms)
//    Bt_M0_Run(TIM0);        //TIM0 运行。
    //串口引脚配置
    App_PortInit();

    //串口配置
    App_UartCfg();

    //< 除法器
    Sysctrl_SetPeripheralGate(SysctrlPeripheralDiv,TRUE);

    //看门狗配置
    App_WdtInit();

    modbus_4000_reg[0x22] = 0;
    modbus_4000_reg[0x44] = 1;
    ///< ADC 顺序扫描 功能配置
    App_AdcSQRCfg();
#if 0
    for(i=0;i<60;i++)
    {
            u8TxData = *(volatile uint8_t*)(u32Addr+i);
    }
    send(0,60);
    delay1ms(1000);////?????????????????
#endif

    while(1)
    {
            if(!b_adc_busy)
            {
                    b_adc_busy = TRUE;
        ///< 启动顺序扫描采样
        Adc_SQR_Start();
            }
        ///ad采样256次
        if(adc_n>=256)
        {
////对1000mV电压进行计算
            u32_adc_acc = 0;
            for(i=0; i<256; i++)
            {
                u32_adc_acc += u16AdcRestult[2];
            }
            enRc = Hdiv_Unsigned(u32_adc_acc,255,&stcDivResult[2]);

            if(Ok == enRc)
            {
                u32AdcRestult3 = stcDivResult[2].Quotient;
                if(stcDivResult[2].Remainder>127)
                {
                    u32AdcRestult3++;
                }
            }
            else
            {
                Error_Handle();
            }
            d_u1000mv = (((double)u32AdcRestult3) / 4096.0) * 1500.0;
            fu4.f_data = (float)d_u1000mv;
            modbus_4000_reg[MODBUS_U1000MV_H] = fu4.u16_data[0];
            modbus_4000_reg[MODBUS_U1000MV_L] = fu4.u16_data[1];
            ///1000mv---end--------
            ////对500mV电压进行计算
            u32_adc_acc = 0;
            for(i=0; i<256; i++)
            {
                u32_adc_acc += u16AdcRestult[3];
            }
            enRc = Hdiv_Unsigned(u32_adc_acc,255,&stcDivResult[3]);

            if(Ok == enRc)
            {
                u32AdcRestult4 = stcDivResult[3].Quotient;
                if(stcDivResult[3].Remainder>127)
                {
                    u32AdcRestult4++;
                }
            }
            else
            {
                Error_Handle();
            }
            d_u500mv = (((double)u32AdcRestult4) / 4096.0) * 1500.0;
            fu4.f_data = (((float)u32AdcRestult4) / 4096.0) * 1500.0;
            modbus_4000_reg[MODBUS_U500MV_H] = fu4.u16_data[0];
            modbus_4000_reg[MODBUS_U500MV_L] = fu4.u16_data[1];

            fu4.f_data = pH_zero / 1.5 - d_u500mv;
            modbus_4000_reg[MODBUS_PH_ZERO_L] = fu4.u16_data[1];
            modbus_4000_reg[MODBUS_PH_ZERO_H] = fu4.u16_data[0];
            ///500mv---end
            ///温度---------------------
            ////对温度电压进行计算
            u32_adc_acc = 0;
            for(i=0; i<256; i++)
            {
                u32_adc_acc += u16AdcRestult[1];
            }
            enRc = Hdiv_Unsigned(u32_adc_acc,255,&stcDivResult[1]);

            if(Ok == enRc)
            {
                u32AdcRestult2 = stcDivResult[1].Quotient;
                if(stcDivResult[1].Remainder>127)
                {
                    u32AdcRestult2++;
                }
            }
            else
            {
                Error_Handle();
            }
            fu4.u32_data = u32_ut = u32AdcRestult2;
            modbus_4000_reg[MODBUS_TV_H] = fu4.u16_data[0];
            modbus_4000_reg[MODBUS_TV_L] = fu4.u16_data[1];
            ////对utn电压进行计算
            u32_adc_acc = 0;
            for(i=0; i<256; i++)
            {
                u32_adc_acc += u16AdcRestult[4];
            }
            enRc = Hdiv_Unsigned(u32_adc_acc,255,&stcDivResult[4]);

            if(Ok == enRc)
            {
                u32AdcRestult5 = stcDivResult[4].Quotient;
                if(stcDivResult[4].Remainder>127)
                {
                    u32AdcRestult5++;
                }
            }
            else
            {
                Error_Handle();
            }
            fu4.u32_data = u32AdcRestult5;
            modbus_4000_reg[MODBUS_UTN_H] = fu4.u16_data[0];
            modbus_4000_reg[MODBUS_UTN_L] = fu4.u16_data[1];

            u32AdcRestult2 = u32_ut - u32AdcRestult5;

            d_utmv = ((double)u32AdcRestult2 * 1500.0) / 4096.0;
            d_itma = (d_u1000mv - (d_utmv / 34.0 + d_u500mv)) / 1000.0;
            d_ptn = (d_utmv / 34.0 + d_u500mv) / d_itma;
            f_t = (-3.9083 + sqrt((3.9083 * 3.9083) - (4.0 * (-0.0005775) * (1000-d_ptn))))
                  / (2.0 * (-0.0005775));
            //缓存数组
            for(i=0; i<14; i++)
            {
                t_buf = t_buf[i+1];
            }
            t_buf = f_t;
            //把缓存复制到排序数组
            for(i=0; i<15; i++)
            {
                sort_arr = t_buf;
            }
            //进行排序
            bubbleSort(sort_arr,15);
            //取中值
            t_sort_buf[t_sort_n++] = sort_arr[7];
            if(t_sort_n>14)
            {
                f_t = 0;
                for(i=0; i<t_sort_n; i++)
                {
                    f_t += t_sort_buf;
                }
                //进行中值平均计算
                f_t = f_t / i;

                t_sort_n = 0;
            }
///温度--end
            ///ph-------------------------
            u32_adc_acc = 0;
            ////计算电压的累计和
            for(i=0; i<256; i++)
            {
                u32_adc_acc += u16AdcRestult[0];
            }
            ////硬件进行除法计算,求平均值
            enRc = Hdiv_Unsigned(u32_adc_acc,255,&stcDivResult[0]);

            if(Ok == enRc)
            {
                u32AdcRestult0 = stcDivResult[0].Quotient;
                ////根据平均值的余数进行四舍五入计算
                if(stcDivResult[0].Remainder>127)
                {
                    u32AdcRestult0++;
                }
            }
            else
            {
                Error_Handle();
            }
            ////求ph电极电压
            vin = (((float)u32AdcRestult0) / 4096.0) * 1500.0;
            //IIR
            //vin = iirFilter(vin, &outputPrev);
            //if(ubuf_n<15)
            if(ubuf_n<5)
            {
                ubuf[ubuf_n++] = vin;
            }
            else
            {
                ubuf_n = 0;
                //for(i=0; i<15; i++)
                for(i=0; i<5; i++)
                {
                    sort_arr = ubuf;
                }
                //进行排序
                //bubbleSort(sort_arr,15);
                bubbleSort(sort_arr,5);
                //取中值
                //u_sort_buf[u_sort_n++] = sort_arr[7];
                u_sort_buf[u_sort_n++] = sort_arr[2];
                //if(u_sort_n>14)
                if(u_sort_n>4)
                {
                    vin = 0;
                    for(i=0; i<u_sort_n; i++)
                    {
                        vin += u_sort_buf;
                    }
                    vin /= u_sort_n;//中值平均数计算
                    //求pH电极原始电压,放大1.5倍,加偏置512mV
                    fu4.f_data = vin / 1.5 - d_u500mv;/////--2024-05-13---512.0;
                    modbus_4000_reg[MODBUS_PH_V_H] = fu4.u16_data[0];
                    modbus_4000_reg[MODBUS_PH_V_L] = fu4.u16_data[1];
                    u_sort_n = 0;
                    pH_zero = ee.save_data.f_ph_zero;
                    pH_step = ee.save_data.f_ph_step;
                    //计算pH值
                    pH = 7 - (vin - pH_zero) / pH_step;
#if 1
                    if(buf_n<15)
                    {
                        pH_buf[buf_n++] = pH;
                        pH = 0;
                        for(i=0; i<buf_n; i++)
                        {
                            pH += pH_buf;
                        }
                        pH = pH / i;
                    }
                    else
                    {
                        //pH缓存数组
                        for(i=0; i<14; i++)
                        {
                            pH_buf = pH_buf[i+1];
                        }
                        pH_buf = pH;
                        pH = 0;
                        for(i=0; i<15; i++)
                        {
                            pH += pH_buf;
                        }
                        pH = pH / i;
                    }
#endif
                    fu4.f_data = pH;
                    modbus_4000_reg[MODBUS_PH_NO_T_H] = fu4.u16_data[0];
                    modbus_4000_reg[MODBUS_PH_NO_T_L] = fu4.u16_data[1];

                    ///ph温度补-----------------------------------------
                    //ph温度补偿计算
                    if(ee.save_data.auto_com==0x00AA)
                    {
                        fu4.f_data = f_t + ee.save_data.f_t_offset;

                        f_pH_t = pH - ((f_t-ee.save_data.f_pHt) * fabs(pH-7) * 0.003);
#if 0
                        //-----2024-09-06----根据梅德勒电极修改温补
                        vin = vin / 1.5 - d_u500mv;//去掉1.5倍放大和512mv偏置
                        pH_zero = pH_zero / 1.5 - d_u500mv;
                        f_pH_t = (vin / (pH_zero - 0.198 * (fu4.f_data + 273.15))) + 7.0;
#endif
                        modbus_4000_reg[MODBUS_T_L] = fu4.u16_data[1];
                        modbus_4000_reg[MODBUS_T_H] = fu4.u16_data[0];
                    }
                    else if(ee.save_data.auto_com==0x0055)
                    {
                        f_pH_t = pH - (((float)ee.save_data.manual_t - ee.save_data.f_pHt) \
                                       * fabs(pH-7) * 0.003);
                        fu4.f_data = (float)ee.save_data.manual_t;
                        modbus_4000_reg[MODBUS_T_H] = fu4.u16_data[0];
                        modbus_4000_reg[MODBUS_T_L] = fu4.u16_data[1];
                    }
                    else
                    {
                        f_pH_t = pH;
                    }

                    f_pH_t += ee.save_data.f_ph_offset;

                    if(f_pH_t<0.001)
                    {
                        f_pH_t = 0.0;
                    }
                    else if(f_pH_t>14.0)
                    {
                        f_pH_t = 14.0f;
                    }
                    ///ph温度补---end-----------------
                    I16_ph = (int)((f_pH_t + 0.005) * 100.0);
                    fu4.f_data = (float)I16_ph / 100.0;
                    modbus_4000_reg[MODBUS_PH_H] = fu4.u16_data[0];
                    modbus_4000_reg[MODBUS_PH_L] = fu4.u16_data[1];
                }
            }
            ///ph---end-----------------
            adc_n = 0;
        }
        if(b_modbus_rx_ok)
        {
            switch(command)
            {
            case 3:
                u8TxData[0] = addess;
                u8TxData[1] = 0x03;
                u8TxData[2] = 2 * data_leng;
                for(i=0; i<data_leng; i++)
                {
                    Byte2.u16_i = modbus_4000_reg[i+data_address];
                    u8TxData[2*i+3] = Byte2.u8_c[1];
                    u8TxData[2*i+4] = Byte2.u8_c[0];
                }
                tx_crc16 = 0xFFFF;
                for (i = 0; i < (u8TxData[2]+3); i++)
                {
                    tx_calccrc(u8TxData);
                }
                Byte2.u16_i = tx_crc16;
                u8TxData[i++] = Byte2.u8_c[0];
                u8TxData[i++] = Byte2.u8_c[1];
                send(0,i);
                break;
            case 6:   //modbus接收到06命令
                //修改modbus id或者串口波特率
                if((addess!=(uint8_t)(modbus_4000_reg[MODBUS_ID]&0x00FF)) \
                        ||(ee.save_data.Baud_rate != (uint32_t)modbus_4000_reg[MODBUS_BAUD]))
                {
                    ee.save_data.modbus_id = (uint8_t)(modbus_4000_reg[MODBUS_ID]&0x00FF);
                    addess = ee.save_data.modbus_id;
                    ee.save_data.Baud_rate = (uint32_t)modbus_4000_reg[MODBUS_BAUD];
                }
                ////接收过一次编辑密码
                if(edit_n>=1)
                {
                    edit_n = 0;
                    ee.save_data.sn = modbus_4000_reg[MODBUS_SN];
                    ee.save_data.cn = modbus_4000_reg[MODBUS_CN];
                }
                ee.save_data.manual_t = modbus_4000_reg[MODBUS_MANUAL_T];
                if(modbus_4000_reg[MODBUS_AUTO_T_PH]==0x00AA)
                {
                    ee.save_data.auto_com = 0x00AA;
                }
                else
                {
                    ee.save_data.auto_com = 0x0055;
                }
                IapProgram(&ee.save[0]);//数据写入flash

                ///< 启动 WDT,为了重启arm
                Wdt_Start();
                break;
            }
            b_modbus_rx_ok = FALSE;
        }
        //modbus接收到16命令
        if(b_modbus_command_16)
        {
            FloatToUint fu4_cal;
            b_modbus_command_16 = FALSE;
            if(modbus_4000_reg[MODBUS_PASS_L]!=0x0000)
            {
                ////收到编辑密码
                if((modbus_4000_reg[MODBUS_PASS_L]==PASS_LO)        \
                        &&(modbus_4000_reg[MODBUS_PASS_H]==PASS_HI))
                {
                    edit_n++;
                    goto LOOP;
                }
                ////收到恢复出厂设置密码
                if((modbus_4000_reg[MODBUS_PASS_L]==PASS_UN_LO)        \
                        &&(modbus_4000_reg[MODBUS_PASS_H]==PASS_UN_HI))
                {
                    pH_zero = (ee.save_data.f_ph_zero_bak + 512.0) * 1.5;
                    pH_step = ee.save_data.f_ph_step_bak * 1.5;
                    ee.save_data.f_ph_zero = pH_zero;
                    ee.save_data.f_ph_step = pH_step;
                    modbus_4000_reg[MODBUS_PH_ZERO_L] = modbus_4000_reg[MODBUS_BAK_ZL];
                    modbus_4000_reg[MODBUS_PH_ZERO_H] = modbus_4000_reg[MODBUS_BAK_ZH];

                    modbus_4000_reg[MODBUS_PH_STEP_L] = modbus_4000_reg[MODBUS_BAK_SL];
                    modbus_4000_reg[MODBUS_PH_STEP_H] = modbus_4000_reg[MODBUS_BAK_SH];
                    IapProgram(&ee.save[0]);//数据写入flash
                    ///< 启动 WDT
                    Wdt_Start();
                }
                ////收到出厂设置密码
                if((modbus_4000_reg[MODBUS_PASS_L]==PASS_IN_LO)        \
                        &&(modbus_4000_reg[MODBUS_PASS_H]==PASS_IN_HI))
                {
                    fu4.u16_data[1] = modbus_4000_reg[MODBUS_BAK_ZL];
                    fu4.u16_data[0] = modbus_4000_reg[MODBUS_BAK_ZH];
                    ee.save_data.f_ph_zero_bak = fu4.f_data;
                    fu4.u16_data[1] = modbus_4000_reg[MODBUS_BAK_SL];
                    fu4.u16_data[0] = modbus_4000_reg[MODBUS_BAK_SH];
                    ee.save_data.f_ph_step_bak = fu4.f_data;
                }
                modbus_4000_reg[MODBUS_PASS_L] = 0x0000;
                modbus_4000_reg[MODBUS_PASS_H] = 0x0000;
            }
            ////收到校准数据
            if((modbus_4000_reg[MODBUS_CAL_L]!=0x0000)        \
                    ||(modbus_4000_reg[MODBUS_CAL_H]!=0x0000))
            {
                fu4.u16_data[1] = modbus_4000_reg[MODBUS_CAL_L];
                fu4.u16_data[0] = modbus_4000_reg[MODBUS_CAL_H];
                if(fabs(fu4.f_data - PH_7_CAL)<1.0)
                {
                    cal_n++;/////校准次数记录
                    if(cal_n==1)//////第一次校准
                    {
                        pH1 = fu4.f_data;
                        U1 = vin;
                        modbus_4000_reg[MODBUS_CAL_1PH_L] = modbus_4000_reg[MODBUS_CAL_L];
                        modbus_4000_reg[MODBUS_CAL_1PH_H] = modbus_4000_reg[MODBUS_CAL_H];
                        fu4_cal.f_data = (vin / 1.5) - d_u500mv;
                        modbus_4000_reg[MODBUS_CAL_1PHU_L] = fu4_cal.u16_data[1];
                        modbus_4000_reg[MODBUS_CAL_1PHU_H] = fu4_cal.u16_data[0];
                        modbus_4000_reg[MODBUS_CAL_SUCC] = 0x0001;
                        modbus_4000_reg[MODBUS_CAL_L] = modbus_4000_reg[MODBUS_CAL_H] = 0x0000;
                        goto LOOP;
                    }
                    else if(cal_n==2)//////第二次校准
                    {
                        pH2 = fu4.f_data;
                        U2 = vin;
                        modbus_4000_reg[MODBUS_CAL_2PH_L] = modbus_4000_reg[MODBUS_CAL_L];
                        modbus_4000_reg[MODBUS_CAL_2PH_H] = modbus_4000_reg[MODBUS_CAL_H];
                        fu4_cal.f_data = (vin / 1.5) - d_u500mv;
                        modbus_4000_reg[MODBUS_CAL_2PHU_L] = fu4_cal.u16_data[1];
                        modbus_4000_reg[MODBUS_CAL_2PHU_H] = fu4_cal.u16_data[0];
                        modbus_4000_reg[MODBUS_CAL_SUCC] = 0x0201;
                    }
                }
                                                                /*
                else if(fabs(fu4.f_data - PH_6_86_CAL)<1.0)
                {
                    cal_n++;
                    if(cal_n==1)
                    {
                        pH1 = PH_6_86_CAL;
                        U1 = vin;
                        modbus_4000_reg[MODBUS_CAL_1PH_L] = modbus_4000_reg[MODBUS_CAL_L];
                        modbus_4000_reg[MODBUS_CAL_1PH_H] = modbus_4000_reg[MODBUS_CAL_H];
                        fu4_cal.f_data = (vin / 1.5) - 512.0;
                        modbus_4000_reg[MODBUS_CAL_1PHU_L] = fu4_cal.u16_data[1];
                        modbus_4000_reg[MODBUS_CAL_1PHU_H] = fu4_cal.u16_data[0];
                        modbus_4000_reg[MODBUS_CAL_SUCC] = 0x0001;
                        modbus_4000_reg[MODBUS_CAL_L] = modbus_4000_reg[MODBUS_CAL_H] = 0x0000;
                        goto LOOP;
                    }
                    else if(cal_n==2)
                    {
                        pH2 = PH_6_86_CAL;
                        U2 = vin;
                        modbus_4000_reg[MODBUS_CAL_2PH_L] = modbus_4000_reg[MODBUS_CAL_L];
                        modbus_4000_reg[MODBUS_CAL_2PH_H] = modbus_4000_reg[MODBUS_CAL_H];
                        fu4_cal.f_data = (vin / 1.5) - 512.0;
                        modbus_4000_reg[MODBUS_CAL_2PHU_L] = fu4_cal.u16_data[1];
                        modbus_4000_reg[MODBUS_CAL_2PHU_H] = fu4_cal.u16_data[0];
                        modbus_4000_reg[MODBUS_CAL_SUCC] = 0x0201;
                    }
                }
                                                                */
                else if(fabs(fu4.f_data - PH_4_CAL)<1.0)
                {
                    cal_n++;
                    if(cal_n==1)
                    {
                        pH1 = fu4.f_data;
                        U1 = vin;
                        modbus_4000_reg[MODBUS_CAL_1PH_L] = modbus_4000_reg[MODBUS_CAL_L];
                        modbus_4000_reg[MODBUS_CAL_1PH_H] = modbus_4000_reg[MODBUS_CAL_H];
                        fu4_cal.f_data = (vin / 1.5) - d_u500mv;
                        modbus_4000_reg[MODBUS_CAL_1PHU_L] = fu4_cal.u16_data[1];
                        modbus_4000_reg[MODBUS_CAL_1PHU_H] = fu4_cal.u16_data[0];
                        modbus_4000_reg[MODBUS_CAL_SUCC] = 0x0001;
                        modbus_4000_reg[MODBUS_CAL_L] = modbus_4000_reg[MODBUS_CAL_H] = 0x0000;
                        goto LOOP;
                    }
                    else if(cal_n==2)
                    {
                        pH2 = fu4.f_data;
                        U2 = vin;
                        modbus_4000_reg[MODBUS_CAL_2PH_L] = modbus_4000_reg[MODBUS_CAL_L];
                        modbus_4000_reg[MODBUS_CAL_2PH_H] = modbus_4000_reg[MODBUS_CAL_H];
                        fu4_cal.f_data = (vin / 1.5) - d_u500mv;
                        modbus_4000_reg[MODBUS_CAL_2PHU_L] = fu4_cal.u16_data[1];
                        modbus_4000_reg[MODBUS_CAL_2PHU_H] = fu4_cal.u16_data[0];
                        modbus_4000_reg[MODBUS_CAL_SUCC] = 0x0201;
                    }
                }
                                                                /*
                else if(fabs(fu4.f_data - PH_4_01_CAL)<1.0)
                {
                    cal_n++;
                    if(cal_n==1)
                    {
                        pH1 = PH_4_01_CAL;
                        U1 = vin;
                        modbus_4000_reg[MODBUS_CAL_1PH_L] = modbus_4000_reg[MODBUS_CAL_L];
                        modbus_4000_reg[MODBUS_CAL_1PH_H] = modbus_4000_reg[MODBUS_CAL_H];
                        fu4_cal.f_data = (vin / 1.5) - 512.0;
                        modbus_4000_reg[MODBUS_CAL_1PHU_L] = fu4_cal.u16_data[1];
                        modbus_4000_reg[MODBUS_CAL_1PHU_H] = fu4_cal.u16_data[0];
                        modbus_4000_reg[MODBUS_CAL_SUCC] = 0x0001;
                        modbus_4000_reg[MODBUS_CAL_L] = modbus_4000_reg[MODBUS_CAL_H] = 0x0000;
                        goto LOOP;
                    }
                    else if(cal_n==2)
                    {
                        pH2 = PH_4_01_CAL;
                        U2 = vin;
                        modbus_4000_reg[MODBUS_CAL_2PH_L] = modbus_4000_reg[MODBUS_CAL_L];
                        modbus_4000_reg[MODBUS_CAL_2PH_H] = modbus_4000_reg[MODBUS_CAL_H];
                        fu4_cal.f_data = (vin / 1.5) - 512.0;
                        modbus_4000_reg[MODBUS_CAL_2PHU_L] = fu4_cal.u16_data[1];
                        modbus_4000_reg[MODBUS_CAL_2PHU_H] = fu4_cal.u16_data[0];
                        modbus_4000_reg[MODBUS_CAL_SUCC] = 0x0201;
                    }
                }
                else if(fu4.f_data == PH_9_18_CAL)
                {
                    cal_n++;
                    if(cal_n==1)
                    {
                        pH1 = PH_9_18_CAL;
                        U1 = vin;
                        modbus_4000_reg[MODBUS_CAL_1PH_L] = modbus_4000_reg[MODBUS_CAL_L];
                        modbus_4000_reg[MODBUS_CAL_1PH_H] = modbus_4000_reg[MODBUS_CAL_H];
                        fu4_cal.f_data = (vin / 1.5) - 512.0;
                        modbus_4000_reg[MODBUS_CAL_1PHU_L] = fu4_cal.u16_data[1];
                        modbus_4000_reg[MODBUS_CAL_1PHU_H] = fu4_cal.u16_data[0];
                        modbus_4000_reg[MODBUS_CAL_SUCC] = 0x0001;
                        modbus_4000_reg[MODBUS_CAL_L] = modbus_4000_reg[MODBUS_CAL_H] = 0x0000;
                        goto LOOP;
                    }
                    else if(cal_n==2)
                    {
                        pH2 = PH_9_18_CAL;
                        U2 = vin;
                        modbus_4000_reg[MODBUS_CAL_2PH_L] = modbus_4000_reg[MODBUS_CAL_L];
                        modbus_4000_reg[MODBUS_CAL_2PH_H] = modbus_4000_reg[MODBUS_CAL_H];
                        fu4_cal.f_data = (vin / 1.5) - 512.0;
                        modbus_4000_reg[MODBUS_CAL_2PHU_L] = fu4_cal.u16_data[1];
                        modbus_4000_reg[MODBUS_CAL_2PHU_H] = fu4_cal.u16_data[0];
                        modbus_4000_reg[MODBUS_CAL_SUCC] = 0x0201;
                    }
                }
                                                                */
                else if(fabs(fu4.f_data - PH_10_01_CAL)<1.0)
                {
                    cal_n++;
                    if(cal_n==1)
                    {
                        pH1 = fu4.f_data;
                        U1 = vin;
                        modbus_4000_reg[MODBUS_CAL_1PH_L] = modbus_4000_reg[MODBUS_CAL_L];
                        modbus_4000_reg[MODBUS_CAL_1PH_H] = modbus_4000_reg[MODBUS_CAL_H];
                        fu4_cal.f_data = (vin / 1.5) - d_u500mv;
                        modbus_4000_reg[MODBUS_CAL_1PHU_L] = fu4_cal.u16_data[1];
                        modbus_4000_reg[MODBUS_CAL_1PHU_H] = fu4_cal.u16_data[0];
                        modbus_4000_reg[MODBUS_CAL_SUCC] = 0x0001;
                        modbus_4000_reg[MODBUS_CAL_L] = modbus_4000_reg[MODBUS_CAL_H] = 0x0000;
                        goto LOOP;
                    }
                    else if(cal_n==2)
                    {
                        pH2 = fu4.f_data;
                        U2 = vin;
                        modbus_4000_reg[MODBUS_CAL_2PH_L] = modbus_4000_reg[MODBUS_CAL_L];
                        modbus_4000_reg[MODBUS_CAL_2PH_H] = modbus_4000_reg[MODBUS_CAL_H];
                        fu4_cal.f_data = (vin / 1.5) - d_u500mv;
                        modbus_4000_reg[MODBUS_CAL_2PHU_L] = fu4_cal.u16_data[1];
                        modbus_4000_reg[MODBUS_CAL_2PHU_H] = fu4_cal.u16_data[0];
                        modbus_4000_reg[MODBUS_CAL_SUCC] = 0x0201;
                    }
                }
                ////接收到两次校准数据,开始计算零点和斜率
                if(cal_n>=2)
                {
                    pH_zero = ((7.0f-pH1)*U2 - (7.0f-pH2)*U1)/(pH2-pH1);
                    pH_step = (U1 - pH_zero) / (7.0f - pH1);

                    modbus_4000_reg[MODBUS_OFFSET_L] = 0x0000;
                    modbus_4000_reg[MODBUS_OFFSET_H] = 0x0000;
                    fu4.f_data = ee.save_data.f_ph_zero = pH_zero;
                    fu4.f_data = fu4.f_data / 1.5 -d_u500mv;
                    modbus_4000_reg[MODBUS_PH_ZERO_L] = fu4.u16_data[1];
                    modbus_4000_reg[MODBUS_PH_ZERO_H] = fu4.u16_data[0];
                    fu4.f_data = ee.save_data.f_ph_step = pH_step;
                    fu4.f_data = fu4.f_data / 1.5;
                    modbus_4000_reg[MODBUS_PH_STEP_L] = fu4.u16_data[1];
                    modbus_4000_reg[MODBUS_PH_STEP_H] = fu4.u16_data[0];
                    ee.save_data.f_pHt = f_t + ee.save_data.f_t_offset;
                    fu4.f_data = ee.save_data.f_pHt;
                    modbus_4000_reg[MODBUS_CAL_T_L] = fu4.u16_data[1];
                    modbus_4000_reg[MODBUS_CAL_T_H] = fu4.u16_data[0];
                    cal_n = 0;
                }
                modbus_4000_reg[MODBUS_CAL_L] = modbus_4000_reg[MODBUS_CAL_H] = 0x0000;
            }
            else
            {
                fu4.u16_data[1] = modbus_4000_reg[MODBUS_OFFSET_L];
                fu4.u16_data[0] = modbus_4000_reg[MODBUS_OFFSET_H];
                ee.save_data.f_ph_offset = fu4.f_data;
                ee.save_data.modbus_id = (uint8_t)(modbus_4000_reg[MODBUS_ID]&0x00FF);
                addess = ee.save_data.modbus_id;
                ee.save_data.Baud_rate = (uint32_t)modbus_4000_reg[MODBUS_BAUD];
#if 1
                fu4.f_data = pH_zero / 1.5 - 512.0;
                modbus_4000_reg[MODBUS_PH_ZERO_L] = fu4.u16_data[1];
                modbus_4000_reg[MODBUS_PH_ZERO_H] = fu4.u16_data[0];
                fu4.f_data = pH_step / 1.5;
                modbus_4000_reg[MODBUS_PH_STEP_L] = fu4.u16_data[1];
                modbus_4000_reg[MODBUS_PH_STEP_H] = fu4.u16_data[0];
#else
                fu4.u16_data[1] = modbus_4000_reg[MODBUS_PH_ZERO_L];
                fu4.u16_data[0] = modbus_4000_reg[MODBUS_PH_ZERO_H];
                ee.save_data.f_ph_zero = pH_zero = fu4.f_data;
                fu4.u16_data[1] = modbus_4000_reg[MODBUS_PH_STEP_L];
                fu4.u16_data[0] = modbus_4000_reg[MODBUS_PH_STEP_H];
                ee.save_data.f_ph_step = pH_step = fu4.f_data;
#endif
                fu4.u16_data[1] = modbus_4000_reg[MODBUS_T_OFFSET_L];
                fu4.u16_data[0] = modbus_4000_reg[MODBUS_T_OFFSET_H];
                ee.save_data.f_t_offset = fu4.f_data;

                fu4.u16_data[1] = modbus_4000_reg[MODBUS_CAL_T_L];
                fu4.u16_data[0] = modbus_4000_reg[MODBUS_CAL_T_H];
                ee.save_data.f_pHt = fu4.f_data;
                ee.save_data.manual_t = modbus_4000_reg[MODBUS_MANUAL_T];
                if(modbus_4000_reg[MODBUS_AUTO_T_PH]==0x00AA)
                {
                    ee.save_data.auto_com = 0x00AA;
                }
                else
                {
                    ee.save_data.auto_com = 0x0055;
                }
            }
            //保存设置
            IapProgram(&ee.save[0]);//数据写入flash
            ///< 启动 WDT
            ///Wdt_Start();
        }
LOOP:
        ;
    }
}

static void GIO_Init(void)
{
        stc_gpio_config_t stcGpioCfg;

    ///< 打开GPIO外设时钟门控
    Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);

    ///< 端口方向配置->输出
    stcGpioCfg.enDir = GpioDirOut;
    ///< 端口驱动能力配置->高驱动能力
    stcGpioCfg.enDrv = GpioDrvH;
    ///< 端口上下拉配置->无上下拉
    stcGpioCfg.enPuPd = GpioPu;
    ///< 端口开漏输出配置->开漏输出关闭
    stcGpioCfg.enOD = GpioOdDisable;
    ///< 端口输入/输出值寄存器总线控制模式配置->AHB
    stcGpioCfg.enCtrlMode = GpioAHB;
    ///< GPIO IO LED端口初始化
    Gpio_Init(STK_WR_PORT, STK_WR_PIN, &stcGpioCfg);
}

//将时钟从RCH4MHz切换至RCH24MHz,
void App_Rch4MHzTo24MHz(void)
{
    ///<============== 将时钟从RCH4MHz切换至RCH24MHz ==============================
    ///< RCH时钟不同频率的切换,需要先将时钟切换到RCL,设置好频率后再切回RCH
    Sysctrl_SetRCLTrim(SysctrlRclFreq32768);
    Sysctrl_ClkSourceEnable(SysctrlClkRCL, TRUE);
    Sysctrl_SysClkSwitch(SysctrlClkRCL);

    ///< 加载目标频率的RCH的TRIM值
    Sysctrl_SetRCHTrim(SysctrlRchFreq8MHz);//(SysctrlRchFreq24MHz);
    ///< 使能RCH
    Sysctrl_ClkSourceEnable(SysctrlClkRCH, TRUE);
    ///< 时钟切换到RCH
    Sysctrl_SysClkSwitch(SysctrlClkRCH);
    ///< 关闭RCL时钟
    ///Sysctrl_ClkSourceEnable(SysctrlClkRCL, FALSE);
}

void IapProgram(unsigned char dat[])
{
    ///< STEP-1: 确保初始化正确执行后方能进行FLASH编程操作,FLASH初始化(编程时间,休眠模式配置)
    while(Ok != Flash_Init(NULL,2, TRUE));

     //< ==> 8位编程
    ///< STEP-3 FLASH目标扇区擦除
    while(Ok != Flash_SectorErase(u32Addr))
    {
            ;
    }
    ///< STEP-4 FLASH 字节写、校验
        //while(Ok!= Flash_WriteByteS(u32Addr, dat,SECTOR_SIZE));
        Flash_WriteByteS(u32Addr, dat,SECTOR_SIZE);
    ///< FLASH 读模式
}

//初始化参数
boolean_t init_data(void)
{
    uint16_t i;

    for(i = 0; i < SECTOR_SIZE; i++)
    {
        ee.save = *(volatile uint8_t *)(u32Addr + i);
    }

    return Ok;
}

static void App_WdtInit(void)
{
        stc_wdt_config_t StcWdtCfg;

    ///< 开启WDT外设时钟
    Sysctrl_SetPeripheralGate(SysctrlPeripheralWdt,TRUE);
    StcWdtCfg.enResetEnable = WRESET_EN;
    StcWdtCfg.pfnWdtIrqCb = NULL;
    StcWdtCfg.u8LoadValue = 3;
    ///< WDT 初始化
    Wdt_Init(&StcWdtCfg);
}

void bubbleSort(float arr[], int size)
{
    for (int i = 0; i < size - 1; i++)
    {
        for (int j = 0; j < size - i - 1; j++)
        {
            if (arr[j] > arr[j + 1])
            {
                // 交换arr[j]和arr[j+1]
                float temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}

///< ADC 顺序扫描 功能配置
void App_AdcSQRCfg(void)
{
        stc_adc_cfg_t          stcAdcCfg;

    DDL_ZERO_STRUCT(stcAdcCfg);

    ///< 顺序扫描模式功能及通道配置
    ///< 注意:扫描模式下,当配置转换次数为n时,转换通道的配置范围必须为[SQRCH(0)MUX,SQRCH(n-1)MUX]
    stcAdcCfg.enAdcOpMode = AdcSCanMode;
    stcAdcCfg.bAdcInBufEn = TRUE;
    stcAdcCfg.enAdcClkDiv = AdcClkSysTDiv1;
    stcAdcCfg.enAdcRefVolSel = RefVolSelInBgr1p5;
    stcAdcCfg.enAdcSampTimeSel = AdcSampTime12Clk;
#if 0
    stcAdcSqrCfg.bSqrDmaTrig = FALSE;
    stcAdcSqrCfg.enResultAcc = AdcResultAccDisable;//AdcResultAccEnable;
    stcAdcSqrCfg.u8SqrCnt    = 5;
    Adc_SqrModeCfg(&stcAdcSqrCfg);
#endif

    Adc_ConfigSqrChannel(CH0MUX, AdcExInputCH2);
    Adc_ConfigSqrChannel(CH1MUX, AdcExInputCH4);
    Adc_ConfigSqrChannel(CH2MUX, AdcExInputCH5);
    Adc_ConfigSqrChannel(CH3MUX, AdcExInputCH6);
    Adc_ConfigSqrChannel(CH4MUX, AdcExInputCH7);

    Adc_ConfigSqrMode(&stcAdcCfg,5,FALSE);
    ///< ADC 中断使能
    Adc_EnableIrq();
    EnableNvic(ADC_IRQn, IrqLevel3, TRUE);

    ///< 启动顺序扫描采样
    Adc_SQR_Start();
}

///< ADC模块 初始化
void App_AdcInit(void)
{
        stc_adc_cfg_t          stcAdcCfg;
        DDL_ZERO_STRUCT(stcAdcCfg);

    Sysctrl_SetPeripheralGate(SysctrlPeripheralAdcBgr, TRUE);
    Bgr_BgrEnable();        ///< 开启BGR
    delay10us(2);

        ///< 顺序扫描模式功能及通道配置
        ///< 注意:扫描模式下,当配置转换次数为n时,转换通道的配置范围必须为[SQRCH(0)MUX,SQRCH(n-1)MUX]
        stcAdcCfg.enAdcOpMode = AdcSCanMode;
        stcAdcCfg.bAdcInBufEn = TRUE;
        stcAdcCfg.enAdcClkDiv = AdcClkSysTDiv1;
        stcAdcCfg.enAdcRefVolSel = RefVolSelInBgr1p5;
        stcAdcCfg.enAdcSampTimeSel = AdcSampTime12Clk;

    //Bgr_TempSensorEnable(); ///温度传感器使能(需要先开启BGR)
    ///< ADC 初始化配置
    //stcAdcCfg.enInRef           = AdcMskInRefEnable;       ///<内部参考电压使能
    //stcAdcCfg.enAdcAlign        = AdcAlignRight;               ///<转换结果对齐方式-右
    stc_adc_irq_calbakfn_pt_t StcAdIrqCB;
    stc_adc_irq_t StcAdIrq;
    StcAdIrq.bAdcHhtCmp = FALSE;
        StcAdIrq.bAdcIrq = FALSE;
        StcAdIrq.bAdcJQRIrq = FALSE;
        StcAdIrq.bAdcLltCmp = FALSE;
        StcAdIrq.bAdcRegCmp = FALSE;
        StcAdIrq.bAdcSQRIrq = TRUE;

        StcAdIrqCB.pfnAdcHhtIrq = NULL;
        StcAdIrqCB.pfnAdcIrq = NULL;
        StcAdIrqCB.pfnAdcJQRIrq = NULL;
        StcAdIrqCB.pfnAdcLltIrq = NULL;
        StcAdIrqCB.pfnAdcRegIrq = NULL;
        StcAdIrqCB.pfnAdcSQRIrq = read_ad;
    Adc_ConfigIrq(&StcAdIrq,&StcAdIrqCB);
    Adc_Init(&stcAdcCfg);
    Adc_Enable();
}

///< ADC 采样端口初始化
void App_AdcPortInit(void)
{
    ///< 开启ADC/BGR GPIO外设时钟
    Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);

    //    Gpio_SetAnalogMode(GpioPortA, GpioPin0);        //PA00 (AIN0)
    Gpio_SetAnalogMode(GpioPortA, GpioPin2);        //PA02 (AIN2)
    Gpio_SetAnalogMode(GpioPortA, GpioPin4);        //PA04 (AIN4)
    Gpio_SetAnalogMode(GpioPortA, GpioPin5);        //PA02 (AIN5)
    Gpio_SetAnalogMode(GpioPortA, GpioPin6);        //PA04 (AIN6)
    Gpio_SetAnalogMode(GpioPortA, GpioPin7);        //PA04 (AIN7)
}

//---------------------------------------------------------------------------------------------------------
void tx_calccrc(uint8_t crcbuf)
{
    uint8_t jj;
    boolean_t TT;

    tx_crc16 = tx_crc16 ^ (unsigned int)(crcbuf & 0x00FF);
    for(jj = 0; jj < 8; jj++)
    {
        if(tx_crc16 & 0x01)
        {
            TT = TRUE;
        }
        else
        {
            TT = FALSE;
        }
        tx_crc16 = tx_crc16 >> 1;
        tx_crc16 = tx_crc16 & 0x7FFF;
        if (TT)
        {
            tx_crc16 = tx_crc16 ^ 0xA001;
        }
    }
}

void calccrc(uint8_t crcbuf)
{
    uint8_t jj;
    boolean_t TT;

    crc = crc ^ ((uint16_t)crcbuf & 0x00FF);
    for(jj = 0; jj < 8; jj++)
    {
        if(crc & 0x0001)
        {
            TT = TRUE;
        }
        else
        {
            TT = FALSE;
        }
        crc = crc >> 1;
        crc = crc & 0x7FFF;
        if (TT)
        {
            crc = crc ^ 0xA001;
        }
    }
}

//串口引脚配置
void App_PortInit(void)
{
        stc_gpio_config_t stcGpioCfg;

    DDL_ZERO_STRUCT(stcGpioCfg);

    Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE); //使能GPIO模块时钟

    ///<TX
    stcGpioCfg.enDir = GpioDirOut;
    Gpio_Init(GpioPortA, GpioPin9, &stcGpioCfg);
    Gpio_SetAfMode(GpioPortA, GpioPin9, GpioAf1);          //配置PA02 端口为URART1_TX

    ///<RX
    stcGpioCfg.enDir = GpioDirIn;
    Gpio_Init(GpioPortA, GpioPin10, &stcGpioCfg);
    Gpio_SetAfMode(GpioPortA, GpioPin10, GpioAf1);          //配置PA03 端口为URART1_RX
}

//串口配置
void App_UartCfg(void)
{
        stc_uart_config_t    stcCfg;

    DDL_ZERO_STRUCT(stcCfg);

    ///< 开启外设时钟
    Sysctrl_SetPeripheralGate(SysctrlPeripheralUart0,TRUE);///<使能uart1模块时钟
/*
    en_uart_mode_t       enRunMode;      ///< 四种模式配置
    en_uart_stop_t       enStopBit;      ///<停止位长度
    stc_uart_multimode_t* pstcMultiMode; ///<多主机模式配置
    stc_uart_irq_cb_t*  pstcIrqCb;       ///<中断服务函数
    boolean_t           bTouchNvic;      ///<NVIC中断使能
* */
    ///<UART Init
    stcCfg.enRunMode        = UartMode1;          ///<模式1
    stcCfg.enStopBit        = Uart1bit;           ///<1bit停止位
    stcCfg.pstcMultiMode->enMulti_mode = UartNormal;
    stcCfg.bTouchNvic = TRUE;
    /*
    func_ptr_t pfnTxIrqCb;    ///<发送中断服务函数
    func_ptr_t pfnRxFEIrqCb;  ///<接收帧错误中断服务函数
    func_ptr_t pfnRxIrqCb;    ///<接收中断服务函数
    func_ptr_t pfnCtsIrqCb;   ///<CTS信号翻转中断服务函数
    func_ptr_t pfnPEIrqCb;    ///<奇偶校验错误中断服务函数
     * */
    stc_uart_irq_cb_t StcUartIrqCB;

        StcUartIrqCB.pfnCtsIrqCb = NULL;
    StcUartIrqCB.pfnPEIrqCb  = NULL;
    StcUartIrqCB.pfnRxFEIrqCb = NULL;
    StcUartIrqCB.pfnRxIrqCb = Uart1_Rx;
    StcUartIrqCB.pfnTxIrqCb = Uart1_Tx;
    stcCfg.pstcIrqCb = &StcUartIrqCB;
    //stcCfg.enMmdorCk        = UartDataOrAddr;
    stc_uart_baud_t StcUartBaud;
    StcUartBaud.enRunMode = UartMode1;
    StcUartBaud.u32Pclk = Sysctrl_GetPClkFreq(); ///<获得外设时钟(PCLK)频率值
    if(modbus_4000_reg[MODBUS_BAUD]==19200)
    {
            StcUartBaud.u32Baud = 19200UL;       ///<波特率19200
    }
    else
    {
            StcUartBaud.u32Baud = 9600UL;       ///<波特率9600
    }

//    stcCfg.stcBaud.enClkDiv = UartMsk8Or16Div;       ///<通道采样分频配置
    Uart_SetBaud(0,Uart_CalScnt(0,&StcUartBaud));
    Uart_EnableFunc(0,UartRx);
    Uart_Init(0, &stcCfg);                   ///<串口初始化
    ///<UART中断使能
    Uart_ClrStatus(0,UartRC);                ///<清接收请求
    Uart_ClrStatus(0,UartTC);                ///<清接收请求
    Uart_EnableIrq(0,UartRxIrq);             ///<使能串口接收中断
    Uart_EnableIrq(0,UartTxIrq);             ///<使能串口接收中断
    EnableNvic(UART0_IRQn, IrqLevel3, TRUE);       ///<系统中断使能
}

void Uart1_Rx(void)
{
    volatile uint8_t k,i,n;
    volatile uint16_t rx_crc, temp0_i16, temp1_i16;
    U16ToU8 uart_temporary;

        k = Uart_ReceiveData(0);   //接收数据字节
        uart_delay = 0;

        if((k == addess) && (u8RxCnt == 0))// || (k == 0)
        {
            u8RxData[0] = addess;
            u8RxCnt++;
            if(k==0)
            {
                Broadcast_address = TRUE;
            }
            return;
        }
        else if((u8RxCnt == 1) && ((k == 3) || (k == 4) || (k == 6) || (k == 16))        \
                && (u8RxData[0] == addess))
        {
            u8RxData[u8RxCnt++] = k;
            return;
        }
        else if((u8RxData[0] == addess) && ((u8RxData[1] == 3)||(u8RxData[1] == 4)||(u8RxData[1] == 6)))
        {
            u8RxData[u8RxCnt++] = k;
            if(u8RxCnt > 7)
            {
                uart_temporary.u8_c[1] = u8RxData[7];
                uart_temporary.u8_c[0] = u8RxData[6];
                rx_crc = uart_temporary.u16_i;

                crc = 0xFFFF;
                for (i = 0; i < 6; i++)
                {
                    calccrc(u8RxData);
                }
                if(crc == rx_crc)
                {
                    uart_temporary.u8_c[1] = u8RxData[2];
                    uart_temporary.u8_c[0] = u8RxData[3];
                    data_address = uart_temporary.u16_i; //数据起始地址
                    uart_temporary.u8_c[1] = u8RxData[4];
                    uart_temporary.u8_c[0] = u8RxData[5];
                    data_leng = uart_temporary.u16_i;//数据长度

                    if(u8RxData[1] == 0x06)
                    {
                                                modbus_4000_reg[data_address] = data_leng;
                    }
                    command = u8RxData[1];
                    b_modbus_rx_ok = TRUE;
                }
                u8RxCnt = 0;
            }
            return;
        }
        else if((u8RxData[0] == addess) && (u8RxData[1] == 16))
        {
            u8RxData[u8RxCnt++] = k;
            if((u8RxCnt==5)&&(u8RxData[4]>0))
            {
                u8RxCnt = 0;
                u8RxData[0] = 0xFF;
                return;
            }
            else if((u8RxCnt==6)&&(u8RxData[5]>127))
            {
                u8RxCnt = 0;
                u8RxData[0] = 0xFF;
                return;
            }
            else if((u8RxCnt==7)&&(u8RxData[6]!=(u8RxData[5]*2)))
            {
                u8RxCnt = 0;
                u8RxData[0] = 0xFF;
                return;
            }
            else
            {
                if(u8RxCnt > 8)
                {
                    n = 8 + u8RxData[6];
                    if(n>MODBUS_REG_LENG)
                    {
                        u8RxCnt = 0;
                        u8RxData[0] = 0xFF;
                        return;
                    }
                    if(u8RxCnt > n)
                    {
                        uart_temporary.u8_c[1] = u8RxData[n];
                        n--;
                        uart_temporary.u8_c[0] = u8RxData[n];
                        rx_crc = uart_temporary.u16_i;
                        crc = 0xFFFF;
                        for (i = 0; i < n; i++)
                        {
                            calccrc(u8RxData);
                        }
                        if((crc == rx_crc)||(Broadcast_address))
                        {
                            uart_temporary.u8_c[1] = u8RxData[2];
                            uart_temporary.u8_c[0] = u8RxData[3];
                            temp0_i16 = uart_temporary.u16_i; //数据起始地址
                            uart_temporary.u8_c[1] = u8RxData[4];
                            uart_temporary.u8_c[0] = u8RxData[5];
                            temp1_i16 = uart_temporary.u16_i;//数据长度
                            if((temp0_i16+temp1_i16)<MODBUS_REG_LENG)
                            {
                                for(i = 0; i < 6; i++)
                                {
                                    u8TxData = u8RxData;
                                }
                                crc = 0xFFFF;
                                for (i = 0; i < 6; i++)
                                {
                                    calccrc(u8TxData);
                                }

                                uart_temporary.u16_i = crc;
                                u8TxData[6] = uart_temporary.u8_c[0];
                                u8TxData[7] = uart_temporary.u8_c[1];
                                send(0,8);
                                u8RxCnt = 0;
                                u8RxData[0] = 0xFF;

                                for(i=0; i<temp1_i16; i++)
                                {
                                    uart_temporary.u8_c[1] = u8RxData[2*i+7];
                                    uart_temporary.u8_c[0] = u8RxData[2*i+8];
                                    modbus_4000_reg[i+temp0_i16] = uart_temporary.u16_i;
                                }
                                b_modbus_command_16 = TRUE;
                                Broadcast_address = FALSE;
                            }
                            u8RxCnt = 0;
                            u8RxData[0] = 0xFF;
                        }
                        else
                        {
                            u8RxCnt = 0;
                            u8RxData[0] = 0xFF;
                        }
                    }
                    return;
                }
            }
        }
        else
        {
            u8RxCnt = 0;
            u8RxData[0] = 0xFF;
            return;
        }
}

void Uart1_Tx(void)
{
        if(u8TxCnt<u8Txmax)
        {
                M0P_UART0->SBUF_f.DATA = u8TxData[u8TxCnt++];
        }
        else
        {
            u8TxCnt = 0;
            u8Txmax = 0;
            Gpio_ClrIO(STK_WR_PORT, STK_WR_PIN);
        }
}

void send(uint8_t UARTx,int tx_leng)
{
    while(!Uart_GetStatus(UARTx,UartTxe));
    u8Txmax=tx_leng;
    Gpio_SetIO(STK_WR_PORT, STK_WR_PIN);
        M0P_UART0->SBUF_f.DATA = u8TxData[u8TxCnt++];
//    Uart_SendData(UARTx, u8TxData[u8TxCnt++]); //启动UART1发送第一个字节
}

void read_ad(void)
{
        Adc_GetSqrResult(&u16AdcRestult[0][adc_n],CH0MUX);  //获取顺序扫描通道0
        Adc_GetSqrResult(&u16AdcRestult[1][adc_n],CH1MUX);  //获取顺序扫描通道1
        Adc_GetSqrResult(&u16AdcRestult[2][adc_n],CH2MUX);
        Adc_GetSqrResult(&u16AdcRestult[3][adc_n],CH3MUX);
        Adc_GetSqrResult(&u16AdcRestult[4][adc_n],CH4MUX);
        adc_n++;
        Adc_SQR_Stop();
        b_adc_busy = FALSE;
}
#if 0
/*******************************************************************************
* TIM0中断服务函数
******************************************************************************/
void Tim0_IRQHandler(void)
{
    //Timer0 模式0 溢出中断
    if(TRUE == Bt_GetIntFlag(TIM0, BtUevIrq))
    {
        Bt_ClearIntFlag(TIM0,BtUevIrq); //中断标志清零
    }
}

//Timer0配置初始化
void App_Timer0Cfg(uint16_t u16Period)
{
    uint16_t                  u16ArrValue;
    uint16_t                  u16CntValue;
    stc_bt_mode0_cfg_t     stcBtBaseCfg;

    DDL_ZERO_STRUCT(stcBtBaseCfg);

    Sysctrl_SetPeripheralGate(SysctrlPeripheralBaseTim, TRUE); //Base Timer外设时钟使能

    stcBtBaseCfg.enWorkMode = BtWorkMode0;                  //定时器模式
    stcBtBaseCfg.enCT       = BtTimer;                      //定时器功能,计数时钟为内部PCLK
    stcBtBaseCfg.enPRS      = BtPCLKDiv256;                 //PCLK/256
    stcBtBaseCfg.enCntMode  = Bt16bitArrMode;               //自动重载16位计数器/定时器
    stcBtBaseCfg.bEnTog     = FALSE;
    stcBtBaseCfg.bEnGate    = FALSE;
    stcBtBaseCfg.enGateP    = BtGatePositive;
    Bt_Mode0_Init(TIM0, &stcBtBaseCfg);                     //TIM0 的模式0功能初始化

    u16ArrValue = 0x10000 - u16Period;
    Bt_M0_ARRSet(TIM0, u16ArrValue);                        //设置重载值(ARR = 0x10000 - 周期)

    u16CntValue = 0x10000 - u16Period;
    Bt_M0_Cnt16Set(TIM0, u16CntValue);                      //设置计数初值

    Bt_ClearIntFlag(TIM0,BtUevIrq);                         //清中断标志
    Bt_Mode0_EnableIrq(TIM0);                               //使能TIM0中断(模式0时只有一个中断)
    EnableNvic(TIM0_IRQn, IrqLevel3, TRUE);                 //TIM0中断使能
}

// 数字积分函数
float numericalIntegration(float* input, int numSamples) {
    float integral = 0.0;
    for (int i = 1; i < numSamples; i++) {
        integral += (input + input[i - 1]) * SAMPLE_PERIOD / 2.0;
    }
    return integral;
}

// IIR滤波函数
float iirFilter(float input, float* outputPrev) {
    float output = A_COEFF * input + B_COEFF * (*outputPrev);
    *outputPrev = output;
    return output;
}
#endif
/******************************************************************************
* EOF (not truncated)
******************************************************************************/


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

36

主题

1704

帖子

1

粉丝