Forum: Compiler & IDEs STM32F4xx: ADC-Trigger mit Timer1-Ereignis?


von Rainer R. (Firma: Reusch Elektronik) (reusch)


Lesenswert?

Hallo Forum-Gemeinde!
Gegeben ist ein STM32F4xx-Controller (STM32F405, Cortex-M4). Ich suche 
ein funktionierendes Quelltext-Beispiel, in dem mit einem 
Timer1-Ereignis, also ohne Interrupt, die (jeweils einmalige) 
ADC-Konvertierung angeworfen wird. Wenn ich das richtig verstanden habe, 
soll das ja gehen. Die Frage ist nur, wie?

Das folgende Beispiel funktioniert mit Timer-Interrupt und manuellem 
Start der A/D-Wandlung. Es verwendet ADC1 und ADC2, die synchron 
getriggert und in ADC_IRQHandler ausgelesen werden. Der A/D-Wandler wird 
in TIM1_UP_TIM10_IRQHandler angeworfen. Doch wie geht es ohne 
Timer-Interrupt-Routine, also mit einem Timer-Ereignis, z.B. mit 
ADC_ExternalTrigConv_T1_CC1, wie in der Initialisierung gesetzt? Hat 
jemand eine passende Lösung?

void ADC_IRQHandler(void)
{
  if (ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)) {
    ADC_ClearFlag(ADC1,ADC_FLAG_EOC);
    //DebugStr("ADC1=%d\n",ADC_GetConversionValue(ADC1));
  }
  if (ADC_GetFlagStatus(ADC2,ADC_FLAG_EOC)) {
    ADC_ClearFlag(ADC2,ADC_FLAG_EOC);
    //DebugStr("ADC2=%d\n",ADC_GetConversionValue(ADC2));
  }
}

void TIM1_UP_TIM10_IRQHandler(void)
{
  TIM_ClearFlag(TIM1,TIM_IT_Update);
  ADC_SoftwareStartConv(ADC1);
}

int main(void)
{
  TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
  NVIC_InitTypeDef NVIC_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
  ADC_CommonInitTypeDef ADC_CommonInitStruct;
  ADC_InitTypeDef ADC_InitStructure;

  SystemInit();

  // Timer1
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
  TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;
  TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;
  TIM_TimeBaseInitStruct.TIM_Prescaler=1-1; // Basisfrequenz: 168MHz
  TIM_TimeBaseInitStruct.TIM_Period=1867-1; // 90000 Abtastungen/sek
  TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;
  TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStruct);
  TIM_Cmd(TIM1,ENABLE);
  TIM_SetCompare1(TIM1,100); // erster Vergleichswert
  TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE);

  // Timer 1 Interrupt
  NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_TIM10_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

   // Analog-Eingänge
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
   GPIO_StructInit(&GPIO_InitStructure);
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(GPIOA, &GPIO_InitStructure);

   // ADC1/ADC2 Konfiguration
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | 
RCC_APB2Periph_ADC2,ENABLE);
   // ADC-Gruppe
   ADC_CommonInitStruct.ADC_Mode=ADC_DualMode_RegSimult_InjecSimult;
   ADC_CommonInitStruct.ADC_Prescaler=ADC_Prescaler_Div2;
   ADC_CommonInitStruct.ADC_DMAAccessMode=ADC_DMAAccessMode_Disabled;
   ADC_CommonInitStruct.ADC_TwoSamplingDelay=ADC_TwoSamplingDelay_5Cycles;
   ADC_CommonInit(&ADC_CommonInitStruct);

   // ADC-Einstellung
   ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
   ADC_InitStructure.ADC_ScanConvMode = DISABLE;
   ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
   ADC_InitStructure.ADC_ExternalTrigConvEdge = 
ADC_ExternalTrigConvEdge_Rising;
   ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
   ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
   ADC_InitStructure.ADC_NbrOfConversion = 1;
   ADC_Init(ADC1, &ADC_InitStructure);
   ADC_Init(ADC2, &ADC_InitStructure);
   ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_3Cycles); 
// beide Kanäle müssen zur gleichen
   ADC_RegularChannelConfig(ADC2,ADC_Channel_1,1,ADC_SampleTime_3Cycles); 
// Gruppe gehören (3. Parameter)
   ADC_Cmd(ADC1,ENABLE);
   ADC_Cmd(ADC2,ENABLE);
   ADC_ITConfig(ADC1,ADC_IT_EOC,ENABLE);

  // ADC Interrupt
  NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

    while(1)
    {
      asm volatile ("nop");
    }
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.