cancel
Showing results for 
Search instead for 
Did you mean: 

ADC External Trigger

puneethj
Associate II
Posted on August 26, 2015 at 19:47

Hi Every One, My problem is I am not able to configure my ADC to start a conversion from external pulse, I want to use

ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_RisingFalling;

ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_Ext_IT11;

That is a pulse on Pin C1 or C2 should start the ADC conversion in non continuous and scan mode, I am using Dual ADC.

/* Includes ------------------------------------------------------------------*/
#include ''stm32f4xx.h''
#include ''stm32f4xx_rcc.h''
#include ''stm32f4xx_gpio.h''
#include ''stm32f4xx_adc.h''
#include ''stm32f4xx_flash.h''
#include ''stm32f4xx_dma.h''
// Configuring clock at MAX speed 168 MHZ
static void clock_config(void)
{
// Reset the clock to default states
RCC_DeInit();
// Enabling the external crystal clock
ErrorStatus Errstate;
RCC_HSEConfig(RCC_HSE_ON);
Errstate = RCC_WaitForHSEStartUp();
if (Errstate == SUCCESS)
{ // HSE is ok
//PLL Config
RCC_PLLConfig(RCC_PLLSource_HSE, 8, 336, 2, 7);
RCC_PLLCmd(ENABLE);
RCC_GetFlagStatus(RCC_FLAG_PLLRDY == RESET); // wait till the pll flag is set
// set flash Latency
//FLASH_SetLatency(uint32_t FLASH_Latency);
FLASH_SetLatency(FLASH_ACR_LATENCY_5WS);
// AHB APB1 and 2 Configuration
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div4);
RCC_PCLK2Config(RCC_HCLK_Div2);
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
}
else
{
// Hse is not ready
// blink a led to indicate Hse is not ready
}
}
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
uint16_t ADC_Val1;
uint16_t ADC_Val2;
#define BUFFERSIZE 1024
__IO uint16_t ADCDmaValuesc2[BUFFERSIZE];
__IO uint16_t ADCDmaValuesc1[BUFFERSIZE];
void ADCinit_SoftTrigger(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOC, &GPIO_InitStructure);
ADC_CommonInitStructure.ADC_Mode = ADC_DualMode_RegSimult;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInit(&ADC_CommonInitStructure);
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_RisingFalling;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_Ext_IT11;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_480Cycles);
ADC_AnalogWatchdogSingleChannelConfig(ADC1, ADC_Channel_11);//PC1
ADC_AnalogWatchdogThresholdsConfig(ADC1, 3000, 1400);
ADC_AnalogWatchdogCmd(ADC1, ADC_AnalogWatchdog_SingleRegEnable);//PC2
ADC_Init(ADC2, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC2, ADC_Channel_12, 1, ADC_SampleTime_480Cycles);
ADC_AnalogWatchdogSingleChannelConfig(ADC2, ADC_Channel_12);// PC2
ADC_AnalogWatchdogThresholdsConfig(ADC2, 3000, 1500);
ADC_AnalogWatchdogCmd(ADC2, ADC_AnalogWatchdog_SingleRegEnable);
ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
ADC_DMARequestAfterLastTransferCmd(ADC2, ENABLE);
ADC_Cmd(ADC1, ENABLE);
ADC_DMACmd(ADC1, ENABLE);
ADC_Cmd(ADC2, ENABLE);
ADC_DMACmd(ADC2, ENABLE);
}
static void DMA_Configurationc1(void)
{
DMA_InitTypeDef DMA_InitStructure;
DMA_StructInit (&DMA_InitStructure);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
DMA_InitStructure.DMA_Channel = DMA_Channel_0;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADCDmaValuesc1[0];
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR; // CDR_ADDRESS; Packed ADC1, ADC2
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = BUFFERSIZE; // Count of 16-bit words
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_FIFOMode = DMA_FIFOMode_Enable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream0, &DMA_InitStructure);
/* Enable DMA Stream Half / Transfer Complete interrupt */
// DMA_ITConfig(DMA2_Stream0, DMA_IT_TC | DMA_IT_HT, ENABLE);
/* DMA2_Stream0 enable */
DMA_Cmd(DMA2_Stream0, ENABLE);
}
static void DMA_Configurationc2(void)
{
DMA_InitTypeDef DMA_InitStructure;
DMA_StructInit (&DMA_InitStructure);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
DMA_InitStructure.DMA_Channel = DMA_Channel_1;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADCDmaValuesc2[0];
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC2->DR; // CDR_ADDRESS; Packed ADC1, ADC2
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = BUFFERSIZE; // Count of 16-bit words
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_FIFOMode = DMA_FIFOMode_Enable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream2, &DMA_InitStructure);
/* Enable DMA Stream Half / Transfer Complete interrupt */
// DMA_ITConfig(DMA2_Stream0, DMA_IT_TC | DMA_IT_HT, ENABLE);
/* DMA2_Stream0 enable */
DMA_Cmd(DMA2_Stream2, ENABLE);
}
int main(void)
{
clock_config();
ADCinit_SoftTrigger();
DMA_Configurationc1();
DMA_Configurationc2();
ADC_SoftwareStartConv(ADC1);
ADC_SoftwareStartConv(ADC2);
while (1)
{
uint16_t i;
/* while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET)
{};
ADC_Val1 = ADC_GetConversionValue(ADC1);
while(ADC_GetFlagStatus(ADC2, ADC_FLAG_EOC) == RESET)
{};
ADC_Val2 = ADC_GetConversionValue(ADC2);
*/
}
}

