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
}
}
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)){
/******************************************************************************
* 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 修改温补计算
**
******************************************************************************/
赞0
* @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;
}
}
评论
2025-01-10
赞0
* 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)
******************************************************************************/
评论
2025-02-14
您需要登录后才可以回复 登录 | 注册