I have to use 4 ADC channels in my stm32f3 Discovery, so I've decided to use DMA with Nvic. Values sent by USART are correct, however, the DMA1 Channel1 interrupt is called only once after downloading code to flash. I need a continuous conversion, is there something wrong with ADC/DMA/Nvic configuration?
#include"stm32f30x.h"
#include"stm32f30x_gpio.h"
#include"stm32f30x_rcc.h"
#include"stm32f30x_usart.h"
#include"stm32f30x_misc.h"
#include"stm32f30x_adc.h"
#include"stm32f30x_tim.h"
#include"stm32f30x_dma.h"
#define ADC1_DR ((uint32_t)0x4001244C)
__IO uint16_t calibration_value = 0;
__IO uint32_t TimingDelay = 0;
__IO uint16_t ADC_Values[4];
uint16_t tmp[4];
volatile uint32_t dmaFlag = 0;
volatile char rxData[100];
volatile long int rxIndex=0, rxFlag=0;
void USART_puts( USART_TypeDef* USARTx, char *str )
{
while(*str)
{
while( USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET );
USART_SendData(USARTx, *str);
*str++;
}
}
void adc_init(void);
int main(void)
{
int8_t dmaIndex;
int k;
usart_init();
USART_puts(USART1,"ok");
adc_init();
while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_RDY));
DMA_Cmd(DMA1_Channel1, ENABLE);
ADC_StartConversion(ADC1);
//
while(1)
{
while(!dmaFlag);
usart_num(tmp[0]);
usart_num(tmp[1]);
usart_num(tmp[2]);
usart_num(tmp[3]);
for(k=0;k<10000000;k++);
dmaFlag= 0;
}
}
void adc_init(void)
{
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure1;
GPIO_InitStructure1.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
GPIO_InitStructure1.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure1.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOC, &GPIO_InitStructure1);
RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div2);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ADC12, ENABLE);
ADC_CommonInitTypeDef ADC_CommonInitStructure;
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_Circular;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = 0;
ADC_CommonInit(ADC1, &ADC_CommonInitStructure);
ADC_InitTypeDef ADC_InitStructure;
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 = 4;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_StructInit(&ADC_InitStructure);
ADC_VoltageRegulatorCmd(ADC1, ENABLE);
ADC_SelectCalibrationMode(ADC1, ADC_CalibrationMode_Single);
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1) != RESET );
calibration_value = ADC_GetCalibrationValue(ADC1);
ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 1, ADC_SampleTime_7Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 2, ADC_SampleTime_7Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 3, ADC_SampleTime_7Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 4, ADC_SampleTime_7Cycles5);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
DMA_InitTypeDef DMA_InitStructure;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_Values;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 4;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // 16 bit
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // 16 bit
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);
DMA_Cmd(DMA1_Channel1, ENABLE);
ADC_DMACmd(ADC1, ENABLE);
ADC_Cmd(ADC1, ENABLE);
}
void DMA1_Channel1_IRQHandler(void)
{
USART_puts(USART1,"fsfr");
if (DMA_GetITStatus(DMA1_IT_TC1))
{
int dmaIndex;
for(dmaIndex=0; dmaIndex<4; dmaIndex++)
{
tmp[dmaIndex]=ADC_Values[dmaIndex]/4;
}
DMA_ClearITPendingBit(DMA1_IT_TC1);
dmaFlag= 1;
}
}
void usart_init( void )
{
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init( GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_7);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_7);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
USART_ITConfig( USART1, USART_IT_RXNE, ENABLE);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStructure);
USART_Cmd( USART1, ENABLE);
}
void USART1_IRQHandler( void )
{
if( USART_GetITStatus( USART1, USART_IT_RXNE) )
{
rxData[rxIndex] = USART_ReceiveData(USART1);
// USART_ClearITPendingBit(USART1,USART_IT_RXNE);
while( !(rxData[rxIndex] == 'e') )
{
if( USART_GetITStatus( USART1, USART_IT_RXNE) )
{
rxIndex++;
rxData[rxIndex] = USART_ReceiveData(USART1);
if( rxData[rxIndex] == ' ')
rxData[rxIndex] = '0';
USART_ClearITPendingBit(USART1,USART_IT_RXNE);
}
}
rxFlag = 1;
}
///USART_ClearITPendingBit(USART1,USART_IT_RXNE);
}
void rxDataClear( void )
{
int i=0;
while( rxData[i] )
{
rxData[i] = 0;
i++;
}
rxIndex = 0;
}
void usart_float( float liczba )
{
float tmp;
char dane[7];
tmp = liczba;
dane[0]=(((int)tmp %1000) /100)+0x30;
dane[1]=(((int)tmp %100) /10)+0x30;
dane[2]=(((int)tmp %10))+0x30;
dane[3]='.';
dane[4]=((int)(tmp*10) %10)+0x30;
dane[5]=((int)(tmp*100) %10)+0x30;
dane[6]=((int)(tmp*1000) %10)+0x30;
dane[7]='\0';
USART_puts(USART1,dane);
}
void usart_num(signed int liczba)
{
int i, length=0,znak=0;
char liczba_str[10] = {0};
if( liczba < 0 )
{
znak = 1;
liczba = - liczba;
}
for( i = 1; (i <= liczba) && (length <= 10); i*=10 )
{
if( (liczba/i) > 0 )
length++;
}
if(length == 0)
length = 1;
i = 1;
while(length)
{
liczba_str[length-1]=liczba%(10*i)/i+48;
length--;
i*= 10;
}
if(znak)
USART_puts(USART1,"-");
else
USART_puts(USART1," ");
USART_puts(USART1, liczba_str );
}