2013-11-17 11:25 PM
I am fighting with this from couple of days. My uC is STM32F407VG.
I want to sample 3 triggered channels. For now I am triggering ADC using software but finaly I will use timer and dma, but for now I can't figure out how to configure ADC to do exactly 3 conversions and fire interrupt after each conversion. Could someone point me out what I am doing wrong in this sample code?#include ''arch/stm32f4xx/stm32f4xx.h''
static
volatile
int
g_adc_cnt;
static
uint32_t adc_data[ 3 ];
void
ADC_IRQHandler(
void
)
{
uint32_t status = READ_REG( ADC2->SR );
if
( status & ADC_SR_EOC )
adc_data[ g_adc_cnt++ ] = READ_REG( ADC2->DR );
}
int
main(
void
)
{
//RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE);
//RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);
ADC_CommonInitTypeDef adc_cmn;
adc_cmn.ADC_Mode = ADC_Mode_Independent;
adc_cmn.ADC_Prescaler = ADC_Prescaler_Div2;
// 16MHz / 2 = 8MHz
adc_cmn.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
adc_cmn.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles;
ADC_CommonInit(&adc_cmn);
ADC_InitTypeDef adc2_conf;
adc2_conf.ADC_Resolution = ADC_Resolution_12b;
adc2_conf.ADC_ScanConvMode = ENABLE;
adc2_conf.ADC_ContinuousConvMode = DISABLE;
adc2_conf.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
adc2_conf.ADC_ExternalTrigConv = 0;
adc2_conf.ADC_DataAlign = ADC_DataAlign_Right;
adc2_conf.ADC_NbrOfConversion = 3;
ADC_Init(ADC2, &adc2_conf);
ADC_DiscModeChannelCountConfig(ADC2, 3);
ADC_DiscModeCmd(ADC2, ENABLE);
ADC_ITConfig(ADC2, ADC_IT_EOC, ENABLE);
ADC_RegularChannelConfig(ADC2, ADC_Channel_10, 1, ADC_SampleTime_480Cycles);
ADC_RegularChannelConfig(ADC2, ADC_Channel_13, 2, ADC_SampleTime_480Cycles);
ADC_RegularChannelConfig(ADC2, ADC_Channel_12, 3, ADC_SampleTime_480Cycles);
ADC_Cmd(ADC2, ENABLE);
NVIC_InitTypeDef nvic;
nvic.NVIC_IRQChannel = ADC_IRQn;
nvic.NVIC_IRQChannelPreemptionPriority = 3;
nvic.NVIC_IRQChannelSubPriority = 0;
nvic.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&nvic);
while
( 1 )
{
ADC_SoftwareStartConv(ADC2);
do
{ ; }
while
( g_adc_cnt < 3 );
__NOP();
// Never gets here
g_adc_cnt = 0;
}
return
0;
}
#stm32-adc-group-interrupt
2013-11-18 04:40 AM
I'd be using DMA, but
Make sure you are actually getting any interrupts? Have you used a debugger to understand what is happening? C++? Make sure the name of the IRQHandler has not been mangled, check vector table and .MAP file. The array holding the data should be volatile, not sure static helps you at all here.