https://blog.csdn.net/mygod2008ok/article/details/106751919
#include "BSP_adc.h"
#include "BSP_delay.h"
#include "stm_log.h"
/* Definition of ADCx conversions data table size */
#define ADC_CONVERTED_DATA_BUFFER_SIZE ((uint32_t) 6) /* Size of array aADCxConvertedData[] */
/* ADC handle declaration */
ADC_HandleTypeDef AdcHandle;
/* ADC channel configuration structure declaration */
ADC_ChannelConfTypeDef sConfig;
/* Variable containing ADC conversions data */
static uint16_t aADCxConvertedData[ADC_CONVERTED_DATA_BUFFER_SIZE];
static uint8_t s_adc_count;
/**
* @brief ADC MSP Init
* @param hadc : ADC handle
* @retval None
*/
void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)
{
GPIO_InitTypeDef GPIO_InitStruct;
static DMA_HandleTypeDef DmaHandle;
/*##-1- Enable peripherals and GPIO Clocks #################################*/
/* Enable GPIO clock ****************************************/
__HAL_RCC_GPIOA_CLK_ENABLE();
/* ADC1 Periph clock enable */
ADCx_CLK_ENABLE();
/* Enable DMA1 clock */
__HAL_RCC_DMA1_CLK_ENABLE();
/*##- 2- Configure peripheral GPIO #########################################*/
/* ADC Channel GPIO pin configuration */
GPIO_InitStruct.Pin = ADCx_CHANNEL_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(ADCx_CHANNEL_GPIO_PORT, &GPIO_InitStruct);
/*##- 3- Configure DMA #####################################################*/
/*********************** Configure DMA parameters ***************************/
DmaHandle.Instance = DMA1_Channel1;
DmaHandle.Init.Direction = DMA_PERIPH_TO_MEMORY;
DmaHandle.Init.PeriphInc = DMA_PINC_DISABLE;
DmaHandle.Init.MemInc = DMA_MINC_ENABLE;
DmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
DmaHandle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
DmaHandle.Init.Mode = DMA_CIRCULAR;
DmaHandle.Init.Priority = DMA_PRIORITY_MEDIUM;
/* Deinitialize & Initialize the DMA for new transfer */
HAL_DMA_DeInit(&DmaHandle);
HAL_DMA_Init(&DmaHandle);
/* Associate the DMA handle */
__HAL_LINKDMA(hadc, DMA_Handle, DmaHandle);
/* NVIC configuration for DMA Input data interrupt */
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}
/**
* @brief ADC MSP De-Initialization
* This function frees the hardware resources used in this example:
* - Disable the Peripheral's clock
* - Revert GPIO to their default state
* @param hadc: ADC handle pointer
* @retval None
*/
void HAL_ADC_MspDeInit(ADC_HandleTypeDef *hadc)
{
/*##-1- Reset peripherals ##################################################*/
ADCx_FORCE_RESET();
ADCx_RELEASE_RESET();
/* ADC Periph clock disable
(automatically reset all ADC instances of the ADC common group) */
__HAL_RCC_ADC1_CLK_DISABLE();
/*##-2- Disable peripherals and GPIO Clocks ################################*/
/* De-initialize the ADC Channel GPIO pin */
HAL_GPIO_DeInit(ADCx_CHANNEL_GPIO_PORT, ADCx_CHANNEL_PIN);
}
//-----------------获取ADC值----------------------------------
static int16_t get_adc_value(void)
{
int32_t mvolts;
int16_t max,min;
mvolts = 0;
max = aADCxConvertedData[0];
min = aADCxConvertedData[0];
for(uint8_t i=0; i= max)
max = aADCxConvertedData[i];
if(aADCxConvertedData[i] <= min)
min = aADCxConvertedData[i];
}
mvolts = mvolts-max-min; //去掉最大,最小值
mvolts /= (ADC_CONVERTED_DATA_BUFFER_SIZE-2);
return (int16_t)mvolts;
}
/**
* @brief adc初时化
*/
void BSP_adc_init(void)
{
AdcHandle.Instance = ADCx;
HAL_StatusTypeDef err_code = HAL_ADC_DeInit(&AdcHandle);
APP_ERROR_CHECK(err_code);
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.LowPowerAutoWait = DISABLE; /* Auto-delayed conversion feature disabled */
AdcHandle.Init.ContinuousConvMode = DISABLE;//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 = DISABLE;//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.SamplingTimeCommon = ADC_SAMPLETIME_1CYCLE_5;
/* Initialize ADC peripheral according to the passed parameters */
err_code = HAL_ADC_Init(&AdcHandle);
APP_ERROR_CHECK(err_code);
/* ### - 2 - Start calibration ############################################ */
err_code = HAL_ADCEx_Calibration_Start(&AdcHandle);
APP_ERROR_CHECK(err_code);
/* ### - 3 - Channel configuration ######################################## */
sConfig.Channel = ADCx_CHANNEL; /* Channel to be converted */
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
err_code = HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);
APP_ERROR_CHECK(err_code);
/* ### - 4 - Start conversion in DMA mode ################################# */
// err_code = HAL_ADC_Start_DMA(&AdcHandle,
// (uint32_t *)aADCxConvertedData,
// ADC_CONVERTED_DATA_BUFFER_SIZE
// );
// APP_ERROR_CHECK(err_code);
}
/**
* @brief adc反初时化
*/
void BSP_adc_deinit()
{
HAL_ADC_DeInit(&AdcHandle);
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Pin = GPIO_PIN_0;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
/**
* @brief 启动转换
*/
void BSP_start_adc_count(uint8_t count)
{
if(s_adc_count == 0)
{
s_adc_count = count;
}
}
//-----------------------电池电量测量在此函数触发,由2秒调用------------------------------------------------------------------
void batteryMessurePeroid(void)
{
static uint8_t s_batt_cnt = 0;
if(s_adc_count)
return;
if(++s_batt_cnt >= MESSURE_BATTERY_PERIOD)
{
s_batt_cnt = 0;
BSP_start_adc_count(1);
}
}
/**
* @brief ADC转换处理
*/
void BSP_adc_convert_handler(void)
{
if(s_adc_count)
{
HAL_StatusTypeDef err_code = HAL_ADC_Start_DMA(&AdcHandle,
(uint32_t *)aADCxConvertedData,
ADC_CONVERTED_DATA_BUFFER_SIZE
);
APP_ERROR_CHECK(err_code);
if(--s_adc_count == 0)
{
int16_t adc = get_adc_value();
NRF_LOG_INFO("ADC=%d",adc);
}
}
}
#ifndef __BSP_ADC_H_
#define __BSP_ADC_H_
#include "main.h"
#include
#include
#ifdef __cplusplus
extern "C" {
#endif
//#include "stm32f0xx_nucleo.h"
/* Definition for ADCx clock resources */
#define ADCx ADC1
#define ADCx_CLK_ENABLE() __HAL_RCC_ADC1_CLK_ENABLE()
#define ADCx_CHANNEL_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
#define DMAx_CHANNELx_CLK_ENABLE() __HAL_RCC_DMA1_CLK_ENABLE()
#define ADCx_FORCE_RESET() __HAL_RCC_ADC1_FORCE_RESET()
#define ADCx_RELEASE_RESET() __HAL_RCC_ADC1_RELEASE_RESET()
/* Definition for ADCx Channel Pin */
#define ADCx_CHANNEL_PIN_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
#define ADCx_CHANNEL_PIN GPIO_PIN_0
#define ADCx_CHANNEL_GPIO_PORT GPIOA
/* Definition for ADCx's Channel */
#define ADCx_CHANNEL ADC_CHANNEL_0
#define MESSURE_BATTERY_PERIOD 3
extern ADC_HandleTypeDef AdcHandle;
void batteryMessurePeroid(void);
void BSP_adc_init(void);
void BSP_adc_deinit(void);
void BSP_start_adc_count(uint8_t count);
void BSP_adc_convert_handler(void);
#ifdef __cplusplus
}
#endif
#endif
/**
* @brief This function handles DMA1_Channel1_IRQHandler interrupt request.
* @param None
* @retval None
*/
void DMA1_Channel1_IRQHandler(void)
{
HAL_DMA_IRQHandler(AdcHandle.DMA_Handle);
}
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
RTT_INIT();
HAL_Init();
SystemClock_Config();
BSP_adc_init();
BSP_wdt_init(5000);
delay_init();
MX_RTC_Init();
BSP_start_adc_count(8);
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
if(s_wakeup_flag) //任务处理模式
{
BSP_wdt_feed();
tick_25hz_handler();
tick_1hz_handler();
}
else // 省电模式
{
}
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* @brief 25Hz handler
*
*/
static void tick_25hz_handler(void)
{
if((s_wakeup_flag & TICK_FOR_25HZ) == 0)
return;
s_wakeup_flag &= CLEAR_TICK_FOR_25HZ;
//####################################################################################
//---------TODO this to add 25hz event handler-----------
BSP_adc_convert_handler();
}
/**
* @brief 1Hz handler
*
*/
static void tick_1hz_handler(void)
{
if((s_wakeup_flag & TICK_FOR_1HZ) == 0)
return;
s_wakeup_flag &= CLEAR_TICK_FOR_1HZ;
//####################################################################################
//---------TODO this to add 1hz event handler-----------
start_cali_rtc();
batteryMessurePeroid(); //电池测量
}