2016-06-21 01:28 PM
Hello,
I have used a timer for triggering ADC for sampling per 20uS and use DMA to transfer 100 sample to the array. I suppose that the total time of converting and sampling time for ADC is about 2uS. So at each 20uS I can transfer 10 samples to the array with DMA. I want to know that does the ADC stop the conversion at the end of 20uS or it continues the conversion and transferring the data to the array until it fills the whole array ? Is it possible to force the DMA to transfer the converted values to the zero index of the array at the start of each triggering? I dont know the order of transferring the converted values to the array with DMA at the start of each triggering? Regards Hamed2016-06-23 05:47 AM
Correct, it will not give you a DMA Interrupt after 5 samples in a buffer that holds 100
I wouldn't zero the pointer, it would create a discontinuity in the buffer, I'd rather just observe where in the buffer it was and save that pointer. You're going to want to code some methods and evaluate them yourself. This isn't my project.2016-06-26 01:47 AM
2016-06-26 08:25 AM
Continuous is where you saturate the ADC, if you want it paced/triggered, you need to turn that off. ie NOT Continuous.
2016-06-27 02:30 PM
Hi clive1
Thanks for reply. I remove the configuration for trigger ADC. ADC is configured for continuous conversion and I config TIM3 for input capture. Now I want to getting 2 pulses on the channel2 of TIM3 and then two times trigger the TIM3_IRQHandler(). Is my code true? as below code:void TIM3_ExternalClockMode1()
{
TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_TimeBaseInitTypeDef TIM_BaseInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
TIM_DeInit(TIM3);
TIM_BaseInitStructure.TIM_Period = 2;
TIM_BaseInitStructure.TIM_Prescaler = 0;
TIM_BaseInitStructure.TIM_ClockDivision = 0;
TIM_BaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_BaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM3, &TIM_BaseInitStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x0;
TIM_ICInit(TIM3, &TIM_ICInitStructure);
/* Select the TIM3 Input Trigger: TI1FP1 */
TIM_SelectInputTrigger(TIM3, TIM_TS_TI2FP2);// TIM_TS_TI2FP2==>PA7 - TIM_TS_TI1FP1==>PA6
/* Select the slave Mode: Reset Mode */
//TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);
TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_External1);
/* Enable the Master/Slave Mode */
TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);
/* TIM enable counter */
TIM_Cmd(TIM3, ENABLE);
/* Enable the CC2 Interrupt Request */
TIM_ITConfig(TIM3, TIM_IT_CC1, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void TIM3_IRQHandler(void)
{
if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET)
{
/* Clear TIM3 Capture compare interrupt pending bit */
TIM_ClearITPendingBit(TIM3, TIM_IT_CC1);
if(CanStartCovert==true)
{
if(CaptureNumber==0 )
{
Current_Pos1=DMA_GetCurrDataCounter(DMA1_Channel1);
CaptureNumber=1;
}
else
{
Current_Pos2=DMA_GetCurrDataCounter(DMA1_Channel1);
CaptureNumber=0;
CanStartCovert=false;
}
}
}
}
void ADC1_Init()
{
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
/* DMA1 Channel1 Configuration ----------------------------------------------*/
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC3ConvertedValue;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = BufferLenght;
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 = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv =ADC_ExternalTrigConv_None; //ADC_ExternalTrigConv_Ext_IT11_TIM8_TRGO; //ADC_ExternalTrigConv_T1_CC2;//; ;// ;//;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC3 regular channels configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1, ADC_SampleTime_13Cycles5); //c2 ==for voltage
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* Enable ADC1 reset calibration register */
ADC_ResetCalibration(ADC1);
/* Check the end of ADC1 reset calibration register */
while(ADC_GetResetCalibrationStatus(ADC1));
/* Start ADC1 calibration */
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while(ADC_GetCalibrationStatus(ADC1));
/* Start ADC1 Software Conversion */
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
when the frequency of input pulse is below than 5khz it samples only one pulse but with the increasing the frequency it samples more than one pulse. I think there is a delay between the rising edge of the input pulse and time-stamping the DMA transferring.
What is you idea?
Regards
2016-06-28 12:09 PM
clive1:''Continuous is where you saturate the ADC, if you want it paced/triggered, you need to turn that off. ie NOT Continuous.''
Can you inform me about what kind of ADC configuration must be choosen? Continious ADC or Trigger ADC? I think I must config TIMx for external clock mode 1 that can call IRQHandler with each rising edge of input pulses. At the last code that I was sent , I save the position of DMA at each rising edge.I dont know is it correct or not ?!! Please help me. Regards Regards.2016-06-28 01:11 PM
So to reiterate, you need to use the ADC either in a CONTINUOUS mode or TRIGGERED mode.
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; // Triggered case
The source of the trigger is typically a timer, either the update or channel compare/input.
To start/stop the ADC in the triggering mode, the timer would need to be a slave. You should perhaps review the timer modes in the manual and experiment with generating pulse trains in the fashion you want to trigger. You can output timer signals to a pin and review with an oscilloscope.
I have my own projects to work on, so can't commit a great deal of time to yours.