Перейти к содержанию
    

STM32 ADC TRIPLE/DOUBLE trigger mode

На TIM4 сделан шим 5МГц, по возростающему фронта которого необходимо получать данные с АЦП. Все 3 АЦП висят на 1 порте, по фронтам должны включаться поорередно.

 

 

/******************************************************************************/
/* ADC Common configuration *************************************************/
ADC_CommonInitStructure.ADC_Mode = ADC_TripleMode_AlterTrig;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_3;  //ADC_DMAAccessMode_2;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInit(&ADC_CommonInitStructure);

/* ADC1 regular channel 3 configuration ************************************/
ADC_InitStructure.ADC_Resolution = ADC_Resolution_8b; //ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;
//ADC_ExternalTrigConvEdge_Rising;//ADC_ExternalTrigConvEdge_Falling
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T5_CC1;
// ADC_ExternalTrigConv_T2_TRGO; //ADC_ExternalTrigConv_T2_CC3
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC1, &ADC_InitStructure);

ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 1, ADC_SampleTime_3Cycles);
ADC_Init(ADC2, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC2, ADC_Channel_3, 1, ADC_SampleTime_3Cycles);
ADC_Init(ADC3, &ADC_InitStructure); 
ADC_RegularChannelConfig(ADC3, ADC_Channel_3, 1, ADC_SampleTime_3Cycles);
ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);
/*
ADC_InjectedChannelConfig(ADC1, ADC_Channel_3, 1, ADC_SampleTime_3Cycles);
ADC_InjectedChannelConfig(ADC2, ADC_Channel_3, 1, ADC_SampleTime_3Cycles);
ADC_InjectedChannelConfig(ADC3, ADC_Channel_3, 1, ADC_SampleTime_3Cycles);
//ADC_InjectedSequencerLengthConfig();
ADC_ExternalTrigInjectedConvConfig(ADC1,ADC_ExternalTrigInjecConv_T4_TRGO);

ADC_ExternalTrigInjectedConvEdgeConfig( ADC1, ADC_ExternalTrigInjecConvEdge_Rising);
ADC_ExternalTrigInjectedConvEdgeConfig( ADC2, ADC_ExternalTrigInjecConvEdge_Rising);
ADC_ExternalTrigInjectedConvEdgeConfig( ADC3, ADC_ExternalTrigInjecConvEdge_Rising);
*/	
ADC_Cmd(ADC1, ENABLE);
ADC_Cmd(ADC2, ENABLE);
ADC_Cmd(ADC3, ENABLE);

С режимом Интерлеавед все работает, данные пакует ДМА, отлажен довольно большой кусок проекта. Сейчас необходимо сделать привязку к сигналу ШИМ - никаких признаков жизни.

Изменено пользователем IgorKossak

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может кому принодиться....

 

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef  	TIM_OCInitStructure;

//__IO uint32_t		ADCvalues0[CCDsize],ADCvalues1[CCDsize];
u8		ADCvalues0[CCDsize*4],ADCvalues1[CCDsize*4];


//****************************


/******************************************************************************/
/*               ADCs interface clock, pin and DMA configuration              */
/******************************************************************************/

/* Enable peripheral clocks */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 | RCC_APB2Periph_ADC3, ENABLE);

 	/* Configure ADC Channel ADC123_IN3 LQFP144.37pin as analog input */ 
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOA, &GPIO_InitStructure);

 	/* DMA2 Stream0 channel0 configuration */
bReadinBufADC = 0;

DMA_InitStructure.DMA_Channel = DMA_Channel_0;  
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC_CDR_ADDRESS;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADCvalues0;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = CCDsize;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;// DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode =DMA_Mode_Normal;// DMA_Mode_Normal;//DMA_Mode_Normal;//DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
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);

/* DMA2_Stream0 enable */
DMA_Cmd(DMA2_Stream0, ENABLE);

/******************************************************************************/
/*  ADCs configuration: triple interleaved with 5cycles delay to reach 6Msps  */
/******************************************************************************/
/* ADC Common configuration *************************************************/
ADC_CommonInitStructure.ADC_Mode =ADC_TripleMode_Interl;// ADC_TripleMode_Interl;//ADC_TripleMode_AlterTrig; 
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_6Cycles;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_3;  //ADC_DMAAccessMode_2;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInit(&ADC_CommonInitStructure);

/* ADC1 regular channel 3 configuration ************************************/
ADC_InitStructure.ADC_Resolution = ADC_Resolution_8b; //ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;
//ADC_ExternalTrigConvEdge_Rising;//ADC_ExternalTrigConvEdge_Falling
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T5_CC1;
// ADC_ExternalTrigConv_T2_TRGO; //ADC_ExternalTrigConv_T2_CC3
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC1, &ADC_InitStructure);

/* ADC2 regular channel 3 configuration ************************************/
ADC_InitStructure.ADC_Resolution = ADC_Resolution_8b; //ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;
//ADC_ExternalTrigConvEdge_Rising;//ADC_ExternalTrigConvEdge_Falling
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T5_CC1;
// ADC_ExternalTrigConv_T2_TRGO; //ADC_ExternalTrigConv_T2_CC3
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC2, &ADC_InitStructure);

