cancel
Showing results for 
Search instead for 
Did you mean: 

DMA1_Channel1_IRQHandler

dhorywal
Associate II
Posted on August 28, 2013 at 20:53

Hi.

I need to read three analog inputs and perform the average of 20 measurements of both values​​, and can not waste time processing the average of these values​​. For this I am using the code below. The reading of the analog inputs is correct, but I'm not getting read interruptions DMA1_Channel1. My goal is to calculate the mean of the values ​​read from the analog channels each interruption Channel 1 DMA1.

If anyone can help me, I'm grateful.

Code:

/*---------------------------------------------------------------------------------

  CONFIGURATION CLOCK

----------------------------------------------------------------------------------*/

void RCC_Configuration(void)

{

/* DMA clock enable */

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 | RCC_AHBPeriph_DMA2, ENABLE);

/* Enable ADC1, ADC2, ADC3 and GPIOC clocks */

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 | RCC_APB2Periph_ADC3 | RCC_APB2Periph_GPIOC, ENABLE);

/* ADC 1 clocks */

RCC_ADCCLKConfig(RCC_PCLK2_Div6);

RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO | RCC_APB2Periph_ADC1, ENABLE);

}

/*--------------------------------------------------------------------------------*/

/*--------------------------------------------------------------------------------

  CONFIGURATION GPIO

----------------------------------------------------------------------------------*/

void GPIO_Configuration(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOC, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOC, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOC, &GPIO_InitStructure);

}

/*--------------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------------

  CONFIGURATION - DMA

----------------------------------------------------------------------------------*/

void AD_DMA_Configuration(void)

{

DMA_InitTypeDef DMA_InitStructure;

ADC_InitTypeDef ADC_InitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

/* Configure and enable ADC interrupt */

NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQChannel;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQChannel;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

  /* DMA1 Channel Config */

/* CONFIGURAÇÃO PARA MEDIÇÃO CORRENTE E TENSÃO DE CAMPO */

DMA_InitStructure.DMA_BufferSize = 3;

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADCBuffer;

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1->DR;

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

DMA_InitStructure.DMA_Priority = DMA_Priority_High;

DMA_Init(DMA1_Channel1, &DMA_InitStructure);

DMA_Cmd(DMA1_Channel1, ENABLE);

 

ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;

ADC_InitStructure.ADC_NbrOfChannel = 3;

ADC_InitStructure.ADC_ScanConvMode = ENABLE;

ADC_Init(ADC1, &ADC_InitStructure);

ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_28Cycles5);

ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 2, ADC_SampleTime_28Cycles5); 

ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 3, ADC_SampleTime_28Cycles5);

ADC_Cmd(ADC1, ENABLE);

ADC_DMACmd(ADC1, ENABLE);

ADC_ResetCalibration(ADC1);

while(ADC_GetResetCalibrationStatus(ADC1));

ADC_StartCalibration(ADC1);

while(ADC_GetCalibrationStatus(ADC1));

ADC_SoftwareStartConvCmd(ADC1, ENABLE);

DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);

//ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);

//ADC_ITConfig(ADC1, ADC_IT_JEOC, ENABLE);

//ADC_ITConfig(ADC1, ADC_IT_AWD, ENABLE);

}

void DMA1_Channel1_IRQHandler(void)

{

  if(DMA_GetITStatus(DMA1_IT_TC1))

  {

// My functions ...

DMA_ClearITPendingBit(DMA1_IT_GL1);

  }

}

6 REPLIES 6
Posted on August 28, 2013 at 21:48

What compiler and library are you using? The library looks old, the code looks reasonable.

If you are using a C++ compiler make sure the vector table is correct, and the name of the IRQHandler is not mangled by the compiler. Check the .MAP file. Unfortunately the code you provided is incomplete, the following was tested for the interrupt functioning on a VL-Discovery board.

// STM32 VLDiscovery 3 Channel ADC - sourcer32@gmail.com
#include ''stm32F10x.h''
vu16 ADC_RegularConvertedValueTab[3 * 20];
/******************************************************************************/
void RCC_Configuration(void)
{
RCC_ADCCLKConfig(RCC_PCLK2_Div2);
/* Enable DMA1 clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
/* Enable GPIOs and ADC1 clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC |
RCC_APB2Periph_ADC1, ENABLE);
}
/******************************************************************************/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure PC.00,01,02 (ADC Channel10-12) as analog input */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
/******************************************************************************/
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/******************************************************************************/
int main(void)
{
ADC_InitTypeDef ADC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
/* System clocks configuration ---------------------------------------------*/
RCC_Configuration();
/* GPIO configuration ------------------------------------------------------*/
GPIO_Configuration();
/* NVIC configuration ------------------------------------------------------*/
NVIC_Configuration();
/* DMA1 channel1 configuration ----------------------------------------------*/
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1->DR;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_RegularConvertedValueTab;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 20 * 3;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
/* Enable DMA1 channel1 */
DMA_Cmd(DMA1_Channel1, ENABLE);
/* ADC1 configuration ------------------------------------------------------*/
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = ENABLE; /* Multiple Channels */
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; /* Over and Over */
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 3;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channels configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_28Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 2, ADC_SampleTime_28Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 3, ADC_SampleTime_28Cycles5);
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* Enable ADC1 reset calibaration register */
ADC_ResetCalibration(ADC1);
/* Check the end of ADC1 reset calibration register */
while(ADC_GetResetCalibrationStatus(ADC1));
/* Start ADC1 calibaration */
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while(ADC_GetCalibrationStatus(ADC1));
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);
while(1)
{
}
/* does not exit - kind of important */
return(1);
}
/******************************************************************************/
void DMA1_Channel1_IRQHandler(void)
{
if (DMA_GetITStatus(DMA1_IT_TC1))
{
DMA_ClearITPendingBit(DMA1_IT_GL1);
// Do something
}
}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
dhorywal
Associate II
Posted on August 29, 2013 at 16:55

The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6cu&d=%2Fa%2F0X0000000bs1%2FYt_6QMDwrgxbTdRphXZhlkPfuo0BV89mt9LPZXioOAA&asPdf=false
akdoganahmet
Associate
Posted on July 13, 2015 at 13:48

Hi,

Thank you for your effort. I used your code in my project. But the DMA circular mode is not for me. I want to use the DMA in Normal Mode. But the DMA is filling the buffer only once in normal mode. I'm clearing the TC1 flag after transfer completed. But DMA is not restarting.

My code is:

void DMA1_Channel1_IRQHandler(void)

{

  if (DMA_GetITStatus(DMA1_IT_TC1))

  {

     DMA_ClearITPendingBit(DMA1_IT_TC1);

for(i=0;i<3*20;i++){

     sprintf(buf,''%u'', ADC_RegularConvertedValueTab[i]);

    GUI_Text(0,i*13,buf,White,Red);

  if(i==3*20)

 i=0;

}

 

  

  }

}

colinconstant
Associate II
Posted on December 08, 2015 at 12:10

colinconstant
Associate II
Posted on December 08, 2015 at 12:24

Posted on December 08, 2015 at 13:15

Hi Colin, whatever you're doing, it's not working. The forum doesn't work well with mobile (phone/tablet) devices due to it's use of advanced Microsoft technology for the post PC era.

Top post responses, edit existing post to correct issues with them.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..