/** ****************************************************************************** * File Name : ADC.c * Description : This file provides code for the configuration * of the ADC instances. ****************************************************************************** * This notice applies to any and all portions of this file * that are not between comment pairs USER CODE BEGIN and * USER CODE END. Other portions of this file, whether * inserted by the user or by software development tools * are owned by their respective copyright owners. * * Copyright (c) 2018 STMicroelectronics International N.V. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted, provided that the following conditions are met: * * 1. Redistribution of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of STMicroelectronics nor the names of other * contributors to this software may be used to endorse or promote products * derived from this software without specific written permission. * 4. This software, including modifications and/or derivative works of this * software, must execute solely and exclusively on microcontroller or * microprocessor devices manufactured by or for STMicroelectronics. * 5. Redistribution and use of this software other than as permitted under * this license is void and will automatically terminate your rights under * this license. * * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "adc.h" #include "tim.h" #include "gpio.h" #include "dma.h" #include "arm_math.h" #include "my.h" __IO bool ADC_OK = false; __IO uint32_t TACHO_SAMPLE = 0; extern TIM_HandleTypeDef htim5; extern volatile bool NeedOff; extern volatile bool clbr; extern __IO uint32_t TIMEOUT_BAT; extern volatile uint8_t menu; volatile bool FirstSample = true; volatile uint16_t FirstSampleCount = 0; volatile uint32_t ADCBat = 0; volatile uint16_t adc_cnt = 0; float32_t Vbat = 4.0f; float32_t oldVbat = 3.9f; volatile uint32_t cntVbat = 0; volatile uint8_t StateBattery = 0xf; volatile uint16_t CounterU = 0; volatile uint32_t med[N_MED_ADC] = {4.0, 4.0, 4.0, 4.0, 4.0}; //{0,0,0,0,0,0,0,0,0,0,0,0,0}; volatile uint8_t gystVbat = VBAT_GYST_VALUE; volatile uint8_t gystTimeout = TIMEOUT_GYST_VALUE; //volatile uint32_t DMABat = 0; //volatile uint16_t DMABat[16384]; __IO bool StartBat = false; ADC_HandleTypeDef hadc1; ADC_HandleTypeDef hadc2; ADC_HandleTypeDef hadc3; DMA_HandleTypeDef hdma_adc1; DMA_HandleTypeDef hdma_adc3; volatile float32_t aa1 = 1.0f; volatile float32_t aa0 = 0.0f; void MX_ADC1_Init(void) { ADC_ChannelConfTypeDef sConfig; hadc1.Instance = ADC1; hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; hadc1.Init.Resolution = ADC_RESOLUTION_12B; hadc1.Init.ScanConvMode = DISABLE; hadc1.Init.ContinuousConvMode = DISABLE; hadc1.Init.DiscontinuousConvMode = DISABLE; hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING; hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T5_TRGO; hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc1.Init.NbrOfConversion = 1; hadc1.Init.DMAContinuousRequests = ENABLE; hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV; if(HAL_ADC_Init(&hadc1) != HAL_OK) { Error_Handler(); } sConfig.Channel = ADC_CHANNEL_1; sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES; if(HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { Error_Handler(); } //SET_ADCOption2(SYSCFG_PMC_ADCxDC2, ENABLE); } void MX_ADC2_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; ADC_ChannelConfTypeDef sConfig; hadc2.Instance = ADC2; hadc2.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; hadc2.Init.Resolution = ADC_RESOLUTION_12B; hadc2.Init.ScanConvMode = DISABLE; hadc2.Init.ContinuousConvMode = DISABLE; hadc2.Init.DiscontinuousConvMode = DISABLE; hadc2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; hadc2.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1; hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc2.Init.NbrOfConversion = 1; hadc2.Init.DMAContinuousRequests = DISABLE; hadc2.Init.EOCSelection = ADC_EOC_SINGLE_CONV; if(HAL_ADC_Init(&hadc2) != HAL_OK) { Error_Handler(); } __HAL_RCC_ADC2_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); sConfig.Channel = ADC_CHANNEL_10; sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES; if(HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK) { Error_Handler(); } } void MX_ADC3_Init(void) //TACHO { GPIO_InitTypeDef GPIO_InitStruct; ADC_ChannelConfTypeDef sConfig; hadc3.Instance = ADC3; hadc3.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; hadc3.Init.Resolution = ADC_RESOLUTION_12B; hadc3.Init.ScanConvMode = DISABLE; hadc3.Init.ContinuousConvMode = DISABLE; hadc3.Init.DiscontinuousConvMode = DISABLE; hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING; hadc3.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_TRGO; hadc3.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc3.Init.NbrOfConversion = 1; hadc3.Init.DMAContinuousRequests = ENABLE; hadc3.Init.EOCSelection = ADC_EOC_SINGLE_CONV; if(HAL_ADC_Init(&hadc3) != HAL_OK) { Error_Handler(); } sConfig.Channel = ADC_CHANNEL_11; sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES; sConfig.Offset = 0; if(HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK) { Error_Handler(); } } void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle) { GPIO_InitTypeDef GPIO_InitStruct; if(adcHandle->Instance == ADC1) { __HAL_RCC_ADC1_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_1; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); hdma_adc1.Instance = DMA2_Stream4; hdma_adc1.Init.Channel = DMA_CHANNEL_0; hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE; hdma_adc1.Init.MemInc = DMA_MINC_ENABLE; hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; hdma_adc1.Init.Mode = DMA_CIRCULAR; hdma_adc1.Init.Priority = DMA_PRIORITY_HIGH; hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_DISABLE; if(HAL_DMA_Init(&hdma_adc1) != HAL_OK) { Error_Handler(); } __HAL_LINKDMA(adcHandle, DMA_Handle, hdma_adc1); } else if(adcHandle->Instance == ADC2) { __HAL_RCC_ADC2_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); } else if(adcHandle->Instance == ADC3) { __HAL_RCC_ADC3_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_1; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); hdma_adc3.Instance = DMA2_Stream1; hdma_adc3.Init.Channel = DMA_CHANNEL_2; hdma_adc3.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_adc3.Init.PeriphInc = DMA_PINC_DISABLE; hdma_adc3.Init.MemInc = DMA_MINC_ENABLE; hdma_adc3.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; hdma_adc3.Init.MemDataAlignment = DMA_PDATAALIGN_HALFWORD; hdma_adc3.Init.Mode = DMA_CIRCULAR; hdma_adc3.Init.Priority = DMA_PRIORITY_HIGH; hdma_adc3.Init.FIFOMode = DMA_FIFOMODE_DISABLE; hdma_adc3.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL; hdma_adc3.Init.MemBurst = DMA_MBURST_SINGLE; hdma_adc3.Init.PeriphBurst = DMA_PBURST_SINGLE; if(HAL_DMA_Init(&hdma_adc3) != HAL_OK) { Error_Handler(); } __HAL_LINKDMA(adcHandle, DMA_Handle, hdma_adc3); } } void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle) { if(adcHandle->Instance == ADC1) { __HAL_RCC_ADC1_CLK_DISABLE(); HAL_GPIO_DeInit(GPIOA, GPIO_PIN_1); HAL_DMA_DeInit(adcHandle->DMA_Handle); } else if(adcHandle->Instance == ADC2) { __HAL_RCC_ADC2_CLK_DISABLE(); HAL_GPIO_DeInit(GPIOC, GPIO_PIN_0); //HAL_DMA_DeInit(adcHandle->DMA_Handle); } else if(adcHandle->Instance == ADC3) { __HAL_RCC_ADC3_CLK_DISABLE(); HAL_GPIO_DeInit(GPIOC, GPIO_PIN_1); HAL_DMA_DeInit(adcHandle->DMA_Handle); } } /* USER CODE BEGIN 1 */ void StartBatMeas(void) { TIMEOUT_BAT = sec5 + sec5; StartBat = true; } /////////////////////////////////////////////////////// void StartADC12(void) { HAL_ADC_Start_DMA(&hadc1, (uint32_t *) &DMA_Udar_u16(0), 16384u); HAL_TIM_Base_Start(&htim5); HAL_TIM_GenerateEvent(&htim5, TIM_EVENTSOURCE_UPDATE); } void StopADC12(void) { HAL_TIM_Base_Stop(&htim5); HAL_ADC_Stop_DMA(&hadc1); } ////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////// void StartTacho(void) { //HAL_ADC_Start_DMA(&hadc3, (uint32_t*) &TACHO_SAMPLE, 1); HAL_ADC_Start_DMA(&hadc3, (uint32_t *) &DMA_Udar_u16(0), 16384u); HAL_TIM_Base_Start(&htim1); HAL_TIM_GenerateEvent(&htim1, TIM_EVENTSOURCE_UPDATE); } void StopTacho(void) { //HAL_ADC_Stop_DMA(&hadc3); HAL_TIM_Base_Stop(&htim1); HAL_ADC_Stop_DMA(&hadc3); } ///////////////////////////////////////////// void MeasBattery(void) { float32_t f; static uint8_t oldState = 0xf; int32_t V32, i; uint32_t Bat; if((StartBat)) { HAL_ADC_Start(&hadc2); HAL_ADC_PollForConversion(&hadc2, 100); Bat = HAL_ADC_GetValue(&hadc2); HAL_ADC_Stop(&hadc2); ADCBat += Bat; } } uint32_t MedVbat(uint32_t val) { uint32_t i = 0; uint32_t j = 0; uint32_t k = 0; uint32_t m; uint32_t temp[N_MED_ADC]; for(i = N_MED_ADC - 1; i > 0; i--) med[i] = med[i - 1]; med[0] = val; for(i = 0; i < N_MED_ADC; i++) temp[i] = med[i]; if(CounterU < N_MED_ADC) CounterU++; for(j = 0; j < CounterU; j++) { for(i = j; i < CounterU; i++) { if(temp[i] < temp[j]) { m = temp[j]; temp[j] = temp[i]; temp[i] = m; } } } i = CounterU >> 1; if((k & 0x1) || (i == 0)) m = temp[i]; else m = (temp[i] + temp[i - 1]) / 2; return m; } void SET_ADCOption1(FunctionalState NewState) { /* ENABLE PWR clock */ __HAL_RCC_PWR_CLK_ENABLE(); if(NewState != DISABLE) { /* Set ADCDC1 bit */ SET_BIT(PWR->CR1, PWR_CR1_ADCDC1); //PWR->CR |= ((uint32_t) PWR_CR_ADCDC1); } else { /* Reset ADCDC1 bit */ SET_BIT(PWR->CR1, PWR_CR1_ADCDC1); //PWR->CR &= (uint32_t) (~PWR_CR_ADCDC1); } } /** * @brief Enables or disables the ADCx Option_2 configuration. * * @param ADCxDC2: The ADCxDC2 bit to be used. * * This parameter can be one of the following values: * * @arg SYSCFG_PMC_ADCxDC2: All ADCxDC2 bits * * @arg SYSCFG_PMC_ADC1DC2: ADC1DC2 bit * * @arg SYSCFG_PMC_ADC2DC2: ADC2DC2 bit * * @arg SYSCFG_PMC_ADC3DC2: ADC3DC2 bit * * @param NewState: new state of the ADCxDC2 bit. * * This parameter can be: ENABLE or DISABLE. * @retval None */ void SET_ADCOption2(uint32_t ADCxDC2, FunctionalState NewState) { /* Enable the SYSCFG clock*/ __HAL_RCC_SYSCFG_CLK_ENABLE(); if(NewState != DISABLE) { /* Set the ADCxDC2 */ SYSCFG->PMC |= (uint32_t) ADCxDC2; } else { /* Reset the ADCxDC2 */ SYSCFG->PMC &= (uint32_t) (~ADCxDC2); } } /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/