#stm32f407 #adc #externaltrigger
6 REPLIES 6
Posted on August 26, 2015 at 20:38

The Dual mode would suggest you can use a single DMA stream, and the common ADC register.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
puneethj
Associate II
Posted on August 27, 2015 at 13:03

But how can i separate the data individually, before i go to DMA my ADC has to be triggered by external pulse, Which is not happening, Please help me on that, Thank you

puneethj
Associate II
Posted on August 27, 2015 at 18:16

Or is it even possible to trigger ADC through External pin without using

ADC_SoftwareStartConv(ADC1);

Posted on August 28, 2015 at 20:20

That is a pulse on Pin C1 or C2 should start the ADC conversion in non continuous and scan mode, I am using Dual ADC. 

 

Yeah, I'm not sure that's going to happen on PC1/PC2, the External trigger needs to be on Pin 11 (EXTI_11) of one of the GPIO banks, or you need to route it via a TIM and Input Capture on a channel that triggers the ADC.

For dual mode you get an interleaved stream of samples, paired and converted at the same time. If you want TWO synchronized and separate streams, use the same trigger but keep the ADC independent. This really isn't something you can mix around, there are two ways of doing it, but you have to pick one.

I think your code mixes too many incompatible methods, you need to sit down with the reference manual and review the ADC chapter, and get some clarity as to what it can and can't do. Assume the silicon implements things which are inherently simple/clean. If necessary break your task into smaller pieces and experiment with ideas one at a time before trying to integrate them into a more complicated arrangement where you don't understand how any of the pieces work, or why they stop working.

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

Thank You Mr Clive, I am re routing to pin 11 and trying simple things as you suggested, Thanks once again

puneethj
Associate II
Posted on August 31, 2015 at 17:22

//PC11 for external trigger
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOC, &GPIO_InitStructure);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource11);
//EXTI Configuration Line 11
EXTI_DeInit();
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_Line11;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);

Hi Clive, I managed to get the external trigger working on PC11, Thank to your Advice, however my next problem is , I am not able to set the threshold value on PC11 for the trigger to occur, Even small mV is triggering my circuit which shouldn't happen, Please let me know How can i set the trigger threshold value for PC11, thanks in advance