Fertirrega_v6 Without Blocking Samples

This commit is contained in:
2026-07-29 10:02:21 +01:00
parent e65f787c34
commit f1cf74ceaf
88 changed files with 13881 additions and 11752 deletions
+88 -2
View File
@@ -93,8 +93,8 @@ extern "C" {
#define AD5934_FREQ_1K590HZ 0x003419E3 // 1.59kHz
#define AD5934_FREQ_0HZ 0x00000000 // 0Hz
#define AD5934_STEP_FREQ_0 0x0000 // 0 passos
//#define AD5934_SETTLING_TIME_0S01 0x000C // 0,01s
#define AD5934_SETTLING_TIME_0S01 0x0080
#define AD5934_SETTLING_TIME_64 0x0040 // 64 ciclos
/*****************************************************************************/
/**************************** Command Codes **********************************/
@@ -117,6 +117,12 @@ extern "C" {
#define ADG715_SW7 0x40 //RTD Input
#define ADG715_SW8 0x80 //CE Input
/*****************************************************************************/
/**************************** General Defines ********************************/
/*****************************************************************************/
/*
#define AD5934_CH_REF_100R 0x10
#define AD5934_CH_REF_1K 0x11
@@ -171,6 +177,31 @@ extern "C" {
#define AD5934_EC_ALPHA_PER_C 0.02f
#define AD5934_EC_TEMP_REF_C 25.0f
// Values for sample timming sync
#define AD5934_SYNC_PER_SWEEP 60 // 60 ms between sweeps
#define AD5934_SYNC_MUX_SETTLING 5 // 5 ms to wait before read after change ADG715 channels
//Mux Set to Read...
#define AD5934_ID_RTD 0
#define AD5934_ID_EC 1
#define AD5934_ID_REF 2
/*****************************************************************************/
/**************************** Filtering Defines *****************************/
/*****************************************************************************/
#define AD5934_TIME_PER_SWEEP 60 // 60 ms entre o início de cada sweep
#define AD5934_TIME_MUX_SETTLING 10 // 10 ms de espera após trocar o MUX
#define AD5934_BURST_SIZE 7
#define AD5934_TRIM_COUNT 1
#define AD5934_HISTORY_SIZE 8
#define AD5934_IIR_ALPHA 0.25f
union Bytes2Int
{
uint8_t bytes[2];
@@ -213,6 +244,30 @@ typedef enum {
AD5934_CH_MAX // Guarda automaticamente o número total de canais (15)
} AD5934_Channel_t;
typedef enum {
AD5934_IDLE,
AD5934_START_CONVERSION,
AD5934_WAIT_CONVERSION,
AD5934_READ_DATA,
AD5934_WAIT_NEXT_SWEEP,
AD5934_SWITCH_MUX,
AD5934_WAIT_MUX
} AD5934_State_t;
typedef struct {
float burst[AD5934_BURST_SIZE];
uint8_t burst_index;
float history[AD5934_HISTORY_SIZE];
uint8_t history_index;
uint8_t history_count;
float iir_state;
uint8_t iir_initialized;
float filtered_value;
uint8_t value_valid;
} AD5934_filter_t;
static const uint8_t ADG715_Channel_Map[AD5934_CH_MAX] = {
[AD5934_CH_REF100R_LOW_GAIN] = (ADG715_SW1 | ADG715_SW4),
[AD5934_CH_REF100R_MID_GAIN] = (ADG715_SW2 | ADG715_SW4),
@@ -248,6 +303,15 @@ extern float ec_temp_dut[AD5934_EC_AVERAGES];
extern I2C_HandleTypeDef hi2c2;
extern volatile AD5934_State_t ad5934_state;
extern volatile uint32_t g_ms_counter; // Increment each 1ms Timer
extern uint8_t current_mux_channel;
extern uint8_t sweep_count; // Count how many sweeps done at the same channel now (0 a 7)
extern uint8_t is_new_channel;
extern AD5934_filter_t g_rtd_filter, g_ec_filter, g_ref_filter;
/*****************************************************************************/
/************************ Functions Declarations *****************************/
/*****************************************************************************/
@@ -263,12 +327,18 @@ uint32_t AD5934_Sweep(void);
void AD5934_RestartSweep(void);
void AD5934_Repeat_Sweep(void);
void AD5934_StopSweep(void);
float AD5934_Get_Ref_Resistance(void);
float AD5934_GetTemperature(float mag_ref);
float AD5934_GetImpedance(float temperature_dut);
float AD5934_GetMagnitude(void);
void AD5934_Wait_For_Data_Valid(void);
float AD5934_Round_Float_Precision(float value, uint8_t number_of_decimals);
@@ -279,6 +349,22 @@ float AD5934_EC_Compensate_To_25C(float ec_raw_uScm, float temp_C);
float AD5934_EC_Calibrate_Temperature(float temp_C);
void AD5934_Process_System(void);
void AD5934_Sort_Array(float *v, uint8_t n);
float AD5934_Trimmed_Mean(float *buffer, uint8_t n, uint8_t trim);
float AD5934_History_Average(const float *hist, uint8_t n);
void AD5934_Process_Sample(AD5934_filter_t *ch, float raw);
void AD5934_RTD_NewSample(float raw);
void AD5934_EC_NewSample(float raw);
void AD5934_Reference_NewSample(float raw);
void ADG715_SetRegisterValue(char value);
void ADG715_SetChannels(uint8_t ch1, uint8_t ch2);
+75 -46
View File
@@ -25,10 +25,10 @@ extern "C" {
/*=========================================================================
I2C ADDRESS/BITS - Connect the following pin to ADDR
-----------------------------------------------------------------------*/
#define ADS_ADDR_GND (0x48) ///< 1001 000 (ADDR -> GND)
#define ADS_ADDR_VDD (0x49) ///< 1001 001 (ADDR -> VDD)
#define ADS_ADDR_SDA (0x4A) ///< 1001 010 (ADDR -> SDA)
#define ADS_ADDR_SCL (0x4B) ///< 1001 011 (ADDR -> SCL)
#define ADS1015_ADDR_GND (0x48 << 1) ///< 1001 000 (ADDR -> GND)
#define ADS1015_ADDR_VDD (0x49 << 1) ///< 1001 001 (ADDR -> VDD)
#define ADS1015_ADDR_SDA (0x4A << 1) ///< 1001 010 (ADDR -> SDA)
#define ADS1015_ADDR_SCL (0x4B << 1) ///< 1001 011 (ADDR -> SCL)
/*=========================================================================*/
/*=========================================================================
@@ -52,22 +52,15 @@ extern "C" {
CONFIG REGISTER
-----------------------------------------------------------------------*/
#define ADS1015_REG_CONFIG_OS_MASK (0x8000) ///< OS Mask
#define ADS1015_REG_CONFIG_OS_SINGLE \
(0x8000) ///< Write: Set to start a single-conversion
#define ADS1015_REG_CONFIG_OS_BUSY \
(0x0000) ///< Read: Bit = 0 when conversion is in progress
#define ADS1015_REG_CONFIG_OS_NOTBUSY \
(0x8000) ///< Read: Bit = 1 when device is not performing a conversion
#define ADS1015_REG_CONFIG_OS_SINGLE (0x8000) ///< Write: Set to start a single-conversion
#define ADS1015_REG_CONFIG_OS_BUSY (0x0000) ///< Read: Bit = 0 when conversion is in progress
#define ADS1015_REG_CONFIG_OS_NOTBUSY (0x8000) ///< Read: Bit = 1 when device is not performing a conversion
#define ADS1015_REG_CONFIG_MUX_MASK (0x7000) ///< Mux Mask
#define ADS1015_REG_CONFIG_MUX_DIFF_0_1 \
(0x0000) ///< Differential P = AIN0, N = AIN1 (default)
#define ADS1015_REG_CONFIG_MUX_DIFF_0_3 \
(0x1000) ///< Differential P = AIN0, N = AIN3
#define ADS1015_REG_CONFIG_MUX_DIFF_1_3 \
(0x2000) ///< Differential P = AIN1, N = AIN3
#define ADS1015_REG_CONFIG_MUX_DIFF_2_3 \
(0x3000) ///< Differential P = AIN2, N = AIN3
#define ADS1015_REG_CONFIG_MUX_DIFF_0_1 (0x0000) ///< Differential P = AIN0, N = AIN1 (default)
#define ADS1015_REG_CONFIG_MUX_DIFF_0_3 (0x1000) ///< Differential P = AIN0, N = AIN3
#define ADS1015_REG_CONFIG_MUX_DIFF_1_3 (0x2000) ///< Differential P = AIN1, N = AIN3
#define ADS1015_REG_CONFIG_MUX_DIFF_2_3 (0x3000) ///< Differential P = AIN2, N = AIN3
#define ADS1015_REG_CONFIG_MUX_SINGLE_0 (0x4000) ///< Single-ended AIN0
#define ADS1015_REG_CONFIG_MUX_SINGLE_1 (0x5000) ///< Single-ended AIN1
#define ADS1015_REG_CONFIG_MUX_SINGLE_2 (0x6000) ///< Single-ended AIN2
@@ -76,53 +69,41 @@ extern "C" {
#define ADS1015_REG_CONFIG_PGA_MASK (0x0E00) ///< PGA Mask
#define ADS1015_REG_CONFIG_PGA_6_144V (0x0000) ///< +/-6.144V range = Gain 2/3
#define ADS1015_REG_CONFIG_PGA_4_096V (0x0200) ///< +/-4.096V range = Gain 1
#define ADS1015_REG_CONFIG_PGA_2_048V \
(0x0400) ///< +/-2.048V range = Gain 2 (default)
#define ADS1015_REG_CONFIG_PGA_2_048V (0x0400) ///< +/-2.048V range = Gain 2 (default)
#define ADS1015_REG_CONFIG_PGA_1_024V (0x0600) ///< +/-1.024V range = Gain 4
#define ADS1015_REG_CONFIG_PGA_0_512V (0x0800) ///< +/-0.512V range = Gain 8
#define ADS1015_REG_CONFIG_PGA_0_256V (0x0A00) ///< +/-0.256V range = Gain 16
#define ADS1015_REG_CONFIG_MODE_MASK (0x0100) ///< Mode Mask
#define ADS1015_REG_CONFIG_MODE_CONTIN (0x0000) ///< Continuous conversion mode
#define ADS1015_REG_CONFIG_MODE_SINGLE \
(0x0100) ///< Power-down single-shot mode (default)
#define ADS1015_REG_CONFIG_MODE_SINGLE (0x0100) ///< Power-down single-shot mode (default)
#define ADS1015_REG_CONFIG_DR_MASK (0x00E0) ///< Data Rate Mask
#define ADS1015_REG_CONFIG_DR_128SPS (0x0000) ///< 128 samples per second
#define ADS1015_REG_CONFIG_DR_250SPS (0x0020) ///< 250 samples per second
#define ADS1015_REG_CONFIG_DR_490SPS (0x0040) ///< 490 samples per second
#define ADS1015_REG_CONFIG_DR_920SPS (0x0060) ///< 920 samples per second
#define ADS1015_REG_CONFIG_DR_1600SPS \
(0x0080) ///< 1600 samples per second (default)
#define ADS1015_REG_CONFIG_DR_1600SPS (0x0080) ///< 1600 samples per second (default)
#define ADS1015_REG_CONFIG_DR_2400SPS (0x00A0) ///< 2400 samples per second
#define ADS1015_REG_CONFIG_DR_3300SPS (0x00C0) ///< 3300 samples per second
#define ADS1015_REG_CONFIG_CMODE_MASK (0x0010) ///< CMode Mask
#define ADS1015_REG_CONFIG_CMODE_TRAD \
(0x0000) ///< Traditional comparator with hysteresis (default)
#define ADS1015_REG_CONFIG_CMODE_TRAD (0x0000) ///< Traditional comparator with hysteresis (default)
#define ADS1015_REG_CONFIG_CMODE_WINDOW (0x0010) ///< Window comparator
#define ADS1015_REG_CONFIG_CPOL_MASK (0x0008) ///< CPol Mask
#define ADS1015_REG_CONFIG_CPOL_ACTVLOW \
(0x0000) ///< ALERT/RDY pin is low when active (default)
#define ADS1015_REG_CONFIG_CPOL_ACTVHI \
(0x0008) ///< ALERT/RDY pin is high when active
#define ADS1015_REG_CONFIG_CPOL_ACTVLOW (0x0000) ///< ALERT/RDY pin is low when active (default)
#define ADS1015_REG_CONFIG_CPOL_ACTVHI (0x0008) ///< ALERT/RDY pin is high when active
#define ADS1015_REG_CONFIG_CLAT_MASK \
(0x0004) ///< Determines if ALERT/RDY pin latches once asserted
#define ADS1015_REG_CONFIG_CLAT_NONLAT \
(0x0000) ///< Non-latching comparator (default)
#define ADS1015_REG_CONFIG_CLAT_MASK (0x0004) ///< Determines if ALERT/RDY pin latches once asserted
#define ADS1015_REG_CONFIG_CLAT_NONLAT (0x0000) ///< Non-latching comparator (default)
#define ADS1015_REG_CONFIG_CLAT_LATCH (0x0004) ///< Latching comparator
#define ADS1015_REG_CONFIG_CQUE_MASK (0x0003) ///< CQue Mask
#define ADS1015_REG_CONFIG_CQUE_1CONV \
(0x0000) ///< Assert ALERT/RDY after one conversions
#define ADS1015_REG_CONFIG_CQUE_2CONV \
(0x0001) ///< Assert ALERT/RDY after two conversions
#define ADS1015_REG_CONFIG_CQUE_4CONV \
(0x0002) ///< Assert ALERT/RDY after four conversions
#define ADS1015_REG_CONFIG_CQUE_NONE \
(0x0003) ///< Disable the comparator and put ALERT/RDY in high state (default)
#define ADS1015_REG_CONFIG_CQUE_1CONV (0x0000) ///< Assert ALERT/RDY after one conversions
#define ADS1015_REG_CONFIG_CQUE_2CONV (0x0001) ///< Assert ALERT/RDY after two conversions
#define ADS1015_REG_CONFIG_CQUE_4CONV (0x0002) ///< Assert ALERT/RDY after four conversions
#define ADS1015_REG_CONFIG_CQUE_NONE (0x0003) ///< Disable the comparator and put ALERT/RDY in high state (default)
#define ADS1015_KELVIN_OFFSET 273.15f // Constante de conversão Kelvin
#define ADS1015_ADC_MAX 4095.0f
@@ -135,8 +116,24 @@ extern "C" {
#define ADS1015_PH_7_BUFFER_ROW 2
#define ADS1015_INTERPOLATION_ROWS 3
#define ADS1015_PH_TEMP_INTER_POINTS 12
#define ADS1015_TIME_PER_SAMPLE 9 // 9ms
/*=========================================================================*/
/* Config Register para single-shot:
* OS=1 (start), MUX[2:0]=000b (AIN0 single-ended, ajustar se necessário),
* PGA[2:0]=010b (±2.048V default, ajustar ganho conforme sensor),
* MODE=1b (single-shot/power-down), DR[2:0]=100b (1600SPS, ajustar se necessário),
* COMP_QUE[1:0]=11b (comparador desabilitado, ALERT/RDY em alta impedância)
*/
#define ADS1015_CONFIG_START_SINGLE (ADS1015_REG_CONFIG_OS_SINGLE | ADS1015_REG_CONFIG_MUX_DIFF_0_1 | ADS1015_REG_CONFIG_PGA_0_256V | ADS1015_REG_CONFIG_MODE_SINGLE | ADS1015_REG_CONFIG_DR_128SPS | ADS1015_REG_CONFIG_CMODE_TRAD | ADS1015_REG_CONFIG_CPOL_ACTVLOW | ADS1015_REG_CONFIG_CLAT_NONLAT | ADS1015_REG_CONFIG_CQUE_NONE) // 0x8583 // valor de reset já tem OS=1, então só precisa garantir MODE=1b
#define ADS1015_BURST_SIZE 5
#define ADS1015_TRIM_COUNT 1
#define ADS1015_HISTORY_SIZE 8
#define ADS1015_IIR_ALPHA 0.3f
/** Gain settings */
typedef enum {
@@ -148,12 +145,10 @@ typedef enum {
GAIN_SIXTEEN = ADS1015_REG_CONFIG_PGA_0_256V
} adsGain_t;
extern I2C_HandleTypeDef hi2c1;
extern float ph_dut_samples[ADS1015_PH_AVERAGES];
typedef struct {
uint16_t m_i2cAddress; ///< the I2C address
uint32_t m_conversionDelay; ///< conversion delay
@@ -162,7 +157,34 @@ typedef struct {
I2C_HandleTypeDef* hi2c; // Handle for I2C
}ADS1015_I2C;
extern ADS1015_I2C i2c;
extern ADS1015_I2C i2c_ads1015;
typedef enum
{
ADS1015_IDLE,
ADS1015_START_CONVERSION,
ADS1015_WAIT_CONVERSION,
ADS1015_READ_DATA,
ADS1015_WAIT_NEXT_SAMPLE
} ADS1015_State_t;
extern volatile ADS1015_State_t ads1015_state;
typedef struct {
float burst[ADS1015_BURST_SIZE];
uint8_t burst_index;
float history[ADS1015_HISTORY_SIZE];
uint8_t history_index;
uint8_t history_count;
float iir_state;
uint8_t iir_initialized;
float filtered_value;
uint8_t value_valid;
} ADS1015_filter_t;
extern ADS1015_filter_t g_ph_filter;
extern volatile uint32_t g_ms_counter; // Increment each 1ms Timer
void ADS1015(ADS1015_I2C* i2c, I2C_HandleTypeDef* hi2c, uint8_t i2cAddress);
uint16_t ADSreadADC_SingleEnded(ADS1015_I2C* i2c, uint8_t channel);
@@ -172,6 +194,13 @@ void ADSstartComparator_SingleEnded(ADS1015_I2C* i2c, uint8_t channel, int16_t
int16_t ADSgetLastConversionResults();
void ADSsetGain(ADS1015_I2C* i2c, adsGain_t gain);
adsGain_t ADSgetGain(ADS1015_I2C* i2c);
void ADS1015_Process_System(void);
void ADS1015_Sort_Array(float *v, uint8_t n);
float ADS1015_Trimmed_Mean(float *buffer, uint8_t n, uint8_t trim);
void ADS1015_Process_Sample(ADS1015_filter_t *ch, float raw);
void ADS1015_pH_NewSample(float raw);
float ADSCalculate_ph_mV(void);
float ADSCalculate_ph_Compensated(float temp_dut);
float ADSCalculate_ph_Uncompensated(void);
+1 -1
View File
@@ -64,7 +64,7 @@
/*#define HAL_SMARTCARD_MODULE_ENABLED */
/*#define HAL_SPI_MODULE_ENABLED */
/*#define HAL_SRAM_MODULE_ENABLED */
/*#define HAL_TIM_MODULE_ENABLED */
#define HAL_TIM_MODULE_ENABLED
#define HAL_UART_MODULE_ENABLED
/*#define HAL_USART_MODULE_ENABLED */
/*#define HAL_WWDG_MODULE_ENABLED */
+1
View File
@@ -55,6 +55,7 @@ void SVC_Handler(void);
void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
void TIM3_IRQHandler(void);
void USART1_IRQHandler(void);
/* USER CODE BEGIN EFP */
+328 -5
View File
@@ -11,6 +11,15 @@
#include "ad5934_driver.h"
volatile AD5934_State_t ad5934_state = AD5934_IDLE;
volatile uint32_t g_ms_counter = 0; /* Incrementado a cada 1ms no Timer */
uint8_t current_mux_channel = AD5934_ID_RTD;
uint8_t current_hw_mux_connection = ADG715_Channel_Map[AD5934_CH_RTD_LOW_GAIN]; // PT100 Connection
uint8_t sweep_count = 0; /* Conta quantos sweeps foram feitos no canal atual (0 a 7) */
int16_t temperature_dut_samples[2][AD5934_TEMP_AVERAGES]={{0},{0}};
int16_t temperature_ref_samples[2][AD5934_TEMP_AVERAGES]={{0},{0}};
float temperature_display[AD5934_TEMP_AVERAGES] = {0};
@@ -19,6 +28,11 @@ float temperature_display[AD5934_TEMP_AVERAGES] = {0};
int16_t ec_dut_samples[2][AD5934_EC_AVERAGES]={{0},{0}};
float ec_display[AD5934_EC_AVERAGES] = {0};
AD5934_filter_t g_rtd_filter = {0};
AD5934_filter_t g_ec_filter = {0};
AD5934_filter_t g_ref_filter = {0};
uint8_t is_new_channel = 1;
/******************************************************************************
* @brief Set an AD5934 internal register value.
*
@@ -151,7 +165,7 @@ void AD5934_Init(void)
AD5934_SetRegisterValue(AD5934_NR_INCR_REG_LB, AD5934_STEP_FREQ_0, 2);
// Set 128 Settling Time
AD5934_SetRegisterValue(AD5934_NR_SETTLE_REG_LB, AD5934_SETTLING_TIME_0S01, 2);
AD5934_SetRegisterValue(AD5934_NR_SETTLE_REG_LB, AD5934_SETTLING_TIME_64, 2);
}
@@ -177,18 +191,50 @@ void AD5934_RestartSweep(void)
AD5934_SetRegisterValue(AD5934_CONTROL_REG_HB, (AD5934_CONTROL_FUNCTION(AD5934_START_FREQ_SWEEP) | AD5934_CONTROL_RANGE(AD5934_400mVpp_RANGE) | AD5934_PGA_GAIN(AD5934_PGA_GAIN_X1)), 1);
// Wait for data to be valid
AD5934_Wait_For_Data_Valid();
//AD5934_Wait_For_Data_Valid();
// Power Down
AD5934_SetRegisterValue(AD5934_CONTROL_REG_HB, (AD5934_CONTROL_FUNCTION(AD5934_POWER_DOWN) | AD5934_CONTROL_RANGE(AD5934_400mVpp_RANGE) | AD5934_PGA_GAIN(AD5934_PGA_GAIN_X1)), 1);
//AD5934_SetRegisterValue(AD5934_CONTROL_REG_HB, (AD5934_CONTROL_FUNCTION(AD5934_POWER_DOWN) | AD5934_CONTROL_RANGE(AD5934_400mVpp_RANGE) | AD5934_PGA_GAIN(AD5934_PGA_GAIN_X1)), 1);
// Place AD5934 in standby (instead of power down)
//AD5934_SetRegisterValue(AD5934_CONTROL_REG_HB, (AD5934_CONTROL_FUNCTION(AD5934_STANDBY) | AD5934_CONTROL_RANGE(AD5934_400mVpp_RANGE) | AD5934_PGA_GAIN(AD5934_PGA_GAIN_X1)), 1);
}
/******************************************************************************
* @brief Repeat Sweep at the AD5934 with the same sweep parameters.
*
* @param None.
*
* @return none.
******************************************************************************/
void AD5934_Repeat_Sweep(void)
{
// Repeat AD5934 Sweep
AD5934_SetRegisterValue(AD5934_CONTROL_REG_HB, (AD5934_CONTROL_FUNCTION(AD5934_REPEAT_FREQ) | AD5934_CONTROL_RANGE(AD5934_400mVpp_RANGE) | AD5934_PGA_GAIN(AD5934_PGA_GAIN_X1)), 1);
}
/******************************************************************************
* @brief Stop the AD5934 to sweep.
*
* @param None.
*
* @return None.
******************************************************************************/
void AD5934_StopSweep(void)
{
// Power Down
//AD5934_SetRegisterValue(AD5934_CONTROL_REG_HB, (AD5934_CONTROL_FUNCTION(AD5934_POWER_DOWN) | AD5934_CONTROL_RANGE(AD5934_400mVpp_RANGE) | AD5934_PGA_GAIN(AD5934_PGA_GAIN_X1)), 1);
// Place AD5934 in standby (instead of power down to save startup time)
AD5934_SetRegisterValue(AD5934_CONTROL_REG_HB, (AD5934_CONTROL_FUNCTION(AD5934_STANDBY) | AD5934_CONTROL_RANGE(AD5934_400mVpp_RANGE) | AD5934_PGA_GAIN(AD5934_PGA_GAIN_X1)), 1);
}
/******************************************************************************
* @brief Start the AD5934 frequency sweep parameters.
*
* @param: channel = AD5934_CH_REF_100R, AD5934_CH_REF_1K, AD5934_CH_REF_10K, AD5934_CH_PT100, AD5934_CH_PT1000 or AD5934_CH_EC
* @param: none
*
* @return Real(int16) and Imaginary(int16) numbers into a int32.
******************************************************************************/
@@ -386,7 +432,6 @@ float AD5934_GetImpedance(float temperature_dut)
ec_dut_samples[1][i] = ec_dut_samples[1][i-1];
}
// Deconstruct 32-bit sample into Real and Imaginary components
ec_dut_samples[0][0] = (float)(int16_t)(sample_dut & 0xFFFF);
ec_dut_samples[1][0] = (float)(int16_t)((sample_dut >> 16) & 0xFFFF);
@@ -424,6 +469,30 @@ float AD5934_GetImpedance(float temperature_dut)
}
/******************************************************************************
* @brief Get Real and Imaginary values and calculate Magnitude.
*
* @param: none
*
* @return Magnitude (float).
******************************************************************************/
float AD5934_GetMagnitude(void)
{
// Get Real Data register
int16_t real_value = ((AD5934_GetRegisterValue(AD5934_REAL_REG_LB,2)));
// Get Imaginary Data register
int16_t imag_value = ((AD5934_GetRegisterValue(AD5934_IMG_REG_LB,2)));
// Calculate Magnitude using float function sqrtf
float magnitude = sqrtf(((float)real_value * (float)real_value) + ((float)imag_value * (float)imag_value));
// Return magnitude value
return (magnitude);
}
/**
* @brief Monitora o status com TIMEOUT para evitar travamento do sistema.
@@ -585,6 +654,260 @@ float AD5934_Calibrate(float dry_probe_real, float dry_probe_imag, float standar
return calibration_factor;
}
void AD5934_Process_System(void)
{
static uint32_t state_timer = 0;
uint8_t status = 0;
switch (ad5934_state)
{
case AD5934_IDLE:
ADG715_Update(current_mux_channel); // Starts changing the mux channel
is_new_channel = 1; // Forces first channel
state_timer = g_ms_counter;
ad5934_state = AD5934_WAIT_MUX;
break;
case AD5934_WAIT_MUX:
if ((g_ms_counter - state_timer) >= AD5934_SYNC_MUX_SETTLING) // Wait until AD715 Mux switch stability
{
sweep_count = 0;
ad5934_state = AD5934_START_CONVERSION;
}
break;
case AD5934_START_CONVERSION:
state_timer = g_ms_counter; // Starts to count the Burst period for the sweeps
/* DECISÃO DE COMANDO: Novo canal vs Leituras sucessivas */
if (is_new_channel) // Decision: Channel Switched or Next Sample in the Burst ?
{
AD5934_RestartSweep(); // Clean some AD5934 internal registers to Re-Start Sweep
is_new_channel = 0; // Resets the flag to read the next Sample Burst
}
else
{
AD5934_Repeat_Sweep(); // Get Sample and just repeat reading
}
ad5934_state = AD5934_WAIT_CONVERSION; // Next State
break;
case AD5934_WAIT_CONVERSION:
status = (uint8_t)AD5934_GetRegisterValue(AD5934_STATUS_REG, 1); // Check if the current converion is ready in the AD5934
if ((status & AD5934_STATUS_DATA_VALID) != 0)
{
ad5934_state = AD5934_READ_DATA;
}
break;
case AD5934_READ_DATA:
{
float magnitude = AD5934_GetMagnitude();
switch (current_mux_channel)
{
case AD5934_ID_RTD:
AD5934_RTD_NewSample(magnitude);
break;
case AD5934_ID_EC:
AD5934_EC_NewSample(magnitude);
break;
case AD5934_ID_REF:
AD5934_Reference_NewSample(magnitude);
break;
}
sweep_count++;
if (sweep_count >= AD5934_BURST_SIZE) // Check if number of samples for the burst is complete
{
ad5934_state = AD5934_SWITCH_MUX; // Next Re-Start Sweep
}
else
{
ad5934_state = AD5934_WAIT_NEXT_SWEEP; // Next Repeat Sweep
}
}
break;
case AD5934_WAIT_NEXT_SWEEP:
if ((g_ms_counter - state_timer) >= AD5934_TIME_PER_SWEEP)
{
ad5934_state = AD5934_START_CONVERSION;
}
break;
case AD5934_SWITCH_MUX:
AD5934_StopSweep(); // Put AD5934 in Standby
current_mux_channel = (uint8_t)((current_mux_channel + 1) % 3); // Pointer to the next channel (Circular Buffer 0 to 2)
switch (current_mux_channel)
{
case AD5934_ID_RTD:
if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7) == GPIO_PIN_SET) // OFF = PT1000, ON = PT100, PA7 has internal pull-up and switch connects to GND
current_hw_mux_connection = AD5934_CH_RTD_LOW_GAIN; //PT100
else
current_hw_mux_connection = AD5934_CH_RTD_MID_GAIN; //PT1000
break;
case AD5934_ID_EC:
if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6) == GPIO_PIN_SET) // Hardware Setup: Gain Selection (PA6)
current_hw_mux_connection = AD5934_CH_EC_HIGH_GAIN;
else
current_hw_mux_connection = AD5934_CH_EC_MID_GAIN;
break;
case AD5934_ID_REF:
if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7) == GPIO_PIN_SET) // OFF = PT1000, ON = PT100, PA7 has internal pull-up and switch connects to GND
current_hw_mux_connection = AD5934_CH_REF100R_LOW_GAIN; // 100 Ohms Reference Resistor
else
current_hw_mux_connection = AD5934_CH_REF1K_MID_GAIN; // 1K Reference Resistor
break;
}
ADG715_Update(current_hw_mux_connection); // Change the analog mux
is_new_channel = 1; // Channel Switched
state_timer = g_ms_counter; // Reload timer to wait for stability
ad5934_state = AD5934_WAIT_MUX; // Next State
break;
}
}
/**
* Simple insertion sort - BURST_SIZE is small, so the cost is negligible
* and it avoids depending on qsort/heap allocation.
**/
void AD5934_Sort_Array(float *v, uint8_t n)
{
for (uint8_t i = 1; i < n; i++)
{
float key = v[i];
int8_t j = (int8_t)i - 1;
while (j >= 0 && v[j] > key)
{
v[j + 1] = v[j];
j--;
}
v[j + 1] = key;
}
}
/**
* Trimmed mean: sorts the buffer IN PLACE (the caller's burst buffer is
* about to be reset right after this call anyway, so preserving its
* original order is not needed), discards TRIM_COUNT values from each
* end, and averages the remainder. Sorting in place avoids a temporary
* array and removes the need for memcpy()/string.h entirely.
**/
float AD5934_Trimmed_Mean(float *buffer, uint8_t n, uint8_t trim)
{
AD5934_Sort_Array(buffer, n);
uint8_t start = trim;
uint8_t end = n - trim; /* exclusive */
if (end <= start) /* guard against a misconfigured trim value */
{
start = 0;
end = n;
}
float sum = 0.0f;
uint8_t count = 0;
for (uint8_t i = start; i < end; i++)
{
sum += buffer[i];
count++;
}
return sum / (float)count;
}
/*
* Simple average of the history buffer (stage-2 sliding window)
*/
float AD5934_History_Average(const float *hist, uint8_t n)
{
float sum = 0.0f;
for (uint8_t i = 0; i < n; i++)
sum += hist[i];
return sum / (float)n;
}
/*
* Common processing core: applied identically to all 3 channels.
* Receives the current raw reading and the channel's state (global
* arrays/struct).
**/
void AD5934_Process_Sample(AD5934_filter_t *ch, float raw)
{
/* --- Stage 1: accumulate into the current burst --- */
ch->burst[ch->burst_index] = raw;
ch->burst_index++;
if (ch->burst_index < AD5934_BURST_SIZE)
return; /* still collecting the burst, nothing else to do */
/* Burst complete: compute the trimmed mean */
float burst_result = AD5934_Trimmed_Mean(ch->burst, AD5934_BURST_SIZE, AD5934_TRIM_COUNT);
ch->burst_index = 0; /* reset for the next burst */
/* --- Stage 2a: rolling history / sliding window --- */
ch->history[ch->history_index] = burst_result;
ch->history_index = (uint8_t)((ch->history_index + 1) % AD5934_HISTORY_SIZE);
if (ch->history_count < AD5934_HISTORY_SIZE)
ch->history_count++;
float window_average = AD5934_History_Average(ch->history, ch->history_count);
/* --- Stage 2b: first-order IIR low-pass filter on the burst result --- */
if (!ch->iir_initialized)
{
ch->iir_state = burst_result;
ch->iir_initialized = 1;
}
else
{
ch->iir_state = AD5934_IIR_ALPHA * burst_result + (1.0f - AD5934_IIR_ALPHA) * ch->iir_state;
}
/* Final output: combines the IIR state (fast response to real drift)
* with the window average (more stable, slower response). Adjust
* the weighting per channel if needed. */
ch->filtered_value = 0.5f * ch->iir_state + 0.5f * window_average;
ch->value_valid = 1;
}
/* ---------------------------------------------------------------------- */
/* PUBLIC FUNCTIONS - ONE PER CHANNEL */
/* ---------------------------------------------------------------------- */
/* Call this every time a sweep completes with the mux on the RTD
* (PT100/PT1000) channel */
void AD5934_RTD_NewSample(float raw)
{
AD5934_Process_Sample(&g_rtd_filter, raw);
}
/* Call this every time a sweep completes with the mux on the EC
* (conductivity probe) channel */
void AD5934_EC_NewSample(float raw)
{
AD5934_Process_Sample(&g_ec_filter, raw);
}
/* Call this every time a sweep completes with the mux on the on-board
* precision reference resistor channel */
void AD5934_Reference_NewSample(float raw)
{
AD5934_Process_Sample(&g_ref_filter, raw);
}
/*****************************************************************************
* ADG715
*****************************************************************************
+213 -6
View File
@@ -9,9 +9,14 @@
#include "ads1015_driver.h"
ADS1015_I2C i2c;
ADS1015_I2C i2c_ads1015;
float ph_dut_samples[ADS1015_PH_AVERAGES]={0};
ADS1015_filter_t g_ph_filter = {0};
volatile ADS1015_State_t ads1015_state = ADS1015_IDLE;
// Write the register
static void writeRegister(ADS1015_I2C *i2c, uint8_t reg, uint16_t value) {
uint8_t pData[3] = { reg, (uint8_t) (value >> 8), (uint8_t) (value & 0xFF) };
@@ -36,13 +41,14 @@ static void ADSbegin(ADS1015_I2C *i2c) {
// Declare an ADS1015 structure
void ADS1015(ADS1015_I2C *i2c, I2C_HandleTypeDef *hi2c, uint8_t i2cAddress) {
i2c->hi2c = hi2c;
i2c->m_i2cAddress = i2cAddress << 1; // It's Important to shift the address << 1
i2c->m_i2cAddress = i2cAddress; // << 1; // It's Important to shift the address << 1
i2c->m_conversionDelay = ADS1015_CONVERSIONDELAY;
i2c->m_bitShift = 4;
i2c->m_gain = GAIN_TWOTHIRDS; /* +/- 6.144V range (limited to VDD +0.3V max!) */
i2c->m_gain = GAIN_SIXTEEN; /* +/- 6.144V range (limited to VDD +0.3V max!) */
//ADSbegin(i2c); //Ready is not used
}
/*
* // The ADC input range (or gain) can be changed via the following
// functions, but be careful never to exceed VDD +0.3V max, or to
@@ -126,7 +132,7 @@ int16_t ADSreadADC_Differential_0_1(ADS1015_I2C *i2c) {
ADS1015_REG_CONFIG_CLAT_NONLAT | // Non-latching (default val)
ADS1015_REG_CONFIG_CPOL_ACTVLOW | // Alert/Rdy active low (default val)
ADS1015_REG_CONFIG_CMODE_TRAD | // Traditional comparator (default val)
ADS1015_REG_CONFIG_DR_128SPS | // 128 samples per second (default)
ADS1015_REG_CONFIG_DR_250SPS | // 128 samples per second (default)
ADS1015_REG_CONFIG_MODE_SINGLE; // Single-shot mode (default)
// Set PGA/voltage range
@@ -271,6 +277,207 @@ int16_t ADSgetLastConversionResults(ADS1015_I2C *i2c) {
}
}
void ADS1015_Process_System(void)
{
static uint32_t state_timer = 0;
static uint32_t sample_count = 0;
uint16_t config_reg = 0;
switch (ads1015_state)
{
case ADS1015_IDLE:
sample_count = 0;
ads1015_state = ADS1015_START_CONVERSION;
break;
case ADS1015_START_CONVERSION:
state_timer = g_ms_counter;
/* Escreve no Config Register (P[1:0]=01b) com OS=1 para
* iniciar a conversão single-shot. O bit OS só tem efeito
* quando o dispositivo está em power-down (seção 7.4.2.1) */
// Write config register to the ADC
writeRegister(&i2c_ads1015, ADS1015_REG_POINTER_CONFIG, ADS1015_CONFIG_START_SINGLE);
ads1015_state = ADS1015_WAIT_CONVERSION;
break;
case ADS1015_WAIT_CONVERSION:
/* Poll do bit OS no Config Register (P[1:0]=01b):
* Ao LER o bit OS:
* 0b = dispositivo ainda convertendo
* 1b = conversão concluída, dado pronto no Conversion Register
* (Tabela 8-4, descrição do bit OS)
*/
config_reg = readRegister(&i2c_ads1015, ADS1015_REG_POINTER_CONFIG);
if (((config_reg & ADS1015_REG_CONFIG_OS_SINGLE) != 0) && (g_ms_counter - state_timer)>ADS1015_TIME_PER_SAMPLE)
{
ads1015_state = ADS1015_READ_DATA;
}
// (opcional) tratar timeout comparando g_ms_counter - state_timer
// Datasheet: conversão single-cycle, tempo = 1/DR (ex: 1600SPS ≈ 625µs)
break;
case ADS1015_READ_DATA:
{
/* Muda o Address Pointer para o Conversion Register (P[1:0]=00b)
* e lê os 16 bits. Dado é 12 bits em complemento de 2,
* left-justified em D[15:4]; D[3:0] sempre lê 0h (Tabela 8-3) */
int16_t raw = (int16_t)readRegister(&i2c_ads1015, ADS1015_REG_POINTER_CONVERT);
raw >>= 4; // remove os 4 bits reservados (D[3:0]), resultado = 12 bits signed
float value = (float)(4096 - raw); // ((float)raw * ADS1015_ADC_VREF) / ADS1015_ADC_MAX; // usa FSR configurado no PGA
ADS1015_pH_NewSample(value);
sample_count++;
if (sample_count >= ADS1015_BURST_SIZE)
{
ads1015_state = ADS1015_IDLE;
}
else
{
state_timer = g_ms_counter;
ads1015_state = ADS1015_WAIT_NEXT_SAMPLE;
}
}
break;
case ADS1015_WAIT_NEXT_SAMPLE:
if ((g_ms_counter - state_timer) >= ADS1015_TIME_PER_SAMPLE)
{
ads1015_state = ADS1015_START_CONVERSION;
}
break;
}
}
/**
* Simple insertion sort - BURST_SIZE is small, so the cost is negligible
* and it avoids depending on qsort/heap allocation.
**/
void ADS1015_Sort_Array(float *v, uint8_t n)
{
for (uint8_t i = 1; i < n; i++)
{
float key = v[i];
int8_t j = (int8_t)i - 1;
while (j >= 0 && v[j] > key)
{
v[j + 1] = v[j];
j--;
}
v[j + 1] = key;
}
}
/**
* Trimmed mean: sorts the buffer IN PLACE (the caller's burst buffer is
* about to be reset right after this call anyway, so preserving its
* original order is not needed), discards TRIM_COUNT values from each
* end, and averages the remainder. Sorting in place avoids a temporary
* array and removes the need for memcpy()/string.h entirely.
**/
float ADS1015_Trimmed_Mean(float *buffer, uint8_t n, uint8_t trim)
{
ADS1015_Sort_Array(buffer, n);
uint8_t start = trim;
uint8_t end = n - trim; /* exclusive */
if (end <= start) /* guard against a misconfigured trim value */
{
start = 0;
end = n;
}
float sum = 0.0f;
uint8_t count = 0;
for (uint8_t i = start; i < end; i++)
{
sum += buffer[i];
count++;
}
return sum / (float)count;
}
/*
* Simple average of the history buffer (stage-2 sliding window)
*/
float ADS1015_History_Average(const float *hist, uint8_t n)
{
float sum = 0.0f;
for (uint8_t i = 0; i < n; i++)
sum += hist[i];
return sum / (float)n;
}
/*
* Common processing core: applied identically to all 3 channels.
* Receives the current raw reading and the channel's state (global
* arrays/struct).
**/
void ADS1015_Process_Sample(ADS1015_filter_t *ch, float raw)
{
/* --- Stage 1: accumulate into the current burst --- */
ch->burst[ch->burst_index] = raw;
ch->burst_index++;
if (ch->burst_index < ADS1015_BURST_SIZE)
return; /* still collecting the burst, nothing else to do */
/* Burst complete: compute the trimmed mean */
float burst_result = ADS1015_Trimmed_Mean(ch->burst, ADS1015_BURST_SIZE, ADS1015_TRIM_COUNT);
ch->burst_index = 0; /* reset for the next burst */
/* --- Stage 2a: rolling history / sliding window --- */
ch->history[ch->history_index] = burst_result;
ch->history_index = (uint8_t)((ch->history_index + 1) % ADS1015_HISTORY_SIZE);
if (ch->history_count < ADS1015_HISTORY_SIZE)
ch->history_count++;
float window_average = ADS1015_History_Average(ch->history, ch->history_count);
/* --- Stage 2b: first-order IIR low-pass filter on the burst result --- */
if (!ch->iir_initialized)
{
ch->iir_state = burst_result;
ch->iir_initialized = 1;
}
else
{
ch->iir_state = ADS1015_IIR_ALPHA * burst_result + (1.0f - ADS1015_IIR_ALPHA) * ch->iir_state;
}
/* Final output: combines the IIR state (fast response to real drift)
* with the window average (more stable, slower response). Adjust
* the weighting per channel if needed. */
ch->filtered_value = 0.5f * ch->iir_state + 0.5f * window_average;
ch->value_valid = 1;
}
/* ---------------------------------------------------------------------- */
/* PUBLIC FUNCTIONS - ONE PER CHANNEL */
/* ---------------------------------------------------------------------- */
void ADS1015_pH_NewSample(float raw)
{
ADS1015_Process_Sample(&g_ph_filter, raw);
}
float ADSCalculate_ph_mV(void) // pH in mV
{
float ph_dut_sum;
@@ -279,7 +486,7 @@ float ADSCalculate_ph_mV(void) // pH in mV
for (i = (ADS1015_PH_AVERAGES-1); i > 0; i--)
ph_dut_samples[i] = ph_dut_samples[i-1];
ph_dut_samples[0] = (((float)(ADSreadADC_Differential_0_1(&i2c)) * ADS1015_ADC_VREF) / ADS1015_ADC_MAX); // 1. Converter leitura bruta do ADC para tensão real (mV)
ph_dut_samples[0] = (((float)(ADSreadADC_Differential_0_1(&i2c_ads1015)) * ADS1015_ADC_VREF) / ADS1015_ADC_MAX); // 1. Converter leitura bruta do ADC para tensão real (mV)
for (i = 0, ph_dut_sum=0; i < ADS1015_PH_AVERAGES; i++)
ph_dut_sum += ph_dut_samples[i];
@@ -333,7 +540,7 @@ float ADSCalculate_ph_Uncompensated(void)
* Note: The subtraction of 2048 assumes a differential configuration
* where the midpoint is at the mid-scale of the ADS1015.
*/
float v_measured = ((float)(2048 - ADSreadADC_Differential_0_1(&i2c)) * ADS1015_ADC_VREF) / ADS1015_ADC_MAX;
float v_measured = ((float)(ADSreadADC_Differential_0_1(&i2c_ads1015)) * ADS1015_ADC_VREF) / ADS1015_ADC_MAX;
/*
* 2. Calculate the original Slope (measured during calibration).
+68 -12
View File
@@ -20,6 +20,7 @@
#include "main.h"
#include "adc.h"
#include "i2c.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
@@ -57,6 +58,8 @@
/* USER CODE BEGIN PV */
uint8_t rx_buffer[256]; /*!< Buffer for received data */
uint8_t tx_data[] = "Hello RS-485 Broadcast!"; /*!< Data to send */
@@ -158,14 +161,21 @@ int main(void)
MX_I2C1_Init();
MX_I2C2_Init();
MX_USART1_UART_Init();
MX_TIM3_Init();
/* USER CODE BEGIN 2 */
Flash_Load_Page(&flash_data);
HAL_TIM_Base_Start_IT(&htim3);
//TempSensor_Init(&hadc1);
/*
HAL_TIM_Base_Start(&htim3);
HAL_ADCEx_Calibration_Start(&hadc1);
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)AD_RES, 2); // Internal Temperature conversion
*/
@@ -176,8 +186,12 @@ int main(void)
rs485_init();
ADS1015(&i2c, &hi2c1, ADS_ADDR_GND);
ADSsetGain(&i2c, GAIN_FOUR);
ADS1015(&i2c_ads1015, &hi2c1, ADS1015_ADDR_GND);
//ADSsetGain(&i2c_ads1015, GAIN_FOUR);
ADG715_ResetChannels();
// Start CE and RTD Measurement
@@ -189,7 +203,7 @@ int main(void)
/* Infinite loop */
/* USER CODE BEGIN WHILE */
/*
for(i=0;i<AD5934_TEMP_AVERAGES;i++) // Loop to get stability and get averages
{
refResistance = AD5934_Get_Ref_Resistance(); // On Board Resistor
@@ -265,14 +279,15 @@ int main(void)
}
*/
while (1)
{
AD5934_Process_System();
ADS1015_Process_System();
current_millis = HAL_GetTick();
current_millis = g_ms_counter;
// Piscar LED verde em PB5 a cada 0,5 segundos
@@ -289,8 +304,19 @@ int main(void)
uint8_t led_data[2] = {0x01, current_green_state}; // Command 0x01 for green LED
}
/*
status1 = rs485_send_broadcast(ph_t, strlen((char*)ph_t));
ph_compensated = ADSCalculate_ph_mV() ;
FloatToString(tempString, ph_compensated);
status0 = rs485_send_broadcast(tempString, (strlen((char*)tempString)-1));
status1 = rs485_send_broadcast(newline_ph, strlen((char*)newline_ph));
*/
}
// Piscar LED vermelho em PB4 a cada 1 segundo
@@ -308,26 +334,44 @@ int main(void)
}
if (g_rtd_filter.value_valid)
{
float rtd_final = g_rtd_filter.filtered_value;
status1 = rs485_send_broadcast(tm_t, strlen((char*)tm_t));
temperature_RTD = AD5934_GetTemperature(refResistance);
FloatToString(tempString, temperature_RTD);
//temperature_RTD = AD5934_GetTemperature(refResistance);
FloatToString(tempString, rtd_final);
status0 = rs485_send_broadcast(tempString, (strlen((char*)tempString)-1));
status1 = rs485_send_broadcast(newline_temp, strlen((char*)newline_temp));
}
if (g_ec_filter.value_valid)
{
float ec_final = g_ec_filter.filtered_value;
status1 = rs485_send_broadcast(ad_t, strlen((char*)ad_t));
admittance_EC = AD5934_GetImpedance(temperature_RTD);
FloatToString(tempString, admittance_EC);
//admittance_EC = AD5934_GetImpedance(temperature_RTD);
FloatToString(tempString, ec_final);
status0 = rs485_send_broadcast(tempString, (strlen((char*)tempString)-1));
status1 = rs485_send_broadcast(newline_admi, strlen((char*)newline_admi));
}
if (g_ref_filter.value_valid)
{
//float reference_final = g_ref_filter.filtered_value;
status1 = rs485_send_broadcast(ph_t, strlen((char*)ph_t));
ph_compensated = 10*ADSCalculate_ph_mV();//ADSCalculate_ph_Compensated(temperature_RTD);
ph_compensated = g_ph_filter.filtered_value;
FloatToString(tempString, ph_compensated);
status0 = rs485_send_broadcast(tempString, (strlen((char*)tempString)-1));
status1 = rs485_send_broadcast(newline_ph, strlen((char*)newline_ph));
status1 = rs485_send_broadcast(newline, strlen((char*)newline));
}
}
@@ -524,6 +568,18 @@ void intToStr(int N, char *str) {
}
}
/* TIM3 Timer Interrupt */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM3)
{
g_ms_counter++; /* Relógio global do sistema */
}
}
/*
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
+15
View File
@@ -55,6 +55,7 @@
/* USER CODE END 0 */
/* External variables --------------------------------------------------------*/
extern TIM_HandleTypeDef htim3;
extern UART_HandleTypeDef huart1;
/* USER CODE BEGIN EV */
@@ -198,6 +199,20 @@ void SysTick_Handler(void)
/* please refer to the startup file (startup_stm32f1xx.s). */
/******************************************************************************/
/**
* @brief This function handles TIM3 global interrupt.
*/
void TIM3_IRQHandler(void)
{
/* USER CODE BEGIN TIM3_IRQn 0 */
/* USER CODE END TIM3_IRQn 0 */
HAL_TIM_IRQHandler(&htim3);
/* USER CODE BEGIN TIM3_IRQn 1 */
/* USER CODE END TIM3_IRQn 1 */
}
/**
* @brief This function handles USART1 global interrupt.
*/
+10 -3
View File
@@ -41,9 +41,9 @@ void MX_TIM3_Init(void)
/* USER CODE END TIM3_Init 1 */
htim3.Instance = TIM3;
htim3.Init.Prescaler = 3;
htim3.Init.Prescaler = 2;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 59999;
htim3.Init.Period = 999;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
@@ -55,7 +55,7 @@ void MX_TIM3_Init(void)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
{
@@ -77,6 +77,10 @@ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
/* USER CODE END TIM3_MspInit 0 */
/* TIM3 clock enable */
__HAL_RCC_TIM3_CLK_ENABLE();
/* TIM3 interrupt Init */
HAL_NVIC_SetPriority(TIM3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM3_IRQn);
/* USER CODE BEGIN TIM3_MspInit 1 */
/* USER CODE END TIM3_MspInit 1 */
@@ -93,6 +97,9 @@ void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle)
/* USER CODE END TIM3_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_TIM3_CLK_DISABLE();
/* TIM3 interrupt Deinit */
HAL_NVIC_DisableIRQ(TIM3_IRQn);
/* USER CODE BEGIN TIM3_MspDeInit 1 */
/* USER CODE END TIM3_MspDeInit 1 */