三重采样很简单,就是三个ADC叠加成更高速度,但是不是所有通道都支持三重采样.如图,只有写着ADC123_INx的才可以.
当初改掉原来官方的ADC1 + ADC2接PA4结果什么用都没,真是麻烦.另外只能按照WORD传输.进入DMA中断后要赶紧处理数据.取出高16和低16位.这个三重下,顺序是比较复杂(其实也就是先来后到),不过实际上不用管,当做只有一个ADC在工作就好了.
aADCxMultimodeDualMasterConvertedData[tmp_index] = (uint16_t) __LL_ADC_MULTI_CONV_DATA_MASTER_SLAVE(LL_ADC_MULTI_MASTER, aADCxADCyMultimodeDualConvertedData[tmp_index]); aADCyMultimodeDualSlaveConvertedData[tmp_index] = (uint16_t) __LL_ADC_MULTI_CONV_DATA_MASTER_SLAVE(LL_ADC_MULTI_SLAVE, aADCxADCyMultimodeDualConvertedData[tmp_index]);
得到数据该怎么处理就怎么处理,这么快速度,串口是发不走的了,因为串口至少得144000000bps,不太可能,看看怎么送出去了,这数据.或者处理.
/** ****************************************************************************** * @file Examples_LL/ADC/ADC_MultimodeDualInterleaved/Src/main.c * @author MCD Application Team * @version V1.0.0 * @date 30-December-2016 * @brief This example describes how to use several ADC peripherals in * multimode, mode interleaved. * ADC master instance synchronizes and manages ADC slave instance. * Multimode interleaved combines ADC instances to convert * the same channel and increase the overall ADC conversion rate. * This example configures the ADC to perform conversions at the * maximum ADC conversion rate possible (with a sampling time * corresponding to ADC resolution 12 bits). * This example is based on the STM32F7xx ADC LL API; * Peripheral initialization done using LL unitary services functions. ****************************************************************************** * @attention * * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2> * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions 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 its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 "main.h" /** @addtogroup STM32F7xx_LL_Examples * @{ */ /** @addtogroup ADC_MultimodeDualInterleaved * @{ */ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Definitions of ADC hardware constraints delays */ /* Note: Only ADC IP HW delays are defined in ADC LL driver driver, */ /* not timeout values: */ /* Timeout values for ADC operations are dependent to device clock */ /* configuration (system clock versus ADC clock), */ /* and therefore must be defined in user application. */ /* Refer to @ref ADC_LL_EC_HW_DELAYS for description of ADC timeout */ /* values definition. */ /* Timeout values for ADC operations. */ /* (enable settling time, disable settling time, ...) */ /* Values defined to be higher than worst cases: low clock frequency, */ /* maximum prescalers. */ /* Example of profile very low frequency : ADC clock frequency 36MHz */ /* prescaler 2, sampling time 56 ADC clock cycles, resolution 12 bits. */ /* - ADC enable time: maximum delay is 3 us */ /* (refer to device datasheet, parameter "tSTAB") */ /* - ADC disable time: maximum delay should be a few ADC clock cycles */ /* - ADC stop conversion time: maximum delay should be a few ADC clock */ /* cycles */ /* - ADC conversion time: with this hypothesis of clock settings, maximum */ /* delay will be 99us. */ /* (refer to device reference manual, section "Timing") */ /* Unit: ms */ #define ADC_CALIBRATION_TIMEOUT_MS ((uint32_t) 1) #define ADC_ENABLE_TIMEOUT_MS ((uint32_t) 1) #define ADC_DISABLE_TIMEOUT_MS ((uint32_t) 1) #define ADC_STOP_CONVERSION_TIMEOUT_MS ((uint32_t) 1) #define ADC_CONVERSION_TIMEOUT_MS ((uint32_t) 2) /* Definitions of environment analog values */ /* Value of analog reference voltage (Vref+), connected to analog voltage */ /* supply Vdda (unit: mV). */ #define VDDA_APPLI ((uint32_t)3300) /* Definitions of data related to this example */ /* Init variable out of expected ADC conversion data range */ #define VAR_CONVERTED_DATA_INIT_VALUE (__LL_ADC_DIGITAL_SCALE(LL_ADC_RESOLUTION_12B) + 1) /* Definition of ADCx conversions data table size */ /* Note: Considering interruption occurring after each number of */ /* "ADC_CONVERTED_DATA_BUFFER_SIZE" ADC conversions */ /* (IT from DMA transfer complete), */ /* select sampling time and ADC clock with sufficient */ /* duration to not create an overhead situation in IRQHandler. */ #define ADC_CONVERTED_DATA_BUFFER_SIZE ((uint32_t) 256) /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Variables for ADC conversion data */ __IO uint32_t aADCxADCyMultimodeDualConvertedData[ADC_CONVERTED_DATA_BUFFER_SIZE]; /* ADC multimode dual conversion data: ADC master and ADC slave conversion data are concatenated in a registers of 32 bits. */ static uint16_t aADCxMultimodeDualMasterConvertedData[ADC_CONVERTED_DATA_BUFFER_SIZE];/* For the purpose of this example, dispatch multimode dual conversion data into array corresponding to ADC master conversion data. */ static uint16_t aADCyMultimodeDualSlaveConvertedData[ADC_CONVERTED_DATA_BUFFER_SIZE]; /* For the purpose of this example, dispatch multimode dual conversion data into array corresponding to ADC slave conversion data. */ /* Variable to report status of DMA transfer of ADC group regular conversions */ /* 0: DMA transfer is not completed */ /* 1: DMA transfer is completed */ /* 2: DMA transfer has not been started yet (initial state) */ __IO uint8_t ubDmaTransferStatus = 2; /* Variable set into DMA interruption callback */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); void Configure_DMA(void); void Configure_ADC(void); void Configure_ADC_slave(void); void Activate_ADC(void); void Activate_ADC_slave(void); static void CPU_CACHE_Enable(void); /* Private functions ---------------------------------------------------------*/ /** * @brief Main program * @param None * @retval None */ int main(void) { /* Enable the CPU Cache */ CPU_CACHE_Enable(); /* Configure the system clock to 216 MHz */ SystemClock_Config(); /* Initialize button in EXTI mode */ /* UserButton_Init(); */ /* Configure DMA for data transfer from ADC */ Configure_DMA(); /* Configure ADC */ /* Note: This function configures the ADC but does not enable it. */ /* To enable it, use function "Activate_ADC()". */ /* This is intended to optimize power consumption: */ /* 1. ADC configuration can be done once at the beginning */ /* (ADC disabled, minimal power consumption) */ /* 2. ADC enable (higher power consumption) can be done just before */ /* ADC conversions needed. */ /* Then, possible to perform successive "Activate_ADC()", */ /* "Deactivate_ADC()", ..., without having to set again */ /* ADC configuration. */ Configure_ADC(); /* For multimode, configure ADC slave */ Configure_ADC_slave(); /* Activate ADC */ /* Perform ADC activation procedure to make it ready to convert. */ Activate_ADC(); Activate_ADC_slave(); LL_ADC_REG_StartConversionSWStart(ADC1); /* Infinite loop */ while (1) { /* Note: ADC group regular conversion start is done into push button */ /* IRQ handler, refer to function "UserButton_Callback()". */ /* Note: LED state depending on DMA transfer status is set into DMA */ /* IRQ handler, refer to functions "DmaTransferComplete()" */ /* and "DmaTransferHalfComplete()". */ /* Note: ADC conversion data are stored into array */ /* "aADCxADCyMultimodeDualConvertedData". */ /* For this example purpose, ADC conversion data of ADC master and */ /* ADC slave are dispatched into arrays */ /* "aADCxMultimodeDualMasterConvertedData" */ /* and "aADCyMultimodeDualSlaveConvertedData", refer to comments */ /* into function "DmaTransferComplete()". */ /* (for debug: see variable content into watch window). */ /* Note: ADC conversion data can be computed to physical values */ /* using ADC LL driver helper macro: */ /* uhADCxConvertedData_Voltage_mVolt */ /* = __LL_ADC_CALC_DATA_TO_VOLTAGE(VDDA_APPLI, */ /* uhADCxConvertedData), */ /* LL_ADC_RESOLUTION_12B) */ } } /** * @brief This function configures DMA for transfer of data from ADC * @param None * @retval None */ void Configure_DMA(void) { /*## Configuration of NVIC #################################################*/ /* Configure NVIC to enable DMA interruptions */ NVIC_SetPriority(DMA2_Stream0_IRQn, 1); /* DMA IRQ lower priority than ADC IRQ */ NVIC_EnableIRQ(DMA2_Stream0_IRQn); /*## Configuration of DMA ##################################################*/ /* Enable the peripheral clock of DMA */ LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA2); /* Configure the DMA transfer */ /* - DMA transfer in circular mode to match with ADC configuration: */ /* DMA unlimited requests. */ /* - DMA transfer from ADC without address increment. */ /* - DMA transfer to memory with address increment. */ /* - DMA transfer from ADC by word to match with ADC configuration: */ /* ADC resolution 12 bits and and multimode enabled, */ /* ADC master and ADC slave conversion data are concatenated in */ /* a register of 32 bits. */ /* - DMA transfer to memory by word to match with ADC conversion data */ /* buffer variable type: word. */ LL_DMA_SetChannelSelection(DMA2, LL_DMA_STREAM_0, LL_DMA_CHANNEL_0); LL_DMA_ConfigTransfer(DMA2, LL_DMA_STREAM_0, LL_DMA_DIRECTION_PERIPH_TO_MEMORY | LL_DMA_MODE_CIRCULAR | LL_DMA_PERIPH_NOINCREMENT | LL_DMA_MEMORY_INCREMENT | LL_DMA_PDATAALIGN_WORD | LL_DMA_MDATAALIGN_WORD | LL_DMA_PRIORITY_HIGH ); /* Set DMA transfer addresses of source and destination */ /* Note: On this STM32 device, in multimode, ADC conversion data with */ /* ADC master and ADC slave conversion data concatenated are located */ /* in a specific multimode data register. */ LL_DMA_ConfigAddresses(DMA2, LL_DMA_STREAM_0, LL_ADC_DMA_GetRegAddr(ADC1, LL_ADC_DMA_REG_REGULAR_DATA_MULTI), (uint32_t)&aADCxADCyMultimodeDualConvertedData, LL_DMA_DIRECTION_PERIPH_TO_MEMORY); /* Set DMA transfer size */ LL_DMA_SetDataLength(DMA2, LL_DMA_STREAM_0, ADC_CONVERTED_DATA_BUFFER_SIZE); /* Enable DMA transfer interruption: transfer complete */ LL_DMA_EnableIT_TC(DMA2, LL_DMA_STREAM_0); /*## Activation of DMA #####################################################*/ /* Enable the DMA transfer */ LL_DMA_EnableStream(DMA2, LL_DMA_STREAM_0); } /** * @brief Configure ADC (ADC instance: ADC1) and GPIO used by ADC channels. * @note In case re-use of this function outside of this example: * This function includes checks of ADC hardware constraints before * executing some configuration functions. * - In this example, all these checks are not necessary but are * implemented anyway to show the best practice usages * corresponding to reference manual procedure. * (On some STM32 series, setting of ADC features are not * conditioned to ADC state. However, in order to be compliant with * other STM32 series and to show the best practice usages, * ADC state is checked anyway with same constraints). * Software can be optimized by removing some of these checks, * if they are not relevant considering previous settings and actions * in user application. * - If ADC is not in the appropriate state to modify some parameters, * the setting of these parameters is bypassed without error * reporting: * it can be the expected behavior in case of recall of this * function to update only a few parameters (which update fullfills * the ADC state). * Otherwise, it is up to the user to set the appropriate error * reporting in user application. * @note Peripheral configuration is minimal configuration from reset values. * Thus, some useless LL unitary functions calls below are provided as * commented examples - setting is default configuration from reset. * @param None * @retval None */ void Configure_ADC(void) { /*## Configuration of GPIO used by ADC channels ############################*/ /* Note: On this STM32 device, ADC1 channel 4 is mapped on GPIO pin PA.04 */ /* Enable GPIO Clock */ LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA); /* Configure GPIO in analog mode to be used as ADC input */ LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_0, LL_GPIO_MODE_ANALOG); /*## Configuration of ADC ##################################################*/ /*## Configuration of ADC hierarchical scope: common to several ADC ########*/ /* Enable ADC clock (core clock) */ LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_ADC1); /* Note: Hardware constraint (refer to description of the functions */ /* below): */ /* On this STM32 serie, setting of these features are not */ /* conditioned to ADC state. */ /* However, in order to be compliant with other STM32 series */ /* and to show the best practice usages, ADC state is checked. */ /* Software can be optimized by removing some of these checks, if */ /* they are not relevant considering previous settings and actions */ /* in user application. */ if(__LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE() == 0) { /* Note: Call of the functions below are commented because they are */ /* useless in this example: */ /* setting corresponding to default configuration from reset state. */ /* Set ADC clock (conversion clock) common to several ADC instances */ LL_ADC_SetCommonClock(__LL_ADC_COMMON_INSTANCE(ADC1), LL_ADC_CLOCK_SYNC_PCLK_DIV2); /* Set ADC measurement path to internal channels */ // LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(ADC1), LL_ADC_PATH_INTERNAL_NONE); /*## Configuration of ADC hierarchical scope: multimode ####################*/ /* Set ADC multimode configuration */ LL_ADC_SetMultimode(__LL_ADC_COMMON_INSTANCE(ADC1), LL_ADC_MULTI_TRIPLE_REG_INTERL); /* Set ADC multimode DMA transfer */ LL_ADC_SetMultiDMATransfer(__LL_ADC_COMMON_INSTANCE(ADC1), LL_ADC_MULTI_REG_DMA_UNLMT_3); /* Set ADC multimode: delay between 2 sampling phases */ /* Note: Delay has been chosen to have ADC2 conversion start in the */ /* mid-delay between ADC1 conversions. */ LL_ADC_SetMultiTwoSamplingDelay(__LL_ADC_COMMON_INSTANCE(ADC1), LL_ADC_MULTI_TWOSMP_DELAY_5CYCLES); } /*## Configuration of ADC hierarchical scope: ADC instance #################*/ /* Note: Hardware constraint (refer to description of the functions */ /* below): */ /* On this STM32 serie, setting of these features are not */ /* conditioned to ADC state. */ /* However, ADC state is checked anyway with standard requirements */ /* (refer to description of this function). */ if (LL_ADC_IsEnabled(ADC1) == 0) { /* Note: Call of the functions below are commented because they are */ /* useless in this example: */ /* setting corresponding to default configuration from reset state. */ /* Set ADC data resolution */ // LL_ADC_SetResolution(ADC1, LL_ADC_RESOLUTION_12B); /* Set ADC conversion data alignment */ // LL_ADC_SetResolution(ADC1, LL_ADC_DATA_ALIGN_RIGHT); /* Set Set ADC sequencers scan mode, for all ADC groups */ /* (group regular, group injected). */ // LL_ADC_SetSequencersScanMode(ADC1, LL_ADC_SEQ_SCAN_DISABLE); } /*## Configuration of ADC hierarchical scope: ADC group regular ############*/ /* Note: Hardware constraint (refer to description of the functions */ /* below): */ /* On this STM32 serie, setting of these features are not */ /* conditioned to ADC state. */ /* However, ADC state is checked anyway with standard requirements */ /* (refer to description of this function). */ if (LL_ADC_IsEnabled(ADC1) == 0) { /* Set ADC group regular trigger source */ LL_ADC_REG_SetTriggerSource(ADC1, LL_ADC_REG_TRIG_SOFTWARE); /* Set ADC group regular trigger polarity */ // LL_ADC_REG_SetTriggerEdge(ADC1, LL_ADC_REG_TRIG_EXT_RISING); /* Set ADC group regular continuous mode */ LL_ADC_REG_SetContinuousMode(ADC1, LL_ADC_REG_CONV_CONTINUOUS); /* Set ADC group regular conversion data transfer */ /* Note: Both ADC master and ADC slave have multimode setting */ /* to use 1 DMA channel for all ADC instances. */ /* In this case, each ADC instance must have setting of */ /* ADC DMA request set to default value (no DMA transfer). */ /* and ADC DMA transfer is managed by ADC common instance. */ /* Refer to function "LL_ADC_SetMultiDMATransfer()". */ LL_ADC_REG_SetDMATransfer(ADC1, LL_ADC_REG_DMA_TRANSFER_NONE); /* Set ADC group regular sequencer */ /* Note: On this STM32 serie, ADC group regular sequencer is */ /* fully configurable: sequencer length and each rank */ /* affectation to a channel are configurable. */ /* Refer to description of function */ /* "LL_ADC_REG_SetSequencerLength()". */ /* Set ADC group regular sequencer length and scan direction */ LL_ADC_REG_SetSequencerLength(ADC1, LL_ADC_REG_SEQ_SCAN_DISABLE); /* Set ADC group regular sequencer discontinuous mode */ // LL_ADC_REG_SetSequencerDiscont(ADC1, LL_ADC_REG_SEQ_DISCONT_DISABLE); /* Set ADC group regular sequence: channel on the selected sequence rank. */ LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_0); } /*## Configuration of ADC hierarchical scope: ADC group injected ###########*/ /* Note: Hardware constraint (refer to description of the functions */ /* below): */ /* On this STM32 serie, setting of these features are not */ /* conditioned to ADC state. */ /* However, ADC state is checked anyway with standard requirements */ /* (refer to description of this function). */ if (LL_ADC_IsEnabled(ADC1) == 0) { /* Note: Call of the functions below are commented because they are */ /* useless in this example: */ /* setting corresponding to default configuration from reset state. */ /* Set ADC group injected trigger source */ // LL_ADC_INJ_SetTriggerSource(ADC1, LL_ADC_INJ_TRIG_SOFTWARE); /* Set ADC group injected trigger polarity */ // LL_ADC_INJ_SetTriggerEdge(ADC1, LL_ADC_INJ_TRIG_EXT_RISING); /* Set ADC group injected conversion trigger */ // LL_ADC_INJ_SetTrigAuto(ADC1, LL_ADC_INJ_TRIG_INDEPENDENT); /* Set ADC group injected sequencer */ /* Note: On this STM32 serie, ADC group injected sequencer is */ /* fully configurable: sequencer length and each rank */ /* affectation to a channel are configurable. */ /* Refer to description of function */ /* "LL_ADC_INJ_SetSequencerLength()". */ /* Set ADC group injected sequencer length and scan direction */ // LL_ADC_INJ_SetSequencerLength(ADC1, LL_ADC_INJ_SEQ_SCAN_DISABLE); /* Set ADC group injected sequencer discontinuous mode */ // LL_ADC_INJ_SetSequencerDiscont(ADC1, LL_ADC_INJ_SEQ_DISCONT_DISABLE); /* Set ADC group injected sequence: channel on the selected sequence rank. */ // LL_ADC_INJ_SetSequencerRanks(ADC1, LL_ADC_INJ_RANK_1, LL_ADC_CHANNEL_0); } /*## Configuration of ADC hierarchical scope: channels #####################*/ /* Note: Hardware constraint (refer to description of the functions */ /* below): */ /* On this STM32 serie, setting of these features are not */ /* conditioned to ADC state. */ /* However, in order to be compliant with other STM32 series */ /* and to show the best practice usages, ADC state is checked. */ /* Software can be optimized by removing some of these checks, if */ /* they are not relevant considering previous settings and actions */ /* in user application. */ if (LL_ADC_IsEnabled(ADC1) == 0) { /* Set ADC channels sampling time */ /* Note: Considering interruption occurring after each number of */ /* "ADC_CONVERTED_DATA_BUFFER_SIZE" ADC conversions */ /* (IT from DMA transfer complete), */ /* select sampling time and ADC clock with sufficient */ /* duration to not create an overhead situation in IRQHandler. */ LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_0, LL_ADC_SAMPLINGTIME_3CYCLES); } /*## Configuration of ADC transversal scope: analog watchdog ###############*/ /* Note: On this STM32 serie, there is only 1 analog watchdog available. */ /* Set ADC analog watchdog: channels to be monitored */ // LL_ADC_SetAnalogWDMonitChannels(ADC1, LL_ADC_AWD_DISABLE); /* Set ADC analog watchdog: thresholds */ // LL_ADC_SetAnalogWDThresholds(ADC1, LL_ADC_AWD_THRESHOLD_HIGH, __LL_ADC_DIGITAL_SCALE(LL_ADC_RESOLUTION_12B)); // LL_ADC_SetAnalogWDThresholds(ADC1, LL_ADC_AWD_THRESHOLD_LOW, 0x000); /*## Configuration of ADC transversal scope: oversampling ##################*/ /* Note: Feature not available on this STM32 serie */ /* Note: in this example, ADC group regular end of conversions */ /* (number of ADC conversions defined by DMA buffer size) */ /* are notified by DMA transfer interruptions). */ } /** * @brief For multimode, configure ADC slave (ADC instance: ADC2) * and GPIO used by ADC channels. * @note Configuration of GPIO: * Not configured: same as ADC master (ADC slave shares the common configuration of ADC master) * Configuration of ADC: * - Common to several ADC: * Not configured: same as ADC master (ADC slave shares the common configuration of ADC master) * - Multimode * Not configured: same as ADC master (ADC slave shares the common configuration of ADC master) * @note In case re-use of this function outside of this example: * This function includes checks of ADC hardware constraints before * executing some configuration functions. * - In this example, all these checks are not necessary but are * implemented anyway to show the best practice usages * corresponding to reference manual procedure. * (On some STM32 series, setting of ADC features are not * conditioned to ADC state. However, in order to be compliant with * other STM32 series and to show the best practice usages, * ADC state is checked anyway with same constraints). * Software can be optimized by removing some of these checks, * if they are not relevant considering previous settings and actions * in user application. * - If ADC is not in the appropriate state to modify some parameters, * the setting of these parameters is bypassed without error * reporting: * it can be the expected behavior in case of recall of this * function to update only a few parameters (which update fullfills * the ADC state). * Otherwise, it is up to the user to set the appropriate error * reporting in user application. * @note Peripheral configuration is minimal configuration from reset values. * Thus, some useless LL unitary functions calls below are provided as * commented examples - setting is default configuration from reset. * @param None * @retval None */ void Configure_ADC_slave(void) { /*## Configuration of GPIO used by ADC channels ############################*/ /* Note: not configured: In this example, ADC slave group regular converts */ /* the same channel as ADC master group regular. */ /* Channel configuration same as ADC master. */ /*## Configuration of ADC ##################################################*/ /* Enable ADC clock (core clock) */ LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_ADC2); LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_ADC3); /*## Configuration of ADC hierarchical scope: common to several ADC ########*/ /* Note: ADC clock (core clock) not configured: same as ADC master */ /* (ADC slave shares the common clock of ADC master). */ /* Note: not configured: same as ADC master (ADC slave shares the common */ /* configuration of ADC master). */ /*## Configuration of ADC hierarchical scope: multimode ####################*/ /* Note: not configured: same as ADC master (ADC slave shares the common */ /* configuration of ADC master). */ /*## Configuration of ADC hierarchical scope: ADC instance #################*/ /* Note: Hardware constraint (refer to description of the functions */ /* below): */ /* On this STM32 serie, setting of these features are not */ /* conditioned to ADC state. */ /* However, ADC state is checked anyway with standard requirements */ /* (refer to description of this function). */ if (LL_ADC_IsEnabled(ADC2) == 0) { /* Note: Call of the functions below are commented because they are */ /* useless in this example: */ /* setting corresponding to default configuration from reset state. */ /* Set ADC data resolution */ // LL_ADC_SetResolution(ADC2, LL_ADC_RESOLUTION_12B); /* Set ADC conversion data alignment */ // LL_ADC_SetResolution(ADC2, LL_ADC_DATA_ALIGN_RIGHT); /* Set Set ADC sequencers scan mode, for all ADC groups */ /* (group regular, group injected). */ LL_ADC_SetSequencersScanMode(ADC2, LL_ADC_SEQ_SCAN_ENABLE); LL_ADC_SetSequencersScanMode(ADC3, LL_ADC_SEQ_SCAN_ENABLE); } /*## Configuration of ADC hierarchical scope: ADC group regular ############*/ /* Note: Hardware constraint (refer to description of the functions */ /* below): */ /* On this STM32 serie, setting of these features are not */ /* conditioned to ADC state. */ /* However, ADC state is checked anyway with standard requirements */ /* (refer to description of this function). */ if (LL_ADC_IsEnabled(ADC2) == 0) { /* Set ADC group regular trigger source */ /* Note: On this STM32 device, in multimode, ADC slave trigger source */ /* setting is mandatory: SW start. */ LL_ADC_REG_SetTriggerSource(ADC2, LL_ADC_REG_TRIG_SOFTWARE); LL_ADC_REG_SetTriggerSource(ADC3, LL_ADC_REG_TRIG_SOFTWARE); /* Set ADC group regular continuous mode */ /* Note: On this STM32 device, in multimode, ADC slave continuous */ /* conversions mode must be the same as ADC master. */ LL_ADC_REG_SetContinuousMode(ADC2, LL_ADC_REG_CONV_CONTINUOUS); LL_ADC_REG_SetContinuousMode(ADC3, LL_ADC_REG_CONV_CONTINUOUS); /* Set ADC group regular conversion data transfer */ /* Note: Both ADC master and ADC slave have multimode setting */ /* to use 1 DMA channel for all ADC instances. */ /* In this case, each ADC instance must have setting of */ /* ADC DMA request set to default value (no DMA transfer). */ /* and ADC DMA transfer is managed by ADC common instance. */ /* Refer to function "LL_ADC_SetMultiDMATransfer()". */ LL_ADC_REG_SetDMATransfer(ADC2, LL_ADC_REG_DMA_TRANSFER_NONE); LL_ADC_REG_SetDMATransfer(ADC3, LL_ADC_REG_DMA_TRANSFER_NONE); /* Specify which ADC flag between EOC (end of unitary conversion) */ /* or EOS (end of sequence conversions) is used to indicate */ /* the end of conversion. */ // LL_ADC_REG_SetFlagEndOfConversion(ADC2, LL_ADC_REG_FLAG_EOC_SEQUENCE_CONV); /* Set ADC group regular sequencer */ /* Note: On this STM32 serie, ADC group regular sequencer is */ /* fully configurable: sequencer length and each rank */ /* affectation to a channel are configurable. */ /* Refer to description of function */ /* "LL_ADC_REG_SetSequencerLength()". */ /* Set ADC group regular sequencer length and scan direction */ LL_ADC_REG_SetSequencerLength(ADC2, LL_ADC_REG_SEQ_SCAN_DISABLE); LL_ADC_REG_SetSequencerLength(ADC3, LL_ADC_REG_SEQ_SCAN_DISABLE); /* Set ADC group regular sequencer discontinuous mode */ // LL_ADC_REG_SetSequencerDiscont(ADC2, LL_ADC_REG_SEQ_DISCONT_DISABLE); /* Set ADC group regular sequence: channel on the selected sequence rank. */ LL_ADC_REG_SetSequencerRanks(ADC2, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_0); LL_ADC_REG_SetSequencerRanks(ADC3, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_0); } /*## Configuration of ADC hierarchical scope: ADC group injected ###########*/ /* Note: Hardware constraint (refer to description of the functions */ /* below): */ /* On this STM32 serie, setting of these features are not */ /* conditioned to ADC state. */ /* However, ADC state is checked anyway with standard requirements */ /* (refer to description of this function). */ if (LL_ADC_IsEnabled(ADC2) == 0) { /* Note: Call of the functions below are commented because they are */ /* useless in this example: */ /* setting corresponding to default configuration from reset state. */ /* Set ADC group injected trigger source */ // LL_ADC_INJ_SetTriggerSource(ADC2, LL_ADC_INJ_TRIG_SOFTWARE); /* Set ADC group injected trigger polarity */ // LL_ADC_INJ_SetTriggerEdge(ADC2, LL_ADC_INJ_TRIG_EXT_RISING); /* Set ADC group injected conversion trigger */ // LL_ADC_INJ_SetTrigAuto(ADC2, LL_ADC_INJ_TRIG_INDEPENDENT); /* Set ADC group injected sequencer */ /* Note: On this STM32 serie, ADC group injected sequencer is */ /* fully configurable: sequencer length and each rank */ /* affectation to a channel are configurable. */ /* Refer to description of function */ /* "LL_ADC_INJ_SetSequencerLength()". */ /* Set ADC group injected sequencer length and scan direction */ // LL_ADC_INJ_SetSequencerLength(ADC2, LL_ADC_INJ_SEQ_SCAN_DISABLE); /* Set ADC group injected sequencer discontinuous mode */ // LL_ADC_INJ_SetSequencerDiscont(ADC2, LL_ADC_INJ_SEQ_DISCONT_DISABLE); /* Set ADC group injected sequence: channel on the selected sequence rank. */ // LL_ADC_INJ_SetSequencerRanks(ADC2, LL_ADC_INJ_RANK_1, LL_ADC_CHANNEL_0); } /*## Configuration of ADC hierarchical scope: channels #####################*/ /* Note: not configured: In this example, ADC slave group regular converts */ /* the same channel as ADC master group regular. */ /* Channel configuration same as ADC master. */ /*## Configuration of ADC transversal scope: analog watchdog ###############*/ /* Note: On this STM32 serie, there is only 1 analog watchdog available. */ /* Set ADC analog watchdog: channels to be monitored */ // LL_ADC_SetAnalogWDMonitChannels(ADC2, LL_ADC_AWD_DISABLE); /* Set ADC analog watchdog: thresholds */ // LL_ADC_SetAnalogWDThresholds(ADC2, LL_ADC_AWD_THRESHOLD_HIGH, __LL_ADC_DIGITAL_SCALE(LL_ADC_RESOLUTION_12B)); // LL_ADC_SetAnalogWDThresholds(ADC2, LL_ADC_AWD_THRESHOLD_LOW, 0x000); /*## Configuration of ADC transversal scope: oversampling ##################*/ /* Note: Feature not available on this STM32 serie */ /* Note: in this example, ADC group regular end of conversions */ /* (number of ADC conversions defined by DMA buffer size) */ /* are notified by DMA transfer interruptions). */ } /** * @brief Perform ADC activation procedure to make it ready to convert * (ADC instance: ADC1). * @note Operations: * - ADC instance * - Enable ADC * - ADC group regular * none: ADC conversion start-stop to be performed * after this function * - ADC group injected * none: ADC conversion start-stop to be performed * after this function * @param None * @retval None */ void Activate_ADC(void) { #if (USE_TIMEOUT == 1) uint32_t Timeout = 0; /* Variable used for timeout management */ #endif /* USE_TIMEOUT */ /*## Operation on ADC hierarchical scope: ADC instance #####################*/ /* Note: Hardware constraint (refer to description of the functions */ /* below): */ /* On this STM32 serie, setting of these features are not */ /* conditioned to ADC state. */ /* However, in order to be compliant with other STM32 series */ /* and to show the best practice usages, ADC state is checked. */ /* Software can be optimized by removing some of these checks, if */ /* they are not relevant considering previous settings and actions */ /* in user application. */ if (LL_ADC_IsEnabled(ADC1) == 0) { /* Enable ADC */ LL_ADC_Enable(ADC1); } /*## Operation on ADC hierarchical scope: ADC group regular ################*/ /* Note: No operation on ADC group regular performed here. */ /* ADC group regular conversions to be performed after this function */ /* using function: */ /* "LL_ADC_REG_StartConversion();" */ /*## Operation on ADC hierarchical scope: ADC group injected ###############*/ /* Note: No operation on ADC group injected performed here. */ /* ADC group injected conversions to be performed after this function */ /* using function: */ /* "LL_ADC_INJ_StartConversion();" */ } /** * @brief Perform ADC activation procedure to make it ready to convert * (ADC instance: ADC2, used as ADC slave in multimode configuration). * @note Operations: * - ADC instance * - Enable ADC * - ADC group regular * none: ADC conversion start-stop to be performed * after this function * - ADC group injected * none: ADC conversion start-stop to be performed * after this function * @param None * @retval None */ void Activate_ADC_slave(void) { #if (USE_TIMEOUT == 1) uint32_t Timeout = 0; /* Variable used for timeout management */ #endif /* USE_TIMEOUT */ /*## Operation on ADC hierarchical scope: ADC instance #####################*/ /* Note: Hardware constraint (refer to description of the functions */ /* below): */ /* On this STM32 serie, setting of these features are not */ /* conditioned to ADC state. */ /* However, in order to be compliant with other STM32 series */ /* and to show the best practice usages, ADC state is checked. */ /* Software can be optimized by removing some of these checks, if */ /* they are not relevant considering previous settings and actions */ /* in user application. */ if (LL_ADC_IsEnabled(ADC2) == 0) { /* Enable ADC */ LL_ADC_Enable(ADC2); LL_ADC_Enable(ADC3); } /*## Operation on ADC hierarchical scope: ADC group regular ################*/ /* Note: No operation on ADC group regular performed here. */ /* In ADC multimode group regular interleaved, ADC slave conversions */ /* start and stop are controlled by ADC master. */ /*## Operation on ADC hierarchical scope: ADC group injected ###############*/ /* Note: No operation on ADC group injected performed here. */ /* ADC group injected conversions to be performed after this function */ /* using function: */ /* "LL_ADC_INJ_StartConversion();" */ } /** * @brief System Clock Configuration * The system Clock is configured as follow : * System Clock source = PLL (HSE) * SYSCLK(Hz) = 216000000 * HCLK(Hz) = 216000000 * AHB Prescaler = 1 * APB1 Prescaler = 4 * APB2 Prescaler = 2 * HSI Frequency(Hz) = 8000000 * PLL_M = 8 * PLL_N = 432 * PLL_P = 2 * VDD(V) = 3.3 * Main regulator output voltage = Scale1 mode * Flash Latency(WS) = 7 * @param None * @retval None */ void SystemClock_Config(void) { /* Enable HSE clock */ LL_RCC_HSE_EnableBypass(); LL_RCC_HSE_Enable(); while(LL_RCC_HSE_IsReady() != 1) { }; /* Set FLASH latency */ LL_FLASH_SetLatency(LL_FLASH_LATENCY_7); /* Enable PWR clock */ LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR); /* Activation OverDrive Mode */ LL_PWR_EnableOverDriveMode(); while(LL_PWR_IsActiveFlag_OD() != 1) { }; /* Activation OverDrive Switching */ LL_PWR_EnableOverDriveSwitching(); while(LL_PWR_IsActiveFlag_ODSW() != 1) { }; /* Main PLL configuration and activation */ LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_8, 432, LL_RCC_PLLP_DIV_2); LL_RCC_PLL_Enable(); while(LL_RCC_PLL_IsReady() != 1) { }; /* Sysclk activation on the main PLL */ LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) { }; /* Set APB1 & APB2 prescaler */ LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_4); LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_2); /* Set systick to 1ms */ SysTick_Config(216000000 / 1000); /* Update CMSIS variable (which can be updated also through SystemCoreClockUpdate function) */ SystemCoreClock = 216000000; } /** * @brief CPU L1-Cache enable. * @param None * @retval None */ static void CPU_CACHE_Enable(void) { /* Enable I-Cache */ SCB_EnableICache(); /* Enable D-Cache */ SCB_EnableDCache(); } /******************************************************************************/ /* USER IRQ HANDLER TREATMENT */ /******************************************************************************/ /** * @brief DMA transfer complete callback * @note This function is executed when the transfer complete interrupt * is generated * @retval None */ void AdcDmaTransferComplete_Callback() { uint32_t tmp_index = 0; /* For the purpose of this example, dispatch multimode dual conversion data */ /* into arrays corresponding to ADC master and ADC slave conversion data. */ /* Note: In a real application, this processing is useless and can be */ /* avoided by setting multimode DMA transfer to one DMA channel */ /* for each of ADC master and ADC slave. */ /* Refer to function "LL_ADC_SetMultiDMATransfer()". */ /* Management of the 2nd half of the buffer */ for (tmp_index = (ADC_CONVERTED_DATA_BUFFER_SIZE / 3); tmp_index < ADC_CONVERTED_DATA_BUFFER_SIZE; tmp_index++) { aADCxMultimodeDualMasterConvertedData[tmp_index] = (uint16_t) __LL_ADC_MULTI_CONV_DATA_MASTER_SLAVE(LL_ADC_MULTI_MASTER, aADCxADCyMultimodeDualConvertedData[tmp_index]); aADCyMultimodeDualSlaveConvertedData[tmp_index] = (uint16_t) __LL_ADC_MULTI_CONV_DATA_MASTER_SLAVE(LL_ADC_MULTI_SLAVE, aADCxADCyMultimodeDualConvertedData[tmp_index]); } /* Update status variable of DMA transfer */ ubDmaTransferStatus = 1; } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t *file, uint32_t line) { /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d", file, line) */ /* Infinite loop */ while (1) { } } #endif /** * @} */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/