diff --git a/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_adc.c b/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_adc.c new file mode 100644 index 0000000..e7fa495 --- /dev/null +++ b/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_adc.c @@ -0,0 +1,230 @@ +#include "stm32_matlab_adc.h" +#include + + +/////////////////////////////---SIMULINK FUNCTIONS---////////////////////////// +void Simulate_ADCs(void) +{ +#ifdef USE_ADC1 + ADC_Simulation(ADC1, &adc1s); +#endif +#ifdef USE_ADC2 + ADC_Simulation(ADC2, &adc2s); +#endif +#ifdef USE_ADC3 + ADC_Simulation(ADC3, &adc3s); +#endif +} + + +/////////////////////////////---ADC SIMULATION---///////////////////////////// +void ADC_Simulation(ADC_TypeDef* ADCx, struct ADC_Sim* ADCS) +{ + if (!(ADCx->CR2 & ADC_CR2_ADON)) return; + + // Start conversion on SWSTART + if (ADCx->CR2 & ADC_CR2_SWSTART) { + ADC_Start_Conversion(ADCx, ADCS); + ADCx->CR2 &= ~ADC_CR2_SWSTART; + } + + // Handle ongoing conversion - проверяем по флагу состояния + if (ADCS->conversion_time_elapsed >= 0) { + ADCS->conversion_time_elapsed += ADCS->simulation_step; + double total_time = ADC_Get_Total_Conversion_Time(ADCx, ADCS); + + if (ADCS->conversion_time_elapsed >= total_time) { + ADC_Complete_Conversion(ADCx, ADCS); + + // Continuous mode auto-restart + if (ADCx->CR2 & ADC_CR2_CONT) { + ADC_Start_Conversion(ADCx, ADCS); + } + } + } + +} + +void ADC_Start_Conversion(ADC_TypeDef* ADCx, struct ADC_Sim* ADCS) +{ + // Определяем канал для конверсии + if (ADCx->CR1 & ADC_CR1_SCAN) { + // Режим сканирования + ADCS->current_rank = 0; + ADCS->current_channel = ADC_Get_Sequence_Channel(ADCx, 0); + } + else { + // Одиночный канал + ADCS->current_channel = ADC_Get_Sequence_Channel(ADCx, 0); + } + + ADCS->conversion_time_elapsed = 0; +} + +void ADC_Complete_Conversion(ADC_TypeDef* ADCx, struct ADC_Sim* ADCS) +{ + // Конвертируем аналоговое значение в цифровое + double analog_val = 0; + if (ADCS->channel_connected[ADCS->current_channel]) { + analog_val = ADCS->channel_values[ADCS->current_channel]; + } + + if (analog_val < 0) + analog_val = 0; + if (analog_val > 3.3) + analog_val = 3.3; + + + // Сначала вычисляем значение АЦП + ADCS->last_conversion_value = (uint16_t)((analog_val / 3.3) * 4095.0); + + // Потом добавляем шум в LSB + int32_t noisy_value = (int32_t)ADCS->last_conversion_value + (rand() % (2 * ADC_NOISE_LSB + 1)) - ADC_NOISE_LSB; + + // Сатурация цифрового значения + if (noisy_value < 0) noisy_value = 0; + if (noisy_value > 4095) noisy_value = 4095; + + ADCS->last_conversion_value = (uint16_t)noisy_value; + + // Записываем в DR + ADCx->DR = ADCS->last_conversion_value; + + // Устанавливаем флаг EOC + ADCx->SR |= ADC_SR_EOC; + + // Обработка DMA + if (ADCx->CR2 & ADC_CR2_DMA) { + ADC_DMA_Transfer(ADCx, ADCS); + } + + // Обработка сканирования + if (ADCx->CR1 & ADC_CR1_SCAN) { + ADCS->current_rank++; + uint32_t seq_len = ADC_Get_Sequence_Length(ADCx); + + if (ADCS->current_rank < seq_len) { + // Следующий канал в последовательности + ADCS->current_channel = ADC_Get_Sequence_Channel(ADCx, ADCS->current_rank); + ADCS->conversion_time_elapsed = 0; + return; + } + else { + // Конец последовательности +#ifdef ADC_SR_EOS + ADCx->SR |= ADC_SR_EOS; +#endif + } + } + + ADCS->conversion_time_elapsed = 0; +} + +/////////////////////////////---REGISTER-BASED FUNCTIONS---/////////////////// +double ADC_Get_Total_Conversion_Time(ADC_TypeDef* ADCx, struct ADC_Sim* ADCS) +{ + // Получаем sampling time из регистров + uint32_t sampling_cycles = ADC_Get_Sampling_Cycles(ADCx, ADCS->current_channel); + + // Conversion cycles фиксированы для разрешения + uint32_t conversion_cycles = 12; // Для 12-bit + + double total_cycles = sampling_cycles + conversion_cycles; + double adc_clock = ADCS->adc_clock_freq; // Частота шины + + return total_cycles / adc_clock; +} + +uint32_t ADC_Get_Sampling_Cycles(ADC_TypeDef* ADCx, uint32_t channel) +{ + // Получаем sampling time из SMPR1/SMPR2 + uint32_t smpr_code; + if (channel <= 9) { + smpr_code = (ADCx->SMPR2 >> (channel * 3)) & 0x7; + } + else { + smpr_code = (ADCx->SMPR1 >> ((channel - 10) * 3)) & 0x7; + } + + // Convert SMPR code to actual cycles + static const uint32_t cycles_map[8] = { 3, 15, 28, 56, 84, 112, 144, 480 }; + return (smpr_code < 8) ? cycles_map[smpr_code] : 3; +} + +uint32_t ADC_Get_Sequence_Length(ADC_TypeDef* ADCx) +{ +#ifdef ADC_SQR1_L + return ((ADCx->SQR1 & ADC_SQR1_L) >> ADC_SQR1_L_Pos) + 1; +#else + return ((ADCx->SQR1 & 0x00F00000) >> 20) + 1; +#endif +} + +uint32_t ADC_Get_Sequence_Channel(ADC_TypeDef* ADCx, uint32_t rank) +{ + if (rank > 15) return 0; + + if (rank < 6) { + return (ADCx->SQR3 >> (rank * 5)) & 0x1F; + } + else if (rank < 12) { + return (ADCx->SQR2 >> ((rank - 6) * 5)) & 0x1F; + } + else { + return (ADCx->SQR1 >> ((rank - 12) * 5)) & 0x1F; + } +} + +/////////////////////////////---DMA FUNCTIONS---/////////////////////////////// +void ADC_DMA_Transfer(ADC_TypeDef* ADCx, struct ADC_Sim* ADCS) +{ + if (!ADCS->dma_buffer || ADCS->dma_buffer_size == 0) return; + + ADCS->dma_buffer[ADCS->dma_current_index] = ADCx->DR; + ADCS->dma_current_index++; + + if (ADCS->dma_current_index >= ADCS->dma_buffer_size) { + if (ADCS->dma_circular) { + ADCS->dma_current_index = 0; + } + } +} + +/////////////////////////////---CHANNEL FUNCTIONS---/////////////////////////// +void ADC_Set_Channel_Value(ADC_TypeDef* ADCx, uint32_t channel, double voltage) +{ +#ifdef USE_ADC1 + if (ADCx == ADC1 && channel < 19) { + adc1s.channel_values[channel] = voltage; + adc1s.channel_connected[channel] = 1; + } +#endif +#ifdef USE_ADC2 + if (ADCx == ADC2 && channel < 19) { + adc2s.channel_values[channel] = voltage; + adc2s.channel_connected[channel] = 1; + } +#endif +#ifdef USE_ADC3 + if (ADCx == ADC3 && channel < 19) { + adc3s.channel_values[channel] = voltage; + adc3s.channel_connected[channel] = 1; + } +#endif +} +/////////////////////////////---INITIALIZATION---///////////////////////////// + +void ADC_SIM_DEINIT(void) +{ +#ifdef USE_ADC1 + memset(&adc1s, 0, sizeof(adc1s)); +#endif +#ifdef USE_ADC2 + memset(&adc2s, 0, sizeof(adc2s)); +#endif +#ifdef USE_ADC3 + memset(&adc3s, 0, sizeof(adc3s)); +#endif +} + +/////////////////////////////////////////////////////////////////////////////// diff --git a/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_adc.h b/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_adc.h new file mode 100644 index 0000000..feea8fe --- /dev/null +++ b/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_adc.h @@ -0,0 +1,56 @@ +#ifndef _MATLAB_ADC_H_ +#define _MATLAB_ADC_H_ + +#include "stm32_matlab_conf.h" + + +#ifdef STM32F1 +#define ADC_NOISE_LSB 10 // РЁСѓРј РІ LSB (квантах АЦП) +#endif + +#ifdef STM32F4 +#define ADC_NOISE_LSB 2 // РЁСѓРј РІ LSB (квантах АЦП) +#endif + +/////////////////////////////---STRUCTURES---/////////////////////////// +struct ADC_Sim +{ + double conversion_time_elapsed; + uint32_t current_channel; + uint32_t current_rank; + uint16_t last_conversion_value; + + double channel_values[19]; + uint8_t channel_connected[19]; + + // DMA + uint32_t* dma_buffer; + uint32_t dma_buffer_size; + uint32_t dma_current_index; + uint8_t dma_circular; + + // Timing + double simulation_step; + double adc_clock_freq; +}; +/////////////////////////////////////////////////////////////////////// + +///////////////////////////---FUNCTIONS---/////////////////////////// + +void Simulate_ADCs(void); +void ADC_Simulation(ADC_TypeDef* ADCx, struct ADC_Sim* ADCS); +void ADC_Start_Conversion(ADC_TypeDef* ADCx, struct ADC_Sim* ADCS); +void ADC_Complete_Conversion(ADC_TypeDef* ADCx, struct ADC_Sim* ADCS); + +double ADC_Get_Total_Conversion_Time(ADC_TypeDef* ADCx, struct ADC_Sim* ADCS); +uint32_t ADC_Get_Sampling_Cycles(ADC_TypeDef* ADCx, uint32_t channel); +uint32_t ADC_Get_Sequence_Length(ADC_TypeDef* ADCx); +uint32_t ADC_Get_Sequence_Channel(ADC_TypeDef* ADCx, uint32_t rank); +void ADC_DMA_Transfer(ADC_TypeDef* ADCx, struct ADC_Sim* ADCS); +void ADC_Set_Channel_Value(ADC_TypeDef* ADCx, uint32_t channel, double voltage); + +void ADC_SIM_DEINIT(void); + +/////////////////////////////////////////////////////////////////////// + +#endif // _MATLAB_ADC_H_ \ No newline at end of file diff --git a/MATLAB/MCU_STM32_Matlab/stm32_matlab_conf.c b/MATLAB/MCU_STM32_Matlab/stm32_matlab_conf.c index 3c6bfd5..2973f9c 100644 --- a/MATLAB/MCU_STM32_Matlab/stm32_matlab_conf.c +++ b/MATLAB/MCU_STM32_Matlab/stm32_matlab_conf.c @@ -16,11 +16,21 @@ MCU_CortexMemoryTypeDef MCU_CORTEX_MEM; void Initialize_Periph_Sim(void) { Init_TIM_SIM(); + Init_ADC_SIM(); } + +// MCU PERIPH SIM +void Simulate_Periph_Sim(void) +{ + Simulate_TIMs(); + Simulate_ADCs(); +} + // MCU PERIPH DEINIT void deInitialize_Periph_Sim(void) { TIM_SIM_DEINIT(); + ADC_SIM_DEINIT(); } // MCU DEINIT void deInitialize_MCU(void) @@ -85,6 +95,7 @@ struct TIM_Sim tim14s; void Init_TIM_SIM(void) { #ifdef USE_TIM1 + memset(&tim1s, 0, sizeof(tim1s)); tim1s.tx_cnt = TIM1->CNT; tim1s.tx_step = hmcu.sSimSampleTime * ABP2_TIMS_Value; @@ -98,6 +109,7 @@ void Init_TIM_SIM(void) tim1s.Channels.OC4_PIN_SHIFT = 11; #endif #ifdef USE_TIM2 + memset(&tim2s, 0, sizeof(tim2s)); tim2s.tx_cnt = TIM2->CNT; tim2s.tx_step = hmcu.sSimSampleTime * ABP1_TIMS_Value; @@ -111,6 +123,7 @@ void Init_TIM_SIM(void) tim2s.Channels.OC4_PIN_SHIFT = 3; #endif #ifdef USE_TIM3 + memset(&tim3s, 0, sizeof(tim3s)); tim3s.tx_cnt = TIM3->CNT; tim3s.tx_step = hmcu.sSimSampleTime * ABP1_TIMS_Value; @@ -124,6 +137,7 @@ void Init_TIM_SIM(void) tim3s.Channels.OC4_PIN_SHIFT = 9; #endif #ifdef USE_TIM4 + memset(&tim4s, 0, sizeof(tim4s)); tim4s.tx_cnt = TIM4->CNT; tim4s.tx_step = hmcu.sSimSampleTime * ABP1_TIMS_Value; @@ -137,6 +151,7 @@ void Init_TIM_SIM(void) tim4s.Channels.OC4_PIN_SHIFT = 9; #endif #ifdef USE_TIM5 + memset(&tim5s, 0, sizeof(tim5s)); tim5s.tx_cnt = TIM5->CNT; tim5s.tx_step = hmcu.sSimSampleTime * ABP1_TIMS_Value; @@ -150,6 +165,7 @@ void Init_TIM_SIM(void) tim5s.Channels.OC4_PIN_SHIFT = 3; #endif #ifdef USE_TIMx + memset(&tim6s, 0, sizeof(tim6s)); tim6s.tx_cnt = TIMx->CNT; tim6s.tx_step = hmcu.sSimSampleTime * ABP1_TIMS_Value; @@ -165,3 +181,39 @@ void Init_TIM_SIM(void) } /*-------------------------------TIMERS----------------------------------*/ //-----------------------------------------------------------------------// + + + +//-----------------------------------------------------------------------// +/*---------------------------------ADC-----------------------------------*/ +#ifdef USE_ADC1 +struct ADC_Sim adc1s; +#endif +#ifdef USE_ADC2 +struct ADC_Sim adc2s; +#endif +#ifdef USE_ADC3 +struct ADC_Sim adc3s; +#endif +void Init_ADC_SIM(void) +{ +#ifdef USE_ADC1 + memset(&adc1s, 0, sizeof(adc1s)); + adc1s.simulation_step = hmcu.sSimSampleTime; + adc1s.adc_clock_freq = ABP2_Value; // Частота APB2 +#endif + +#ifdef USE_ADC2 + memset(&adc2s, 0, sizeof(adc2s)); + adc2s.simulation_step = hmcu.sSimSampleTime; + adc2s.adc_clock_freq = ABP2_Value; // Частота APB2 +#endif + +#ifdef USE_ADC3 + memset(&adc3s, 0, sizeof(adc3s)); + adc3s.simulation_step = hmcu.sSimSampleTime; + adc3s.adc_clock_freq = ABP2_Value; // Частота APB2 +#endif +} +/*---------------------------------ADC-----------------------------------*/ +//-----------------------------------------------------------------------// diff --git a/MATLAB/MCU_STM32_Matlab/stm32_matlab_conf.h b/MATLAB/MCU_STM32_Matlab/stm32_matlab_conf.h index df6ccad..8b353e6 100644 --- a/MATLAB/MCU_STM32_Matlab/stm32_matlab_conf.h +++ b/MATLAB/MCU_STM32_Matlab/stm32_matlab_conf.h @@ -54,13 +54,13 @@ //-----------------------------------------------------------------------// /*------------------------------FUNCTIONS--------------------------------*/ void deInitialize_Periph_Sim(void); +void Simulate_Periph_Sim(void); void deInitialize_MCU(void); void Initialize_Periph_Sim(void); #include "stm32_matlab_rcc.h" #include "stm32_matlab_gpio.h" - //-----------------------------------------------------------------------// /*-------------------------------TIMERS----------------------------------*/ //#if defined(USE_TIM1) || defined(USE_TIM2) || defined(USE_TIM3) || defined(USE_TIM4) || defined(USE_TIM5) || \ @@ -116,4 +116,22 @@ extern struct TIM_Sim tim14s; /*-------------------------------TIMERS----------------------------------*/ //-----------------------------------------------------------------------// +//-----------------------------------------------------------------------// +/*---------------------------------ADC-----------------------------------*/ +#include "stm32_matlab_adc.h" + +#ifdef USE_ADC1 +extern struct ADC_Sim adc1s; +#endif +#ifdef USE_ADC2 +extern struct ADC_Sim adc2s; +#endif +#ifdef USE_ADC3 +extern struct ADC_Sim adc3s; +#endif + +/*---------------------------------ADC-----------------------------------*/ +//-----------------------------------------------------------------------// + + #endif // _MATLAB_SETUP_H_ diff --git a/MATLAB/MCU_STM32_Matlab/stm32f4xx_matlab_conf.json b/MATLAB/MCU_STM32_Matlab/stm32f4xx_matlab_conf.json index 5a81e53..3c36e56 100644 --- a/MATLAB/MCU_STM32_Matlab/stm32f4xx_matlab_conf.json +++ b/MATLAB/MCU_STM32_Matlab/stm32f4xx_matlab_conf.json @@ -16,8 +16,7 @@ ], "PeriphSimulation": [ "uwTick = hmcu.SystemClock / (MCU_CORE_CLOCK / 1000)", - "Simulate_TIMs()", - "Simulate_GPIO_BSRR()" + "Simulate_Periph_Sim()" ], "PeriphDeinit": [ "deInitialize_Periph_Sim()" @@ -56,7 +55,7 @@ "Tab_ADC_Enable": { "Prompt": "Enable ADCs", "Type": "checkbox", - "Default": false, + "Default": true, "NewRow": true } } @@ -583,17 +582,27 @@ } }, "ADC": { + "Sources": [ + "Drivers/STM32_SIMULINK/stm32_matlab_adc.c" + ], "Defines": { "ADC1_Enable": { "Prompt": "ADC1 Enable", - "Def": "ADC1_ENABLE", + "Def": "USE_ADC1", "Type": "checkbox", - "Default": false, + "Default": true, "NewRow": true }, "ADC2_Enable": { "Prompt": "ADC2 Enable", - "Def": "ADC2_ENABLE", + "Def": "USE_ADC2", + "Type": "checkbox", + "Default": false, + "NewRow": true + }, + "ADC3_Enable": { + "Prompt": "ADC3 Enable", + "Def": "USE_ADC3", "Type": "checkbox", "Default": false, "NewRow": true diff --git a/MATLAB/MCU_Wrapper/MCU.c b/MATLAB/MCU_Wrapper/MCU.c index 822dd05..72b00c7 100644 --- a/MATLAB/MCU_Wrapper/MCU.c +++ b/MATLAB/MCU_Wrapper/MCU.c @@ -197,24 +197,24 @@ static void mdlTerminate(SimStruct* S) //// Простая версия - ждем завершения потока - // Ждем РґРѕ 5 секунд - for (int i = 0; i < 50; i++) { - // Проверяем, завершился ли поток (упрощенная проверка) - DWORD exitCode; - if (GetExitCodeThread(hmcu.hMCUThread, &exitCode) && exitCode != STILL_ACTIVE) { - break; // поток завершился - } - Sleep(100); // ждем 100ms - } - - - //// Даем потоку шанс завершиться нормально - //DWORD waitResult = WaitForSingleObject(hmcu.hMCUThread, 3000); - //if (waitResult == WAIT_TIMEOUT) { - // // Поток РЅРµ ответил - завершаем принудительно - // TerminateThread(hmcu.hMCUThread, 0); + //// Ждем РґРѕ 5 секунд + //for (int i = 0; i < 50; i++) { + // // Проверяем, завершился ли поток (упрощенная проверка) + // DWORD exitCode; + // if (GetExitCodeThread(hmcu.hMCUThread, &exitCode) && exitCode != STILL_ACTIVE) { + // break; // поток завершился + // } + // Sleep(100); // ждем 100ms //} + + // Даем потоку шанс завершиться нормально + DWORD waitResult = WaitForSingleObject(hmcu.hMCUThread, 10000); + if (waitResult == WAIT_TIMEOUT) { + // Поток РЅРµ ответил - завершаем принудительно + TerminateThread(hmcu.hMCUThread, 0); + } + CloseHandle(hmcu.hMCUThread); hmcu.hMCUThread = NULL; } diff --git a/MATLAB/MCU_Wrapper/mcu_wrapper.c b/MATLAB/MCU_Wrapper/mcu_wrapper.c index dba2ff6..6a07287 100644 --- a/MATLAB/MCU_Wrapper/mcu_wrapper.c +++ b/MATLAB/MCU_Wrapper/mcu_wrapper.c @@ -114,8 +114,7 @@ void MCU_Periph_Simulation(SimStruct* S) { // PERIPH SIM START uwTick = hmcu.SystemClock / (MCU_CORE_CLOCK / 1000); - Simulate_TIMs(); - Simulate_GPIO_BSRR(); + Simulate_Periph_Sim(); // PERIPH SIM END } diff --git a/MATLAB/MCU_Wrapper/mcu_wrapper_conf.h b/MATLAB/MCU_Wrapper/mcu_wrapper_conf.h index e444b4f..fa2864b 100644 --- a/MATLAB/MCU_Wrapper/mcu_wrapper_conf.h +++ b/MATLAB/MCU_Wrapper/mcu_wrapper_conf.h @@ -51,11 +51,11 @@ // INPUT/OUTPUTS PARAMS START #define IN_PORT_NUMB 2 #define ADC_PORT_1_WIDTH 6 -#define IN_PORT_2_WIDTH 16 +#define IN_PORT_2_WIDTH 1 #define OUT_PORT_NUMB 2 #define THYR_PORT_1_WIDTH 6 -#define OUT_PORT_2_WIDTH 16 +#define OUT_PORT_2_WIDTH 1 // INPUT/OUTPUTS PARAMS END /** WRAPPER_CONF diff --git a/MATLAB/app_wrapper/app_includes.h b/MATLAB/app_wrapper/app_includes.h index a1f34d7..1c5648d 100644 --- a/MATLAB/app_wrapper/app_includes.h +++ b/MATLAB/app_wrapper/app_includes.h @@ -13,6 +13,7 @@ //#include "stm32_matlab_conf.h" #include "main.h" #include "tim.h" +#include "adc.h" // INCLUDES END #endif //_APP_INCLUDES_H_ \ No newline at end of file diff --git a/MATLAB/app_wrapper/app_init.c b/MATLAB/app_wrapper/app_init.c index 12338d5..515a489 100644 --- a/MATLAB/app_wrapper/app_init.c +++ b/MATLAB/app_wrapper/app_init.c @@ -21,6 +21,8 @@ void app_init(void) { MX_TIM3_Init(); __HAL_TIM_SET_COMPARE(&hpwm1, PWM_CHANNEL_1, __HAL_TIM_GET_AUTORELOAD(&hpwm1)/2); HAL_TIM_PWM_Start(&hpwm1, PWM_CHANNEL_1); + MX_ADC1_Init(); + HAL_ADC_Start(&hadc1); // USER APP INIT END } diff --git a/MATLAB/app_wrapper/app_io.c b/MATLAB/app_wrapper/app_io.c index 745e9b9..46f50ea 100644 --- a/MATLAB/app_wrapper/app_io.c +++ b/MATLAB/app_wrapper/app_io.c @@ -32,7 +32,7 @@ void ThyristorWrite(real_T* Buffer) */ void app_readInputs(const real_T* Buffer) { // USER APP INPUT START - +ADC_Set_Channel_Value(ADC1, 0, ReadInputArray(1,0)); // USER APP INPUT END } @@ -44,5 +44,6 @@ void app_readInputs(const real_T* Buffer) { void app_writeOutputBuffer(real_T* Buffer) { // USER APP OUTPUT START ThyristorWrite(Buffer); + WriteOutputArray(ADC1->DR, 1, 0); // USER APP OUTPUT END } \ No newline at end of file diff --git a/MATLAB/upp_r2023.slx b/MATLAB/upp_r2023.slx index 67a3ffd..d991585 100644 Binary files a/MATLAB/upp_r2023.slx and b/MATLAB/upp_r2023.slx differ diff --git a/UPP/Core/Inc/adc.h b/UPP/Core/Inc/adc.h index 674dd85..34c0965 100644 --- a/UPP/Core/Inc/adc.h +++ b/UPP/Core/Inc/adc.h @@ -32,12 +32,15 @@ extern "C" { /* USER CODE END Includes */ +extern ADC_HandleTypeDef hadc1; + extern ADC_HandleTypeDef hadc3; /* USER CODE BEGIN Private defines */ /* USER CODE END Private defines */ +void MX_ADC1_Init(void); void MX_ADC3_Init(void); /* USER CODE BEGIN Prototypes */ diff --git a/UPP/Core/Src/adc.c b/UPP/Core/Src/adc.c index 317cc69..87bdb83 100644 --- a/UPP/Core/Src/adc.c +++ b/UPP/Core/Src/adc.c @@ -24,8 +24,56 @@ /* USER CODE END 0 */ +ADC_HandleTypeDef hadc1; ADC_HandleTypeDef hadc3; +/* ADC1 init function */ +void MX_ADC1_Init(void) +{ + + /* USER CODE BEGIN ADC1_Init 0 */ + + /* USER CODE END ADC1_Init 0 */ + + ADC_ChannelConfTypeDef sConfig = {0}; + + /* USER CODE BEGIN ADC1_Init 1 */ + + /* USER CODE END ADC1_Init 1 */ + + /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) + */ + hadc1.Instance = ADC1; + hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; + hadc1.Init.Resolution = ADC_RESOLUTION_12B; + hadc1.Init.ScanConvMode = DISABLE; + hadc1.Init.ContinuousConvMode = ENABLE; + hadc1.Init.DiscontinuousConvMode = DISABLE; + hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; + hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; + hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; + hadc1.Init.NbrOfConversion = 1; + hadc1.Init.DMAContinuousRequests = DISABLE; + hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV; + if (HAL_ADC_Init(&hadc1) != HAL_OK) + { + Error_Handler(); + } + + /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. + */ + sConfig.Channel = ADC_CHANNEL_0; + sConfig.Rank = 1; + sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES; + if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN ADC1_Init 2 */ + + /* USER CODE END ADC1_Init 2 */ + +} /* ADC3 init function */ void MX_ADC3_Init(void) { @@ -78,7 +126,28 @@ void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle) { GPIO_InitTypeDef GPIO_InitStruct = {0}; - if(adcHandle->Instance==ADC3) + if(adcHandle->Instance==ADC1) + { + /* USER CODE BEGIN ADC1_MspInit 0 */ + + /* USER CODE END ADC1_MspInit 0 */ + /* ADC1 clock enable */ + __HAL_RCC_ADC1_CLK_ENABLE(); + + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**ADC1 GPIO Configuration + PA0/WKUP ------> ADC1_IN0 + */ + GPIO_InitStruct.Pin = GPIO_PIN_0; + GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* USER CODE BEGIN ADC1_MspInit 1 */ + + /* USER CODE END ADC1_MspInit 1 */ + } + else if(adcHandle->Instance==ADC3) { /* USER CODE BEGIN ADC3_MspInit 0 */ @@ -116,7 +185,24 @@ void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle) void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle) { - if(adcHandle->Instance==ADC3) + if(adcHandle->Instance==ADC1) + { + /* USER CODE BEGIN ADC1_MspDeInit 0 */ + + /* USER CODE END ADC1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_ADC1_CLK_DISABLE(); + + /**ADC1 GPIO Configuration + PA0/WKUP ------> ADC1_IN0 + */ + HAL_GPIO_DeInit(GPIOA, GPIO_PIN_0); + + /* USER CODE BEGIN ADC1_MspDeInit 1 */ + + /* USER CODE END ADC1_MspDeInit 1 */ + } + else if(adcHandle->Instance==ADC3) { /* USER CODE BEGIN ADC3_MspDeInit 0 */ diff --git a/UPP/Core/Src/main.c b/UPP/Core/Src/main.c index becb0c7..ec5e420 100644 --- a/UPP/Core/Src/main.c +++ b/UPP/Core/Src/main.c @@ -104,6 +104,7 @@ int main(void) MX_SPI3_Init(); MX_TIM11_Init(); MX_TIM12_Init(); + MX_ADC1_Init(); /* USER CODE BEGIN 2 */ #else MX_TIM1_Init(); diff --git a/UPP/MDK-ARM/UPP.uvoptx b/UPP/MDK-ARM/UPP.uvoptx index d9bfde0..13cdd2d 100644 --- a/UPP/MDK-ARM/UPP.uvoptx +++ b/UPP/MDK-ARM/UPP.uvoptx @@ -1,4 +1,4 @@ - + 1.0 @@ -45,7 +45,7 @@ 79 66 8 - + 1 @@ -104,16 +104,16 @@ 0 0 6 - - - - - - - - - - + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll @@ -128,7 +128,7 @@ -U-O142 -O2190 -S0 -C0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC800 -FN1 -FF0STM32F4xx_1024.FLM -FS08000000 -FL0100000 -FP0($$Device:STM32F427ZGTx$CMSIS\Flash\STM32F4xx_1024.FLM) - + 0 @@ -158,19 +158,19 @@ 0 0 - - + + 0 0 0 - - - - - - - - + + + + + + + + 1 1 diff --git a/UPP/MDK-ARM/UPP.uvprojx b/UPP/MDK-ARM/UPP.uvprojx index 7545c7a..13644f1 100644 --- a/UPP/MDK-ARM/UPP.uvprojx +++ b/UPP/MDK-ARM/UPP.uvprojx @@ -1,10 +1,7 @@ - - - + + 2.1 -
### uVision Project, (C) Keil Software
- UPP @@ -20,28 +17,28 @@ Keil.STM32F4xx_DFP.2.16.0 http://www.keil.com/pack/ IRAM(0x20000000-0x2002FFFF) IRAM2(0x10000000-0x1000FFFF) IROM(0x8000000-0x80FFFFF) CLOCK(25000000) FPU2 CPUTYPE("Cortex-M4") TZ - - - + + + 0 - - - - - - - - - - + + + + + + + + + + $$Device:STM32F427ZGTx$CMSIS\SVD\STM32F427x.svd 0 0 - - - - - + + + + + 0 0 @@ -56,15 +53,15 @@ 1 1 1 - + 1 0 0 0 0 - - + + 0 0 0 @@ -73,8 +70,8 @@ 0 0 - - + + 0 0 0 @@ -83,15 +80,15 @@ 0 1 - - + + 0 0 0 0 1 - + 0 @@ -105,8 +102,8 @@ 0 0 3 - - + + 0 @@ -139,11 +136,11 @@ 1 BIN\UL2V8M.DLL - - - - - + + + + + 0 @@ -176,7 +173,7 @@ 0 0 "Cortex-M4" - + 0 0 0 @@ -311,7 +308,7 @@ 0x10000 - + 1 @@ -338,9 +335,9 @@ 0 0 - + USE_HAL_DRIVER,STM32F427xx - + ../Core/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F4xx/Include;../Drivers/CMSIS/Include;../AllLibs/ExtMemory/Inc;../AllLibs/Modbus/Inc;../AllLibs/MyLibs/MyLibs/Inc;../AllLibs/MyLibs/RTT;../AllLibs/PeriphGeneral/Inc;../Core/Configs @@ -356,10 +353,10 @@ 0 1 - - - - + + + + @@ -369,15 +366,15 @@ 0 1 0 - - - - - - - - - + + + + + + + + + @@ -796,26 +793,24 @@ - - + - + - + - + - + - + - @@ -824,5 +819,5 @@ -
+ diff --git a/UPP/UPP.ioc b/UPP/UPP.ioc index caaef45..b810d65 100644 --- a/UPP/UPP.ioc +++ b/UPP/UPP.ioc @@ -1,6 +1,14 @@ #MicroXplorer Configuration settings - do not modify +ADC1.Channel-1\#ChannelRegularConversion=ADC_CHANNEL_0 +ADC1.ContinuousConvMode=ENABLE +ADC1.IPParameters=Rank-1\#ChannelRegularConversion,master,Channel-1\#ChannelRegularConversion,SamplingTime-1\#ChannelRegularConversion,NbrOfConversionFlag,ContinuousConvMode +ADC1.NbrOfConversionFlag=1 +ADC1.Rank-1\#ChannelRegularConversion=1 +ADC1.SamplingTime-1\#ChannelRegularConversion=ADC_SAMPLETIME_3CYCLES +ADC1.master=1 ADC3.Channel-15\#ChannelRegularConversion=ADC_CHANNEL_7 -ADC3.IPParameters=Rank-15\#ChannelRegularConversion,Channel-15\#ChannelRegularConversion,SamplingTime-15\#ChannelRegularConversion,NbrOfConversionFlag +ADC3.IPParameters=Rank-15\#ChannelRegularConversion,Channel-15\#ChannelRegularConversion,SamplingTime-15\#ChannelRegularConversion,NbrOfConversionFlag,NbrOfConversion +ADC3.NbrOfConversion=1 ADC3.NbrOfConversionFlag=1 ADC3.Rank-15\#ChannelRegularConversion=1 ADC3.SamplingTime-15\#ChannelRegularConversion=ADC_SAMPLETIME_3CYCLES @@ -21,22 +29,23 @@ IWDG.Prescaler=IWDG_PRESCALER_32 KeepUserPlacement=false Mcu.CPN=STM32F427ZGT6 Mcu.Family=STM32F4 -Mcu.IP0=ADC3 -Mcu.IP1=CAN1 -Mcu.IP10=TIM11 -Mcu.IP11=TIM12 -Mcu.IP12=TIM13 -Mcu.IP13=USART3 -Mcu.IP14=USART6 -Mcu.IP2=IWDG -Mcu.IP3=NVIC -Mcu.IP4=RCC -Mcu.IP5=RTC -Mcu.IP6=SPI3 -Mcu.IP7=SYS -Mcu.IP8=TIM1 -Mcu.IP9=TIM3 -Mcu.IPNb=15 +Mcu.IP0=ADC1 +Mcu.IP1=ADC3 +Mcu.IP10=TIM3 +Mcu.IP11=TIM11 +Mcu.IP12=TIM12 +Mcu.IP13=TIM13 +Mcu.IP14=USART3 +Mcu.IP15=USART6 +Mcu.IP2=CAN1 +Mcu.IP3=IWDG +Mcu.IP4=NVIC +Mcu.IP5=RCC +Mcu.IP6=RTC +Mcu.IP7=SPI3 +Mcu.IP8=SYS +Mcu.IP9=TIM1 +Mcu.IPNb=16 Mcu.Name=STM32F427Z(G-I)Tx Mcu.Package=LQFP144 Mcu.Pin0=PE2 @@ -47,61 +56,62 @@ Mcu.Pin12=PF10 Mcu.Pin13=PH0/OSC_IN Mcu.Pin14=PH1/OSC_OUT Mcu.Pin15=PC0 -Mcu.Pin16=PA4 -Mcu.Pin17=PA5 -Mcu.Pin18=PA6 -Mcu.Pin19=PB0 +Mcu.Pin16=PA0/WKUP +Mcu.Pin17=PA4 +Mcu.Pin18=PA5 +Mcu.Pin19=PA6 Mcu.Pin2=PE4 -Mcu.Pin20=PB1 -Mcu.Pin21=PF11 -Mcu.Pin22=PB10 -Mcu.Pin23=PB11 -Mcu.Pin24=PB13 -Mcu.Pin25=PG6 -Mcu.Pin26=PC6 -Mcu.Pin27=PC7 -Mcu.Pin28=PC8 -Mcu.Pin29=PC9 +Mcu.Pin20=PB0 +Mcu.Pin21=PB1 +Mcu.Pin22=PF11 +Mcu.Pin23=PB10 +Mcu.Pin24=PB11 +Mcu.Pin25=PB13 +Mcu.Pin26=PG6 +Mcu.Pin27=PC6 +Mcu.Pin28=PC7 +Mcu.Pin29=PC8 Mcu.Pin3=PE5 -Mcu.Pin30=PA8 -Mcu.Pin31=PA9 -Mcu.Pin32=PA10 -Mcu.Pin33=PA11 -Mcu.Pin34=PA12 -Mcu.Pin35=PA13 -Mcu.Pin36=PA14 -Mcu.Pin37=PA15 -Mcu.Pin38=PC10 -Mcu.Pin39=PC11 +Mcu.Pin30=PC9 +Mcu.Pin31=PA8 +Mcu.Pin32=PA9 +Mcu.Pin33=PA10 +Mcu.Pin34=PA11 +Mcu.Pin35=PA12 +Mcu.Pin36=PA13 +Mcu.Pin37=PA14 +Mcu.Pin38=PA15 +Mcu.Pin39=PC10 Mcu.Pin4=PE6 -Mcu.Pin40=PC12 -Mcu.Pin41=PD2 -Mcu.Pin42=PD3 -Mcu.Pin43=PD6 -Mcu.Pin44=PG12 -Mcu.Pin45=PG15 -Mcu.Pin46=PB3 -Mcu.Pin47=PB6 -Mcu.Pin48=PB7 -Mcu.Pin49=PB8 +Mcu.Pin40=PC11 +Mcu.Pin41=PC12 +Mcu.Pin42=PD2 +Mcu.Pin43=PD3 +Mcu.Pin44=PD6 +Mcu.Pin45=PG12 +Mcu.Pin46=PG15 +Mcu.Pin47=PB3 +Mcu.Pin48=PB6 +Mcu.Pin49=PB7 Mcu.Pin5=PC13 -Mcu.Pin50=PB9 -Mcu.Pin51=PE0 -Mcu.Pin52=PE1 -Mcu.Pin53=VP_IWDG_VS_IWDG -Mcu.Pin54=VP_RTC_VS_RTC_Activate -Mcu.Pin55=VP_RTC_VS_RTC_Calendar -Mcu.Pin56=VP_SYS_VS_tim14 -Mcu.Pin57=VP_TIM1_VS_ClockSourceINT -Mcu.Pin58=VP_TIM3_VS_ClockSourceINT -Mcu.Pin59=VP_TIM11_VS_ClockSourceINT +Mcu.Pin50=PB8 +Mcu.Pin51=PB9 +Mcu.Pin52=PE0 +Mcu.Pin53=PE1 +Mcu.Pin54=VP_IWDG_VS_IWDG +Mcu.Pin55=VP_RTC_VS_RTC_Activate +Mcu.Pin56=VP_RTC_VS_RTC_Calendar +Mcu.Pin57=VP_SYS_VS_tim14 +Mcu.Pin58=VP_TIM1_VS_ClockSourceINT +Mcu.Pin59=VP_TIM3_VS_ClockSourceINT Mcu.Pin6=PC14/OSC32_IN -Mcu.Pin60=VP_TIM12_VS_ClockSourceINT -Mcu.Pin61=VP_TIM13_VS_ClockSourceINT +Mcu.Pin60=VP_TIM11_VS_ClockSourceINT +Mcu.Pin61=VP_TIM12_VS_ClockSourceINT +Mcu.Pin62=VP_TIM13_VS_ClockSourceINT Mcu.Pin7=PC15/OSC32_OUT Mcu.Pin8=PF6 Mcu.Pin9=PF7 -Mcu.PinsNb=62 +Mcu.PinsNb=63 Mcu.ThirdPartyNb=0 Mcu.UserConstants=mb_huart,huart3;mbdbg_htim,htim11;mb_htim,htim12;mb_dbg_huart,huart6;ustim,htim13;mem_hspi,hspi3;hpwm1,htim1;hpwm2,htim2;PWM_CHANNEL_1,TIM_CHANNEL_1;PWM_CHANNEL_2,TIM_CHANNEL_2;PWM_CHANNEL_3,TIM_CHANNEL_3;PWM_CHANNEL_4,TIM_CHANNEL_4;PWM_CHANNEL_5,TIM_CHANNEL_3;PWM_CHANNEL_6,TIM_CHANNEL_4 Mcu.UserName=STM32F427ZGTx @@ -121,6 +131,7 @@ NVIC.TIM8_TRG_COM_TIM14_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:true NVIC.TimeBase=TIM8_TRG_COM_TIM14_IRQn NVIC.TimeBaseIP=TIM14 NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +PA0/WKUP.Signal=ADCx_IN0 PA10.GPIOParameters=GPIO_Label PA10.GPIO_Label=PWM3 PA10.Locked=true @@ -404,6 +415,8 @@ RTC.IPParameters=WeekDay,Year,Date,Month,Hours RTC.Month=RTC_MONTH_JANUARY RTC.WeekDay=RTC_WEEKDAY_MONDAY RTC.Year=25 +SH.ADCx_IN0.0=ADC1_IN0,IN0 +SH.ADCx_IN0.ConfNb=1 SH.ADCx_IN10.0=ADC3_IN10,IN10 SH.ADCx_IN10.ConfNb=1 SH.S_TIM1_CH1.0=TIM1_CH1,PWM Generation1 CH1