171 lines
6.1 KiB
C
Raw Permalink Normal View History

2021-09-28 14:26:28 +08:00
//ADC <20><>
#include "sys.h"
#include "tim.h"
#include "adc.h"
//32 <20>ֽڶ<D6BD><DAB6><EFBFBD>
ALIGN_32BYTES(uint16_t __attribute__((section(".RAM_D3"))) ADCxValues[2]);
/**
* @brief ADC <EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
void ADC_Init(void)
{
ADC_HandleTypeDef AdcHandle = {0};
DMA_HandleTypeDef DMA_Handle = {0};
ADC_ChannelConfTypeDef sConfig = {0};
GPIO_InitTypeDef GPIO_InitStruct;
//<2F><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_ADC;
PeriphClkInitStruct.PLL2.PLL2M = 25;
PeriphClkInitStruct.PLL2.PLL2N = 504;
PeriphClkInitStruct.PLL2.PLL2P = 7;
PeriphClkInitStruct.PLL2.PLL2Q = 7;
PeriphClkInitStruct.PLL2.PLL2R = 7;
PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_0;
PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE;
PeriphClkInitStruct.PLL2.PLL2FRACN = 0;
PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_PLL2;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
//GPIO
__HAL_RCC_GPIOC_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
//DMA
__HAL_RCC_DMA1_CLK_ENABLE();
DMA_Handle.Instance = DMA1_Stream1; //ʹ<>õ<EFBFBD>DMA1 Stream1
DMA_Handle.Init.Request = DMA_REQUEST_ADC3; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͳ<EFBFBD><CDB2><EFBFBD> DMA_REQUEST_ADC3
DMA_Handle.Init.Direction = DMA_PERIPH_TO_MEMORY; //<2F><><EFBFBD><EFBFBD><E4B7BD><EFBFBD>ǴӴ洢<D3B4><E6B4A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
DMA_Handle.Init.PeriphInc = DMA_PINC_DISABLE; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֹ
DMA_Handle.Init.MemInc = DMA_MINC_ENABLE; //<2F><EFBFBD><E6B4A2><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>
DMA_Handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݴ<EFBFBD><DDB4><EFBFBD>λ<EFBFBD><CEBB>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD><EFBFBD>֣<EFBFBD><D6A3><EFBFBD> 16bit
DMA_Handle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; //<2F><EFBFBD><E6B4A2><EFBFBD><EFBFBD><EFBFBD>ݴ<EFBFBD><DDB4><EFBFBD>λ<EFBFBD><CEBB>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD><EFBFBD>֣<EFBFBD><D6A3><EFBFBD> 16bit
DMA_Handle.Init.Mode = DMA_CIRCULAR; //ѭ<><D1AD>ģʽ
DMA_Handle.Init.Priority = DMA_PRIORITY_LOW; //<2F><><EFBFBD>ȼ<EFBFBD><C8BC><EFBFBD>
DMA_Handle.Init.FIFOMode = DMA_FIFOMODE_DISABLE; //<2F><>ֹ FIFO
DMA_Handle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
DMA_Handle.Init.MemBurst = DMA_MBURST_SINGLE;
DMA_Handle.Init.PeriphBurst = DMA_PBURST_SINGLE;
if (HAL_DMA_Init(&DMA_Handle) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
//<2F><><EFBFBD><EFBFBD> ADC <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> DMA <20><><EFBFBD><EFBFBD>
__HAL_LINKDMA(&AdcHandle, DMA_Handle, DMA_Handle);
//<2F><><EFBFBD><EFBFBD> ADC
__HAL_RCC_ADC3_CLK_ENABLE();
AdcHandle.Instance = ADC3;
AdcHandle.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV8; //<2F><><EFBFBD><EFBFBD>PLL<4C>첽ʱ<ECB2BD>ӣ<EFBFBD>8<EFBFBD><38>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD> 72MHz / 8 = 36MHz
AdcHandle.Init.Resolution = ADC_RESOLUTION_16B; //16 λ<>ֱ<EFBFBD><D6B1><EFBFBD>
AdcHandle.Init.ScanConvMode = ADC_SCAN_ENABLE; //<2F><><EFBFBD><EFBFBD>ɨ<EFBFBD><C9A8>
AdcHandle.Init.EOCSelection = ADC_EOC_SINGLE_CONV; //EOC ת<><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־
AdcHandle.Init.LowPowerAutoWait = DISABLE; //<2F><>ֹ<EFBFBD>͹<EFBFBD><CDB9><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6>ӳ<EFBFBD><D3B3><EFBFBD><EFBFBD><EFBFBD>
AdcHandle.Init.ContinuousConvMode = ENABLE; //<2F><><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD>ת<EFBFBD><D7AA>
AdcHandle.Init.NbrOfConversion = 2; //ʹ<><CAB9><EFBFBD><EFBFBD> 2 <20><>ת<EFBFBD><D7AA>ͨ<EFBFBD><CDA8>
AdcHandle.Init.DiscontinuousConvMode = DISABLE; //<2F><>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ
AdcHandle.Init.NbrOfDiscConversion = 1; //<2F><>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ<C4A3>󣬴˲<F3A3ACB4><CBB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԣ<EFBFBD><D4A3><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ò<EFBFBD><C3B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD>
AdcHandle.Init.ExternalTrigConv = ADC_SOFTWARE_START; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
AdcHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD>
AdcHandle.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR; //DMA ѭ<><D1AD>ģʽ<C4A3><CABD><EFBFBD><EFBFBD> ADC ת<><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
AdcHandle.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; //ADC ת<><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ADC <20><><EFBFBD><EFBFBD><EFBFBD>ݼĴ<DDBC><C4B4><EFBFBD>
AdcHandle.Init.OversamplingMode = DISABLE; //<2F><>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//<2F><>ʼ<EFBFBD><CABC> ADC
if (HAL_ADC_Init(&AdcHandle) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
//У׼ ADC<44><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƫ<EFBFBD><C6AB>У׼
if (HAL_ADCEx_Calibration_Start(&AdcHandle, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
//<2F><><EFBFBD><EFBFBD> 1<><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD> PC0 <20><><EFBFBD><EFBFBD>
sConfig.Channel = ADC_CHANNEL_10;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_810CYCLES_5; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
sConfig.SingleDiff = ADC_SINGLE_ENDED; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
sConfig.OffsetNumber = ADC_OFFSET_NONE; //<2F><>ƫ<EFBFBD><C6AB>
sConfig.Offset = 0;
sConfig.OffsetRightShift = DISABLE; //<2F><>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD>
sConfig.OffsetSignedSaturation = DISABLE; //<2F><>ֹ<EFBFBD>з<EFBFBD><D0B7>ű<EFBFBD><C5B1><EFBFBD>
if (HAL_ADC_ConfigChannel(&AdcHandle, &sConfig) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
//<2F><><EFBFBD><EFBFBD> 2<><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD> PC1 <20><><EFBFBD><EFBFBD>
sConfig.Channel = ADC_CHANNEL_11;
sConfig.Rank = ADC_REGULAR_RANK_2;
sConfig.SamplingTime = ADC_SAMPLETIME_810CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
sConfig.OffsetRightShift = DISABLE;
sConfig.OffsetSignedSaturation = DISABLE;
if (HAL_ADC_ConfigChannel(&AdcHandle, &sConfig) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
//<2F><><EFBFBD><EFBFBD> ADC <20><> DMA <20><>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD>
if (HAL_ADC_Start_DMA(&AdcHandle, (uint32_t *)ADCxValues, 2) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
//<2F><><EFBFBD>ö<EFBFBD>ʱ<EFBFBD><CAB1>
TIM_Set(TIM3, 1000, 0, 0);
}
/**
* @brief <EFBFBD><EFBFBD>ȡ PC0 <EFBFBD><EFBFBD>ѹ
* @retval <EFBFBD><EFBFBD>ѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ V
*/
float ADC_Get_PC0(void)
{
return ADCxValues[0] * 3.3 / 65536;
}
/**
* @brief <EFBFBD><EFBFBD>ȡ PC1 <EFBFBD><EFBFBD>ѹ
* @retval <EFBFBD><EFBFBD>ѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ V
*/
float ADC_Get_PC1(void)
{
return ADCxValues[1] * 3.3 / 65536;
}
/**
* @brief TIM3 <EFBFBD>жϴ<EFBFBD><EFBFBD><EFBFBD>
*/
void TIM3_IRQHandler(void)
{
if ((TIM3->SR & TIM_FLAG_UPDATE) != RESET)
{
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>±<EFBFBD>־
TIM3->SR = ~TIM_FLAG_UPDATE;
SCB_InvalidateDCache_by_Addr((uint32_t *)ADCxValues, sizeof(uint32_t));
}
}