void adcSetResolution (uint8_t res){ samplingDisable(); HAL_ADC_Stop_DMA(&hadc1); HAL_ADC_Stop_DMA(&hadc2); HAL_ADC_Stop_DMA(&hadc3); if(res==8){ ADCResolution = ADC_RESOLUTION8b; }else if(res==12){ ADCResolution = ADC_RESOLUTION12b; }else{ return; } HAL_ADC_DeInit(&hadc1); HAL_ADC_DeInit(&hadc2); HAL_ADC_DeInit(&hadc3); HAL_DMA_DeInit(&hdma_adc1); HAL_DMA_DeInit(&hdma_adc2); HAL_DMA_DeInit(&hdma_adc3); MX_ADC1_Init(); MX_ADC2_Init(); MX_ADC3_Init(); }
/** * @brief Initializes ADC HAL. * @param None * @retval None */ static void ADCx_DeInit(void) { hnucleo_Adc.Instance = NUCLEO_ADCx; HAL_ADC_DeInit(&hnucleo_Adc); ADCx_MspDeInit(&hnucleo_Adc); }
void adc_deinit() { HAL_Status status = HAL_ERROR; #ifdef ADC_IT_MODE #ifdef ADC_TEST_FIFO status = HAL_ADC_FifoConfigChannel(ADC_INCH, ADC_SELECT_DISABLE); #else status = HAL_ADC_ConfigChannel(ADC_INCH, ADC_SELECT_DISABLE, ADC_IRQ_MODE, 0, 0); #endif if (status != HAL_OK) printf("ADC config error %d\n", status); status = HAL_ADC_Stop_Conv_IT(); if (status != HAL_OK) printf("ADC it mode stop error %d\n", status); status = HAL_ADC_DisableIRQCallback(ADC_INCH); if (status != HAL_OK) printf("ADC cb disable error %d\n", status); #endif status = HAL_ADC_DeInit(); if (status != HAL_OK) printf("ADC deinit error %d\n", status); }
/*====================================================================================================*/ void ADC_Config( void ) { ADC_ChannelConfTypeDef ADC_ChannelConfStruct; HAL_StatusTypeDef state; /* Config ADC *****************************************************************/ ADC_HandleStruct.Instance = ADCx; ADC_HandleStruct.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1; ADC_HandleStruct.Init.Resolution = ADC_RESOLUTION_12B; ADC_HandleStruct.Init.DataAlign = ADC_DATAALIGN_RIGHT; ADC_HandleStruct.Init.ScanConvMode = ENABLE; ADC_HandleStruct.Init.EOCSelection = ADC_EOC_SINGLE_CONV; ADC_HandleStruct.Init.LowPowerAutoWait = DISABLE; ADC_HandleStruct.Init.ContinuousConvMode = ENABLE; ADC_HandleStruct.Init.NbrOfConversion = ADC_BUF_CHENNAL; ADC_HandleStruct.Init.DiscontinuousConvMode = ENABLE; ADC_HandleStruct.Init.NbrOfDiscConversion = 1; ADC_HandleStruct.Init.ExternalTrigConv = ADC_SOFTWARE_START; ADC_HandleStruct.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; ADC_HandleStruct.Init.DMAContinuousRequests = ENABLE; ADC_HandleStruct.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; HAL_ADC_DeInit(&ADC_HandleStruct); state = HAL_ADC_Init(&ADC_HandleStruct); if(state != HAL_OK) while(1) { ; } /* Config ADC Chennal **********************************************************/ ADC_ChannelConfStruct.SamplingTime = ADC_SAMPLETIME_601CYCLES_5; ADC_ChannelConfStruct.SingleDiff = ADC_SINGLE_ENDED; ADC_ChannelConfStruct.OffsetNumber = ADC_OFFSET_NONE; ADC_ChannelConfStruct.Offset = 0; // ADC1_CH1 Channel ADC_ChannelConfStruct.Channel = ADCx_CHANNEL; ADC_ChannelConfStruct.Rank = ADC_REGULAR_RANK_1; state = HAL_ADC_ConfigChannel(&ADC_HandleStruct, &ADC_ChannelConfStruct); if(state != HAL_OK) while(1) { ; } // ADC1_CH2 Channel // ADC_ChannelConfStruct.Channel = ADCx_2_CHANNEL; // ADC_ChannelConfStruct.Rank = ADC_REGULAR_RANK_2; // state = HAL_ADC_ConfigChannel(&ADC_HandleStruct, &ADC_ChannelConfStruct); // if(state != HAL_OK) // while(1) { ; } /* Setup ADC *******************************************************************/ state = HAL_ADCEx_Calibration_Start(&ADC_HandleStruct, ADC_SINGLE_ENDED); if(state != HAL_OK) while(1) { ; } state = HAL_ADC_Start_DMA(&ADC_HandleStruct, (uint32_t *)ADC_DMA_ConvBuf, ADC_BUF_SIZE * ADC_BUF_CHENNAL); if(state != HAL_OK) while(1) { ; } }
uint16_t AdcMcuRead( Adc_t *obj, uint8_t channel ) { ADC_HandleTypeDef *hadc; ADC_ChannelConfTypeDef adcConf; uint16_t adcData = 0; hadc = &obj->Adc; /* Enable HSI */ __HAL_RCC_HSI_ENABLE(); /* Wait till HSI is ready */ while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET) { } __HAL_RCC_ADC1_CLK_ENABLE( ); adcConf.Channel = channel; adcConf.Rank = ADC_REGULAR_RANK_1; adcConf.SamplingTime = ADC_SAMPLETIME_192CYCLES; HAL_ADC_ConfigChannel( hadc, &adcConf); /* Enable ADC1 */ __HAL_ADC_ENABLE( hadc) ; /* Start ADC1 Software Conversion */ HAL_ADC_Start( hadc); HAL_ADC_PollForConversion( hadc, HAL_MAX_DELAY ); adcData = HAL_ADC_GetValue ( hadc); __HAL_ADC_DISABLE( hadc) ; if( ( adcConf.Channel == ADC_CHANNEL_TEMPSENSOR ) || ( adcConf.Channel == ADC_CHANNEL_VREFINT ) ) { HAL_ADC_DeInit( hadc ); } __HAL_RCC_ADC1_CLK_DISABLE( ); /* Disable HSI */ __HAL_RCC_HSI_DISABLE(); return adcData; }
static int adc_suspend(struct soc_device *dev, enum suspend_state_t state) { hal_adc_suspending = 1; switch (state) { case PM_MODE_SLEEP: break; case PM_MODE_STANDBY: case PM_MODE_HIBERNATION: case PM_MODE_POWEROFF: HAL_ADC_DeInit(); break; default: break; } return 0; }
/** \brief 温度控制硬件初始化 * * \return void */ void hw_TemperatureManageInit(void) { ///ADC配置,ADC1,in10,in11,in12,in13 GPIO_InitTypeDef GPIO_InitStruct; TIM_OC_InitTypeDef TIM_InitStruct; ADC_ChannelConfTypeDef sConfig; ADC_HandleStruct.Instance = ADC1; if (HAL_ADC_DeInit(&ADC_HandleStruct) != HAL_OK) { return; } ADC_HandleStruct.Init.ScanConvMode = ADC_SCAN_ENABLE; ADC_HandleStruct.Init.ContinuousConvMode = ENABLE; ADC_HandleStruct.Init.DiscontinuousConvMode = DISABLE; ADC_HandleStruct.Init.DataAlign = ADC_DATAALIGN_RIGHT; ADC_HandleStruct.Init.ExternalTrigConv = ADC_SOFTWARE_START; ADC_HandleStruct.Init.NbrOfConversion = HEATER_COUNT; init_BeforeADC(); HAL_ADC_Init(&ADC_HandleStruct); sConfig.Channel = ADC_CHANNEL_10; ///Channel_Extruder_0 sConfig.Rank = 1; sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5; HAL_ADC_ConfigChannel(&ADC_HandleStruct, &sConfig); #ifdef HEATBED_ENABLED sConfig.Channel = ADC_CHANNEL_11; ///Channel_bed sConfig.Rank = 2; sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5; HAL_ADC_ConfigChannel(&ADC_HandleStruct, &sConfig); #endif #ifdef EXTRUDER_2_ENABLED sConfig.Channel = ADC_CHANNEL_12; ///Channel_Extruder_1 sConfig.Rank = 3; sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5; HAL_ADC_ConfigChannel(&ADC_HandleStruct, &sConfig); #endif #ifdef EXTRUDER_3_ENABLED sConfig.Channel = ADC_CHANNEL_13; ///Channel_Extruder_2 sConfig.Rank = 4; sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5; HAL_ADC_ConfigChannel(&ADC_HandleStruct, &sConfig); #endif HAL_ADCEx_Calibration_Start(&ADC_HandleStruct); ///ADC时钟配置 采样周期100ms __HAL_RCC_TIM6_CLK_ENABLE(); TIM_ADC_HandleStruct.Instance = TIM6; TIM_ADC_HandleStruct.Init.Period = 1000 - 1; TIM_ADC_HandleStruct.Init.Prescaler = (uint32_t) (SystemCoreClock/2/10000) - 1; TIM_ADC_HandleStruct.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; TIM_ADC_HandleStruct.Init.CounterMode = TIM_COUNTERMODE_UP; HAL_TIM_Base_Init(&TIM_ADC_HandleStruct); __HAL_TIM_SET_COUNTER(&TIM_ADC_HandleStruct, 0); HAL_NVIC_SetPriority(TIM6_IRQn, 4, 0); HAL_NVIC_EnableIRQ(TIM6_IRQn); ///加热PWM配置 PB6,7,8,9 __HAL_RCC_GPIOB_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_6; #ifdef HEATBED_ENABLED GPIO_InitStruct.Pin |= GPIO_PIN_7; #endif #ifdef EXTRUDER_2_ENABLED GPIO_InitStruct.Pin |= GPIO_PIN_8; #endif #ifdef EXTRUDER_3_ENABLED GPIO_InitStruct.Pin |= GPIO_PIN_9; #endif GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; ///内部不做上下拉电阻 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); ///PWM时钟配置 __HAL_RCC_TIM4_CLK_ENABLE(); TIM_PWM_HandleStruct.Instance = TIM4; TIM_PWM_HandleStruct.Init.Prescaler = (uint32_t) (SystemCoreClock/2/250000) - 1; TIM_PWM_HandleStruct.Init.Period = 254; ///总共255 TIM_PWM_HandleStruct.Init.ClockDivision = 0; TIM_PWM_HandleStruct.Init.CounterMode = TIM_COUNTERMODE_UP; HAL_TIM_PWM_Init(&TIM_PWM_HandleStruct); TIM_InitStruct.OCMode = TIM_OCMODE_PWM1; TIM_InitStruct.OCPolarity = TIM_OCPOLARITY_HIGH; TIM_InitStruct.OCFastMode = TIM_OCFAST_DISABLE; TIM_InitStruct.Pulse = 0; HAL_TIM_PWM_ConfigChannel(&TIM_PWM_HandleStruct, &TIM_InitStruct, TIM_CHANNEL_1); #ifdef HEATBED_ENABLED HAL_TIM_PWM_ConfigChannel(&TIM_PWM_HandleStruct, &TIM_InitStruct, TIM_CHANNEL_2); #endif #ifdef EXTRUDER_2_ENABLED HAL_TIM_PWM_ConfigChannel(&TIM_PWM_HandleStruct, &TIM_InitStruct, TIM_CHANNEL_3); #endif #ifdef EXTRUDER_3_ENABLED HAL_TIM_PWM_ConfigChannel(&TIM_PWM_HandleStruct, &TIM_InitStruct, TIM_CHANNEL_4); #endif }
/** * @brief Initialize wave recording * @param AudioFreq Audio frequency acquisition. * Note: On STM32L1 evaluation board, the microphone acquisition is * done through an analong amplifier with a band-pass filter * centered at 32kHz. * Therefore, this parameter value should be set at maximum * to 32kHz (value "32000"). * @param BitRes Audio frequency to be configured for the I2S peripheral. * Note: On STM32L1 evaluation board, this parameter is not used, but * kept as parameter for compatibility with other STM32 BSP * drivers. * @param ChnlNbr Audio frequency to be configured for the I2S peripheral. * Note: On STM32L1 evaluation board, this parameter is not used, but * kept as parameter for compatibility with other STM32 BSP * drivers. * @retval AUDIO_OK if correct communication, else wrong communication */ uint8_t BSP_AUDIO_IN_Init(uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr) { /*## Configure the OPAMP ###################################################*/ /* Set OPAMP instance */ hAudioInOpamp.Instance = OPAMP1; /* Configure the OPAMP if not already configured (on the first occurrence */ /* of this function (). */ if(HAL_OPAMP_GetState(&hAudioInOpamp) == HAL_OPAMP_STATE_RESET) { /* Configuration of OPAMP */ hAudioInOpamp.Init.Mode = OPAMP_STANDALONE_MODE; hAudioInOpamp.Init.NonInvertingInput = OPAMP_NONINVERTINGINPUT_IO0; hAudioInOpamp.Init.InvertingInput = OPAMP_INVERTINGINPUT_IO0; hAudioInOpamp.Init.PowerMode = OPAMP_POWERMODE_NORMAL; hAudioInOpamp.Init.PowerSupplyRange = OPAMP_POWERSUPPLY_HIGH; hAudioInOpamp.Init.UserTrimming = OPAMP_TRIMMING_FACTORY; /* Init MSP of OPAMPx */ OPAMPx_MspInit(&hAudioInOpamp); /* Init OPAMPx */ if (HAL_OPAMP_Init(&hAudioInOpamp) != HAL_OK) { return AUDIO_ERROR; } } /* Enable OPAMPx */ if (HAL_OPAMP_Start(&hAudioInOpamp) != HAL_OK) { return AUDIO_ERROR; } /*## Configure the ADC #####################################################*/ /* Set ADC instance */ hAudioInAdc.Instance = ADC1; /* Deinitialize the ADC peripheral registers to its default reset values */ HAL_ADC_DeInit(&hAudioInAdc); /* Configure the ADC */ /* Configuration of ADCx init structure: ADC parameters and regular group */ hAudioInAdc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1; /* ADC clock equal to HSI frequency: 16MHz */ hAudioInAdc.Init.Resolution = ADC_RESOLUTION_12B; hAudioInAdc.Init.DataAlign = ADC_DATAALIGN_RIGHT; hAudioInAdc.Init.ScanConvMode = DISABLE; /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */ hAudioInAdc.Init.EOCSelection = ADC_EOC_SEQ_CONV; hAudioInAdc.Init.LowPowerAutoWait = ADC_AUTOWAIT_DISABLE; hAudioInAdc.Init.LowPowerAutoPowerOff = ADC_AUTOPOWEROFF_DISABLE; hAudioInAdc.Init.ChannelsBank = ADC_CHANNELS_BANK_A; hAudioInAdc.Init.ContinuousConvMode = DISABLE; /* Continuous mode disabled to have only 1 conversion at each ADC external event trig */ hAudioInAdc.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T3_TRGO; /* Trig of conversion start done by external event */ hAudioInAdc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING; hAudioInAdc.Init.DMAContinuousRequests = ENABLE; /* Init MSP of ADCx */ ADCx_MspInit(&hAudioInAdc); /* Init ADCx */ if (HAL_ADC_Init(&hAudioInAdc) != HAL_OK) { return AUDIO_ERROR; } /* Configuration of channel on ADCx regular group on rank 1 */ hAudioInConfigAdc.Channel = AUDIO_IN_ADC_CHANNEL; hAudioInConfigAdc.SamplingTime = ADC_SAMPLETIME_384CYCLES; /* With ADC frequency of 16MHz, conversion time will be 24.75us. This is compliant with sampling time of 32kHz (31.25us) or below */ hAudioInConfigAdc.Rank = ADC_REGULAR_RANK_1; HAL_ADC_ConfigChannel(&hAudioInAdc, &hAudioInConfigAdc); /*## Configure the Timer ###################################################*/ /* Set TIM3 period to AudioFreq using system clock 32Mhz */ hAudioInTim3.Instance = TIM3; hAudioInTim3.Init.Period = (HAL_RCC_GetPCLK1Freq() / (AudioFreq)) -1; hAudioInTim3.Init.Prescaler = 0; hAudioInTim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; hAudioInTim3.Init.CounterMode = TIM_COUNTERMODE_UP; /* Init MSP of TIMx */ TIMx_Base_MspInit(&hAudioInTim3); /* Init TIMx time base */ HAL_TIM_Base_Init(&hAudioInTim3); /* Return 0 if all operations are OK */ return AUDIO_OK; }
/** * @brief Main program. * @param None * @retval None */ int main(void) { ADC_ChannelConfTypeDef sConfig; /* STM32F4xx HAL library initialization: - Configure the Flash prefetch, instruction and Data caches - Systick timer is configured by default as source of time base, but user can eventually implement his proper time base source (a general purpose timer for example or other time source), keeping in mind that Time base duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and handled in milliseconds basis. - Set NVIC Group Priority to 4 - Low Level Initialization: global MSP (MCU Support Package) initialization */ HAL_Init(); /* Configure the system clock to 180 MHz */ SystemClock_Config(); /* Configure LED3 */ BSP_LED_Init(LED3); /*##-1- Configure the ADC peripheral #######################################*/ AdcHandle.Instance = ADCx; if (HAL_ADC_DeInit(&AdcHandle) != HAL_OK) { /* ADC de-initialization Error */ Error_Handler(); } AdcHandle.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV4; /* Asynchronous clock mode, input ADC clock not divided */ AdcHandle.Init.Resolution = ADC_RESOLUTION_12B; /* 12-bit resolution for converted data */ AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT; /* Right-alignment for converted data */ AdcHandle.Init.ScanConvMode = DISABLE; /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */ AdcHandle.Init.EOCSelection = DISABLE; /* EOC flag picked-up to indicate conversion end */ AdcHandle.Init.ContinuousConvMode = DISABLE; /* Continuous mode disabled to have only 1 conversion at each conversion trig */ AdcHandle.Init.NbrOfConversion = 1; /* Parameter discarded because sequencer is disabled */ AdcHandle.Init.DiscontinuousConvMode = DISABLE; /* Parameter discarded because sequencer is disabled */ AdcHandle.Init.NbrOfDiscConversion = 0; /* Parameter discarded because sequencer is disabled */ AdcHandle.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1; /* Software start to trig the 1st conversion manually, without external event */ AdcHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; /* Parameter discarded because software trigger chosen */ AdcHandle.Init.DMAContinuousRequests = DISABLE; /* DMA one-shot mode selected (not applied to this example) */ if (HAL_ADC_Init(&AdcHandle) != HAL_OK) { /* ADC initialization Error */ Error_Handler(); } /*##-2- Configure ADC regular channel ######################################*/ sConfig.Channel = ADCx_CHANNEL; /* Sampled channel number */ sConfig.Rank = 1; /* Rank of sampled channel number ADCx_CHANNEL */ sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES; /* Sampling time (number of clock cycles unit) */ sConfig.Offset = 0; /* Parameter discarded because offset correction is disabled */ if (HAL_ADC_ConfigChannel(&AdcHandle, &sConfig) != HAL_OK) { /* Channel Configuration Error */ Error_Handler(); } /*##-3- Start the conversion process #######################################*/ if (HAL_ADC_Start(&AdcHandle) != HAL_OK) { /* Start Conversation Error */ Error_Handler(); } /*##-4- Wait for the end of conversion #####################################*/ /* Before starting a new conversion, you need to check the current state of the peripheral; if it’s busy you need to wait for the end of current conversion before starting a new one. For simplicity reasons, this example is just waiting till the end of the conversion, but application may perform other tasks while conversion operation is ongoing. */ if (HAL_ADC_PollForConversion(&AdcHandle, 10) != HAL_OK) { /* End Of Conversion flag not set on time */ Error_Handler(); } /* Check if the continuous conversion of regular channel is finished */ if ((HAL_ADC_GetState(&AdcHandle) & HAL_ADC_STATE_EOC_REG) == HAL_ADC_STATE_EOC_REG) { /*##-5- Get the converted value of regular channel ########################*/ uhADCxConvertedValue = HAL_ADC_GetValue(&AdcHandle); } /* Infinite loop */ while (1) { } }
/** * @brief Main program. * @param None * @retval None */ int main(void) { /* This sample code shows how to convert an analog input and read the converted data using DMA transfer. To proceed, 4 steps are required: */ /* STM32F3xx HAL library initialization: - Configure the Flash prefetch - Configure the Systick to generate an interrupt each 1 msec - Set NVIC Group Priority to 4 - Low Level Initialization */ HAL_Init(); /* Configure the system clock to 64 MHz */ SystemClock_Config(); /* Configure LED3 */ BSP_LED_Init(LED3); /* ### - 1 - Initialize ADC peripheral #################################### */ AdcHandle.Instance = ADCx; if (HAL_ADC_DeInit(&AdcHandle) != HAL_OK) { /* ADC de-initialization Error */ Error_Handler(); } AdcHandle.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2; /* Synchronous clock mode, input ADC clock divided by 2*/ AdcHandle.Init.Resolution = ADC_RESOLUTION_12B; /* 12-bit resolution for converted data */ AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT; /* Right-alignment for converted data */ AdcHandle.Init.ScanConvMode = DISABLE; /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */ AdcHandle.Init.EOCSelection = ADC_EOC_SINGLE_CONV; /* EOC flag picked-up to indicate conversion end */ AdcHandle.Init.LowPowerAutoWait = DISABLE; /* Auto-delayed conversion feature disabled */ AdcHandle.Init.ContinuousConvMode = ENABLE; /* Continuous mode enabled (automatic conversion restart after each conversion) */ AdcHandle.Init.NbrOfConversion = 1; /* Parameter discarded because sequencer is disabled */ AdcHandle.Init.DiscontinuousConvMode = DISABLE; /* Parameter discarded because sequencer is disabled */ AdcHandle.Init.NbrOfDiscConversion = 1; /* Parameter discarded because sequencer is disabled */ AdcHandle.Init.ExternalTrigConv = ADC_SOFTWARE_START; /* Software start to trig the 1st conversion manually, without external event */ AdcHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; /* Parameter discarded because software trigger chosen */ AdcHandle.Init.DMAContinuousRequests = ENABLE; /* ADC DMA continuous request to match with DMA circular mode */ AdcHandle.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; /* DR register is overwritten with the last conversion result in case of overrun */ /* Initialize ADC peripheral according to the passed parameters */ if (HAL_ADC_Init(&AdcHandle) != HAL_OK) { Error_Handler(); } /* ### - 2 - Start calibration ############################################ */ if (HAL_ADCEx_Calibration_Start(&AdcHandle, ADC_SINGLE_ENDED) != HAL_OK) { Error_Handler(); } /* ### - 3 - Channel configuration ######################################## */ sConfig.Channel = ADCx_CHANNEL; /* Sampled channel number */ sConfig.Rank = ADC_REGULAR_RANK_1; /* Rank of sampled channel number ADCx_CHANNEL */ sConfig.SamplingTime = ADC_SAMPLETIME_61CYCLES_5; /* Sampling time (number of clock cycles unit) */ sConfig.SingleDiff = ADC_SINGLE_ENDED; /* Single-ended input channel */ sConfig.OffsetNumber = ADC_OFFSET_NONE; /* No offset subtraction */ sConfig.Offset = 0; /* Parameter discarded because offset correction is disabled */ if (HAL_ADC_ConfigChannel(&AdcHandle, &sConfig) != HAL_OK) { Error_Handler(); } /* ### - 4 - Start conversion in DMA mode ################################# */ if (HAL_ADC_Start_DMA(&AdcHandle, (uint32_t *)aADCxConvertedData, ADC_CONVERTED_DATA_BUFFER_SIZE ) != HAL_OK) { Error_Handler(); } /* Infinite Loop */ while (1) { } }
void uni_adc_init(void) { ADC_ChannelConfTypeDef sConfig; //------------------------------------- HAL_DMA_DeInit(hadc1.DMA_Handle); HAL_ADC_DeInit(&hadc1); //------------------------------------- // Configure the global features of the ADC // (Clock, Resolution, Data Alignment and number of conversion) hadc1.Instance = ADC1; hadc1.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV4; hadc1.Init.Resolution = ADC_RESOLUTION12b; hadc1.Init.ScanConvMode = ENABLE; hadc1.Init.ContinuousConvMode = ENABLE; hadc1.Init.DiscontinuousConvMode = DISABLE; hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc1.Init.NbrOfConversion = 16; hadc1.Init.DMAContinuousRequests = ENABLE; hadc1.Init.EOCSelection = EOC_SINGLE_CONV; hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; #ifdef CIRCULAR_DMA // circular buffer with HAL_ADC_ConvCpltCallback() // and (if not disabled) HAL_ADC_ConvHalfCpltCallback() // Note: set hdma_adc1.Init.Mode = DMA_CIRCULAR; in adc.c hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1; // dummy value #else // one buffer sample with HAL_ADC_ConvCpltCallback() // Note: set hdma_adc1.Init.Mode = DMA_NORMAL; in adc.c hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; #endif HAL_ADC_Init(&hadc1); sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES; /**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; HAL_ADC_ConfigChannel(&hadc1, &sConfig); /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */ //sConfig.Channel = ADC_CHANNEL_TEMPSENSOR; //sConfig.Channel = ADC_CHANNEL_VBAT; sConfig.Channel = ADC_CHANNEL_1; sConfig.Rank = 2; HAL_ADC_ConfigChannel(&hadc1, &sConfig); /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */ //sConfig.Channel = ADC_CHANNEL_VREFINT; sConfig.Channel = ADC_CHANNEL_2; sConfig.Rank = 3; HAL_ADC_ConfigChannel(&hadc1, &sConfig); /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */ sConfig.Channel = ADC_CHANNEL_3; sConfig.Rank = 4; HAL_ADC_ConfigChannel(&hadc1, &sConfig); /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */ sConfig.Channel = ADC_CHANNEL_4; sConfig.Rank = 5; HAL_ADC_ConfigChannel(&hadc1, &sConfig); /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */ sConfig.Channel = ADC_CHANNEL_5; sConfig.Rank = 6; HAL_ADC_ConfigChannel(&hadc1, &sConfig); /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */ sConfig.Channel = ADC_CHANNEL_6; sConfig.Rank = 7; HAL_ADC_ConfigChannel(&hadc1, &sConfig); /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */ sConfig.Channel = ADC_CHANNEL_7; sConfig.Rank = 8; HAL_ADC_ConfigChannel(&hadc1, &sConfig); /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */ sConfig.Channel = ADC_CHANNEL_8; sConfig.Rank = 9; HAL_ADC_ConfigChannel(&hadc1, &sConfig); /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */ sConfig.Channel = ADC_CHANNEL_9; sConfig.Rank = 10; HAL_ADC_ConfigChannel(&hadc1, &sConfig); /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */ sConfig.Channel = ADC_CHANNEL_10; sConfig.Rank = 11; HAL_ADC_ConfigChannel(&hadc1, &sConfig); /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */ sConfig.Channel = ADC_CHANNEL_11; sConfig.Rank = 12; HAL_ADC_ConfigChannel(&hadc1, &sConfig); /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */ sConfig.Channel = ADC_CHANNEL_12; sConfig.Rank = 13; HAL_ADC_ConfigChannel(&hadc1, &sConfig); /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */ sConfig.Channel = ADC_CHANNEL_13; sConfig.Rank = 14; HAL_ADC_ConfigChannel(&hadc1, &sConfig); /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */ sConfig.Channel = ADC_CHANNEL_14; sConfig.Rank = 15; HAL_ADC_ConfigChannel(&hadc1, &sConfig); /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */ sConfig.Channel = ADC_CHANNEL_15; sConfig.Rank = 16; HAL_ADC_ConfigChannel(&hadc1, &sConfig); }
/** * @brief Main program. * @param None * @retval None */ int main(void) { /* This sample code shows how to convert an analog input and read the converted data using DMA transfer. To proceed, 4 steps are required: */ /* STM32L0xx HAL library initialization: - Configure the Flash prefetch, Flash preread and Buffer caches - Systick timer is configured by default as source of time base, but user can eventually implement his proper time base source (a general purpose timer for example or other time source), keeping in mind that Time base duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and handled in milliseconds basis. - Low Level Initialization */ HAL_Init(); /* Configure the system clock to 2 MHz */ SystemClock_Config(); /* Configure LED2 */ BSP_LED_Init(LED2); /* ### - 1 - Initialize ADC peripheral #################################### */ AdcHandle.Instance = ADCx; if (HAL_ADC_DeInit(&AdcHandle) != HAL_OK) { /* ADC de-initialization Error */ Error_Handler(); } AdcHandle.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2; /* Synchronous clock mode, input ADC clock with prscaler 2 */ AdcHandle.Init.Resolution = ADC_RESOLUTION_12B; /* 12-bit resolution for converted data */ AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT; /* Right-alignment for converted data */ AdcHandle.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD; /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */ AdcHandle.Init.EOCSelection = ADC_EOC_SINGLE_CONV; /* EOC flag picked-up to indicate conversion end */ AdcHandle.Init.LowPowerAutoPowerOff = DISABLE; AdcHandle.Init.LowPowerFrequencyMode = DISABLE; AdcHandle.Init.LowPowerAutoWait = DISABLE; /* Auto-delayed conversion feature disabled */ AdcHandle.Init.ContinuousConvMode = ENABLE; /* Continuous mode enabled (automatic conversion restart after each conversion) */ AdcHandle.Init.DiscontinuousConvMode = DISABLE; /* Parameter discarded because sequencer is disabled */ AdcHandle.Init.ExternalTrigConv = ADC_SOFTWARE_START; /* Software start to trig the 1st conversion manually, without external event */ AdcHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; /* Parameter discarded because software trigger chosen */ AdcHandle.Init.DMAContinuousRequests = ENABLE; /* ADC DMA continuous request to match with DMA circular mode */ AdcHandle.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; /* DR register is overwritten with the last conversion result in case of overrun */ AdcHandle.Init.OversamplingMode = DISABLE; /* No oversampling */ AdcHandle.Init.SamplingTime = ADC_SAMPLETIME_7CYCLES_5; /* Initialize ADC peripheral according to the passed parameters */ if (HAL_ADC_Init(&AdcHandle) != HAL_OK) { Error_Handler(); } /* ### - 2 - Start calibration ############################################ */ if (HAL_ADCEx_Calibration_Start(&AdcHandle, ADC_SINGLE_ENDED) != HAL_OK) { Error_Handler(); } /* ### - 3 - Channel configuration ######################################## */ sConfig.Channel = ADCx_CHANNEL; /* Channel to be converted */ sConfig.Rank = ADC_RANK_CHANNEL_NUMBER; if (HAL_ADC_ConfigChannel(&AdcHandle, &sConfig) != HAL_OK) { Error_Handler(); } /* ### - 4 - Start conversion in DMA mode ################################# */ if (HAL_ADC_Start_DMA(&AdcHandle, (uint32_t *)aADCxConvertedData, ADC_CONVERTED_DATA_BUFFER_SIZE ) != HAL_OK) { Error_Handler(); } /* Infinite Loop */ while (1) { } }
/** * @brief ADC configuration * @param None * @retval None */ static void ADC_Config(void) { ADC_ChannelConfTypeDef sConfig; /* Configuration of ADCx init structure: ADC parameters and regular group */ AdcHandle.Instance = ADCx; if (HAL_ADC_DeInit(&AdcHandle) != HAL_OK) { /* ADC initialization error */ Error_Handler(); } AdcHandle.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1; /* Asynchronous clock mode, input ADC clock not divided */ AdcHandle.Init.Resolution = ADC_RESOLUTION_12B; /* 12-bit resolution for converted data */ AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT; /* Right-alignment for converted data */ AdcHandle.Init.ScanConvMode = ENABLE; /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */ AdcHandle.Init.EOCSelection = ADC_EOC_SINGLE_CONV; /* EOC flag picked-up to indicate conversion end */ AdcHandle.Init.LowPowerAutoWait = DISABLE; /* Auto-delayed conversion feature disabled */ AdcHandle.Init.ContinuousConvMode = DISABLE; /* Continuous mode disabled to have only 1 conversion at each conversion trig */ AdcHandle.Init.NbrOfConversion = 3; /* Parameter discarded because sequencer is disabled */ AdcHandle.Init.DiscontinuousConvMode = ENABLE; /* Parameter discarded because sequencer is disabled */ AdcHandle.Init.NbrOfDiscConversion = 1; /* Parameter discarded because sequencer is disabled */ AdcHandle.Init.ExternalTrigConv = ADC_SOFTWARE_START; /* Software start to trigger the 1st conversion manually, without external event */ AdcHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; /* Parameter discarded because trigger of conversion by software start (no external event) */ AdcHandle.Init.DMAContinuousRequests = ENABLE; /* DMA circular mode selected */ AdcHandle.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; /* DR register is overwritten with the last conversion result in case of overrun */ AdcHandle.Init.OversamplingMode = DISABLE; /* No oversampling */ if (HAL_ADC_Init(&AdcHandle) != HAL_OK) { /* ADC initialization error */ Error_Handler(); } /* Configuration of channel on ADCx regular group on sequencer rank 1 */ /* Note: Considering IT occurring after each ADC conversion (IT by DMA end */ /* of transfer), select sampling time and ADC clock with sufficient */ /* duration to not create an overhead situation in IRQHandler. */ /* Note: Set long sampling time due to internal channels (VrefInt, */ /* temperature sensor) constraints. */ sConfig.Channel = ADCx_CHANNELa; /* Sampled channel number */ sConfig.Rank = ADC_REGULAR_RANK_1; /* Rank of sampled channel number ADCx_CHANNEL */ sConfig.SamplingTime = ADC_SAMPLETIME_247CYCLES_5; /* Minimum sampling time */ sConfig.SingleDiff = ADC_SINGLE_ENDED; /* Single-ended input channel */ sConfig.OffsetNumber = ADC_OFFSET_NONE; /* No offset subtraction */ sConfig.Offset = 0; /* Parameter discarded because offset correction is disabled */ if (HAL_ADC_ConfigChannel(&AdcHandle, &sConfig) != HAL_OK) { /* Channel Configuration Error */ Error_Handler(); } /* Configuration of channel on ADCx regular group on sequencer rank 2 */ /* Replicate previous rank settings, change only channel and rank */ sConfig.Channel = ADC_CHANNEL_TEMPSENSOR; sConfig.Rank = ADC_REGULAR_RANK_2; if (HAL_ADC_ConfigChannel(&AdcHandle, &sConfig) != HAL_OK) { /* Channel Configuration Error */ Error_Handler(); } /* Configuration of channel on ADCx regular group on sequencer rank 3 */ /* Replicate previous rank settings, change only channel and rank */ sConfig.Channel = ADC_CHANNEL_VREFINT; sConfig.Rank = ADC_REGULAR_RANK_3; if (HAL_ADC_ConfigChannel(&AdcHandle, &sConfig) != HAL_OK) { /* Channel Configuration Error */ Error_Handler(); } }
/** * @brief This function will set the ADC to the required value * @param pin : the pin to use * @retval the value of the adc */ uint16_t adc_read_value(PinName pin) { ADC_HandleTypeDef AdcHandle = {}; ADC_ChannelConfTypeDef AdcChannelConf = {}; __IO uint16_t uhADCxConvertedValue = 0; AdcHandle.Instance = pinmap_peripheral(pin, PinMap_ADC); if (AdcHandle.Instance == NP) return 0; #ifndef STM32F1xx AdcHandle.Init.ClockPrescaler = ADC_CLOCK_DIV; /* Asynchronous clock mode, input ADC clock divided */ AdcHandle.Init.Resolution = ADC_RESOLUTION_12B; /* 12-bit resolution for converted data */ AdcHandle.Init.EOCSelection = ADC_EOC_SINGLE_CONV; /* EOC flag picked-up to indicate conversion end */ AdcHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; /* Parameter discarded because software trigger chosen */ AdcHandle.Init.DMAContinuousRequests = DISABLE; /* DMA one-shot mode selected (not applied to this example) */ #endif AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT; /* Right-alignment for converted data */ AdcHandle.Init.ScanConvMode = DISABLE; /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */ AdcHandle.Init.ContinuousConvMode = DISABLE; /* Continuous mode disabled to have only 1 conversion at each conversion trig */ AdcHandle.Init.DiscontinuousConvMode = DISABLE; /* Parameter discarded because sequencer is disabled */ AdcHandle.Init.ExternalTrigConv = ADC_SOFTWARE_START; /* Software start to trig the 1st conversion manually, without external event */ AdcHandle.State = HAL_ADC_STATE_RESET; #if defined (STM32F0xx) || defined (STM32L0xx) AdcHandle.Init.LowPowerAutoWait = DISABLE; /* Auto-delayed conversion feature disabled */ AdcHandle.Init.LowPowerAutoPowerOff = DISABLE; /* ADC automatically powers-off after a conversion and automatically wakes-up when a new conversion is triggered */ AdcHandle.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; /* DR register is overwritten with the last conversion result in case of overrun */ #ifdef STM32F0xx AdcHandle.Init.SamplingTimeCommon = SAMPLINGTIME; #else // STM32L0 //LowPowerFrequencyMode to enable if clk freq < 2.8Mhz AdcHandle.Init.SamplingTime = SAMPLINGTIME; #endif #else #ifdef STM32F3xx AdcHandle.Init.LowPowerAutoWait = DISABLE; /* Auto-delayed conversion feature disabled */ #endif AdcHandle.Init.NbrOfConversion = 1; /* Specifies the number of ranks that will be converted within the regular group sequencer. */ AdcHandle.Init.NbrOfDiscConversion = 0; /* Parameter discarded because sequencer is disabled */ #endif g_current_pin = pin; /* Needed for HAL_ADC_MspInit*/ if (HAL_ADC_Init(&AdcHandle) != HAL_OK) { return 0; } AdcChannelConf.Channel = get_adc_channel(pin); /* Specifies the channel to configure into ADC */ #ifdef STM32L4xx if (!IS_ADC_CHANNEL(&AdcHandle, AdcChannelConf.Channel)) return 0; #else if (!IS_ADC_CHANNEL(AdcChannelConf.Channel)) return 0; #endif AdcChannelConf.Rank = ADC_REGULAR_RANK_1; /* Specifies the rank in the regular group sequencer */ #ifndef STM32L0xx AdcChannelConf.SamplingTime = SAMPLINGTIME; /* Sampling time value to be set for the selected channel */ #endif #if defined (STM32F3xx) || defined (STM32L4xx) AdcChannelConf.SingleDiff = ADC_SINGLE_ENDED; /* Single-ended input channel */ AdcChannelConf.OffsetNumber = ADC_OFFSET_NONE; /* No offset subtraction */ AdcChannelConf.Offset = 0; /* Parameter discarded because offset correction is disabled */ #endif /*##-2- Configure ADC regular channel ######################################*/ if (HAL_ADC_ConfigChannel(&AdcHandle, &AdcChannelConf) != HAL_OK) { /* Channel Configuration Error */ return 0; } #if defined (STM32F0xx) || defined (STM32F1xx) || defined (STM32F3xx) || defined (STM32L0xx) || defined (STM32L4xx) /*##-2.1- Calibrate ADC then Start the conversion process ####################*/ #if defined (STM32F0xx) || defined (STM32F1xx) if (HAL_ADCEx_Calibration_Start(&AdcHandle) != HAL_OK) #else if (HAL_ADCEx_Calibration_Start(&AdcHandle, ADC_SINGLE_ENDED) != HAL_OK) #endif { /* ADC Calibration Error */ return 0; } #endif /*##-3- Start the conversion process ####################*/ if (HAL_ADC_Start(&AdcHandle) != HAL_OK) { /* Start Conversation Error */ return 0; } /*##-4- Wait for the end of conversion #####################################*/ /* For simplicity reasons, this example is just waiting till the end of the conversion, but application may perform other tasks while conversion operation is ongoing. */ if (HAL_ADC_PollForConversion(&AdcHandle, 10) != HAL_OK) { /* End Of Conversion flag not set on time */ return 0; } /* Check if the continous conversion of regular channel is finished */ if ((HAL_ADC_GetState(&AdcHandle) & HAL_ADC_STATE_REG_EOC) == HAL_ADC_STATE_REG_EOC) { /*##-5- Get the converted value of regular channel ########################*/ uhADCxConvertedValue = HAL_ADC_GetValue(&AdcHandle); } if (HAL_ADC_Stop(&AdcHandle) != HAL_OK) { /* Stop Conversation Error */ return 0; } if(HAL_ADC_DeInit(&AdcHandle) != HAL_OK) { return 0; } return uhADCxConvertedValue; }