f1a75267fb
+Fix filter
126 lines
3.8 KiB
C
126 lines
3.8 KiB
C
//Mostly from: http://www.pezzino.ch/stm32-adc-voltage-monitor/
|
|
//Also: http://www.micromouseonline.com/2009/05/26/simple-adc-use-on-the-stm32/
|
|
|
|
#include "adc.h"
|
|
#include <stm32f30x_rcc.h>
|
|
#include <stm32f30x_gpio.h>
|
|
#include <stm32f30x_adc.h>
|
|
#include <stm32f30x_tim.h>
|
|
#include <stm32f30x_misc.h>
|
|
|
|
static int calibration_value;
|
|
extern RCC_ClocksTypeDef RCC_Clocks;
|
|
|
|
void InitADC()
|
|
{
|
|
ADC_InitTypeDef ADC_InitStructure;
|
|
ADC_CommonInitTypeDef ADC_CommonInitStructure;
|
|
GPIO_InitTypeDef GPIO_InitStructure;
|
|
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
|
|
|
/* Configure the ADC clock */
|
|
RCC_ADCCLKConfig( RCC_ADC34PLLCLK_Div2 );
|
|
|
|
/* Enable ADC1 clock */
|
|
RCC_AHBPeriphClockCmd( RCC_AHBPeriph_ADC34, ENABLE );
|
|
|
|
/* ADC Channel configuration */
|
|
/* GPIOC Periph clock enable */
|
|
RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOB, ENABLE );
|
|
|
|
/* Configure ADC Channel7 as analog input */
|
|
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
|
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
|
|
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
|
|
GPIO_Init( GPIOB, &GPIO_InitStructure );
|
|
|
|
ADC_StructInit( &ADC_InitStructure );
|
|
|
|
/* Calibration procedure */
|
|
ADC_VoltageRegulatorCmd( ADC4, ENABLE );
|
|
|
|
/* Insert delay equal to 10 µs */
|
|
_delay_us( 10 );
|
|
|
|
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
|
|
ADC_CommonInitStructure.ADC_Clock = ADC_Clock_AsynClkMode;
|
|
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
|
|
ADC_CommonInitStructure.ADC_DMAMode = ADC_DMAMode_OneShot;
|
|
ADC_CommonInitStructure.ADC_TwoSamplingDelay = 0;
|
|
ADC_CommonInit( ADC4, &ADC_CommonInitStructure );
|
|
|
|
ADC_InitStructure.ADC_ContinuousConvMode = ADC_ContinuousConvMode_Enable;
|
|
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
|
|
ADC_InitStructure.ADC_ExternalTrigConvEvent = ADC_ExternalTrigConvEvent_0;
|
|
ADC_InitStructure.ADC_ExternalTrigEventEdge = ADC_ExternalTrigEventEdge_None;
|
|
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
|
|
ADC_InitStructure.ADC_OverrunMode = ADC_OverrunMode_Disable;
|
|
ADC_InitStructure.ADC_AutoInjMode = ADC_AutoInjec_Disable;
|
|
ADC_InitStructure.ADC_NbrOfRegChannel = 1;
|
|
ADC_Init( ADC4, &ADC_InitStructure );
|
|
|
|
/* ADC4 regular channel3 configuration */
|
|
ADC_RegularChannelConfig( ADC4, ADC_Channel_3, 1, ADC_SampleTime_181Cycles5 );
|
|
|
|
/* Enable ADC4 */
|
|
ADC_Cmd( ADC4, ENABLE );
|
|
|
|
/* wait for ADRDY */
|
|
while( !ADC_GetFlagStatus( ADC4, ADC_FLAG_RDY ) );
|
|
|
|
|
|
NVIC_InitTypeDef NVIC_InitStructure;
|
|
/* Enable the TIM2 gloabal Interrupt */
|
|
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
|
|
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
|
|
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
|
|
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
|
NVIC_Init (&NVIC_InitStructure);
|
|
|
|
/* TIM2 clock enable */
|
|
RCC_APB1PeriphClockCmd (RCC_APB1Periph_TIM2, ENABLE);
|
|
/* Time base configuration */
|
|
RCC->CFGR |= 0X1400;
|
|
TIM_TimeBaseStructure.TIM_Period = (RCC_Clocks.HCLK_Frequency/(ADCFS*ADCOVERSAMP)) - 1;
|
|
TIM_TimeBaseStructure.TIM_Prescaler = 1 - 1; // Operate at clock frequency
|
|
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
|
|
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
|
TIM_TimeBaseInit (TIM2, &TIM_TimeBaseStructure);
|
|
/* TIM IT enable */
|
|
TIM_ITConfig (TIM2, TIM_IT_Update, ENABLE);
|
|
/* TIM2 enable counter */
|
|
TIM_Cmd (TIM2, ENABLE);
|
|
|
|
/* Start ADC4 Software Conversion */
|
|
ADC_StartConversion( ADC4 );
|
|
}
|
|
|
|
|
|
void TIM2_IRQHandler (void)
|
|
{
|
|
static uint8_t oversamp = 0;
|
|
static int32_t average = 0;
|
|
static int32_t oversampout = 0;
|
|
|
|
if (TIM_GetITStatus (TIM2, TIM_IT_Update) != RESET) {
|
|
TIM_ClearITPendingBit (TIM2, TIM_IT_Update);
|
|
int16_t value = ADC_GetConversionValue(ADC4);
|
|
ADC_StartConversion( ADC4 );
|
|
|
|
oversampout += value;
|
|
oversamp++;
|
|
|
|
if( oversamp >= ADCOVERSAMP )
|
|
{
|
|
value = oversampout / ADCOVERSAMP;
|
|
average = ((average*1023) + (value*1024))/1024;
|
|
value = value-(average/1024);
|
|
oversamp = 0;
|
|
ADCCallback( value );
|
|
oversampout = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
|