/* ADC3 regular channel 3 configuration ************************************/
ADC_InitStructure.ADC_Resolution = ADC_Resolution_8b; //ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode =DISABLE;// ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;
//ADC_ExternalTrigConvEdge_Rising;//ADC_ExternalTrigConvEdge_Falling
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T5_CC1;
// ADC_ExternalTrigConv_T2_TRGO; //ADC_ExternalTrigConv_T2_CC3
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC3, &ADC_InitStructure);

ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 1, ADC_SampleTime_3Cycles);
ADC_RegularChannelConfig(ADC2, ADC_Channel_3, 1, ADC_SampleTime_3Cycles);
ADC_RegularChannelConfig(ADC3, ADC_Channel_3, 1, ADC_SampleTime_3Cycles);
/*
ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);

ADC_Cmd(ADC1, ENABLE);
ADC_Cmd(ADC2, ENABLE);
ADC_Cmd(ADC3, ENABLE);
*/

ADC_DMACmd(ADC1, ENABLE);
       ADC_DMACmd(ADC2, ENABLE);
       ADC_DMACmd(ADC3, ENABLE);



      ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);

      /* Enable ADC1 */
      ADC_Cmd(ADC1, ENABLE);
      ADC_Cmd(ADC2, ENABLE);
      ADC_Cmd(ADC3, ENABLE);


/* TIM2 clock enable */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
/* TIM3 clock enable */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
/* TIM5 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);

 	/* GPIOB clock enable */
 	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
 	/* GPIOA clock enable */
 	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

	/* GPIOB Configuration: TIM3 CH3 (PB0), TIM2 CH3 (PB10) */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
GPIO_Init(GPIOB, &GPIO_InitStructure); 

	///GPIOD Configuration: TIM5 CH0 (PA)
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
GPIO_Init(GPIOA, &GPIO_InitStructure); 

 	/* Connect TIM2,TIM3 pins to AF */  
GPIO_PinAFConfig(GPIOB, GPIO_PinSource0, GPIO_AF_TIM3);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_TIM2); 
GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_TIM5); 

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);

 	/* Enable the TIM3 gloabal Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

/* TIM2 Peripheral Configuration ----------------------------------------*/
 	/* Compute the prescaler value */                     //10000000
	PrescalerValue = (uint16_t) ((SystemCoreClock / 4) / (1000000));

 	/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = 1;
 	TIM_TimeBaseStructure.TIM_Prescaler =  2;
 	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
 	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

/* Output Compare Toggle Mode configuration: Channel3 */
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
 	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 1; //1;

	TIM_OC3Init(TIM2, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Disable);
TIM_ARRPreloadConfig(TIM2, ENABLE); 

/* TIM3 Peripheral Configuration ----------------------------------------*/

       TIM_TimeBaseStructure.TIM_Period = 530;
TIM_TimeBaseStructure.TIM_Prescaler =0; //0;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//  TIM_CounterMode_Up;
 	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse =TIM_TimeBaseStructure.TIM_Period - 300; //mks * 10
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC3Init(TIM3, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Disable);

TIM_SelectOnePulseMode(TIM3, TIM_OPMode_Repetitive);//TIM_OPMode_Repetitive//TIM_OPMode_Single
TIM_ARRPreloadConfig(TIM3, ENABLE);        

/* TIM5 Peripheral Configuration ----------------------------------------*/
/* Compute the prescaler value */                     //10000000

 	TIM_TimeBaseStructure.TIM_Period =35;//11;//get 5MHZ
TIM_TimeBaseStructure.TIM_Prescaler =0; //0;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//  TIM_CounterMode_Up;
 	TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure);

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse =1;//1; //Rising front regulator
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OC1Init(TIM5, &TIM_OCInitStructure);

TIM_OC1PreloadConfig(TIM5, TIM_OCPreload_Disable);

TIM_SelectOnePulseMode(TIM5, TIM_OPMode_Repetitive);//TIM_OPMode_Repetitive//TIM_OPMode_Single
TIM_ARRPreloadConfig(TIM5, ENABLE);        

//------------------------------------------------------------------------------  

// Select the Master Slave Mode 
TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);
TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_OC3Ref);

// Slave Mode selection: TIM3 
TIM_SelectInputTrigger(TIM3, TIM_TS_ITR1);
TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_External1);//тактируется от ^ импульсов ТМ2
// Slave Mode selection: TIM5 
TIM_SelectInputTrigger(TIM5, TIM_TS_ITR1);
TIM_SelectSlaveMode(TIM5, TIM_SlaveMode_Trigger);//Starts at rising edge of TM2 trigger

/* TIM enable counter */
TIM_Cmd(TIM3, ENABLE); 
TIM_Cmd(TIM5, ENABLE); 

TIM_Cmd(TIM2, ENABLE);

 

TM2 (5МГц) клочит ПЗС матрицу, тм3 - задаёт время её экспозиции, ТМ5 (1,66МГц)- регулировка фазового сдвига относительно ТМ3. Ацп стартует по верхнему фронту T5_CC1, делает 3 измерения и ждёт след. триггера, что суммарно даёт немного кривоватые, но 5МГц со сдвигом по фазе относительно основного клока. Дма раскладывает все результаты ацп в массив.

Изменено пользователем IgorKossak
форматирование

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...