Forum: Mikrocontroller und Digitale Elektronik AT91SAM7 ADC mit Interrupt


von Nobbie (Gast)


Lesenswert?

Hallo,

ich bin gerade dabei, das ADC Modul mit Multichannel, Softwaretriggerung 
und Interrupt zu programmieren.
Nachfolgend mal der Quellcode:
1
unsigned int adc_Init(void)
2
{
3
  // reset
4
  AT91F_ADC_SoftReset(AT91C_BASE_ADC);
5
6
  // enable peripheral clock ADC
7
  AT91F_ADC_CfgPMC();
8
9
  // config timing of ADC 55Mhz mainclock, ADC clock 5MHz
10
  AT91F_ADC_CfgTimings(AT91C_BASE_ADC, 
11
                       55     /*MHz   MCK*/, 
12
                       5      /*MHz   ADCCK*/,
13
           20     /*uSec  startup time*/, 
14
                       700    /*nSec  sample and hold*/);
15
16
  // enable channels to measure
17
  // channel 0
18
  // channel 1
19
  // channel 2
20
  // channel 3
21
  AT91F_ADC_EnableChannel(AT91C_BASE_ADC,
22
                          (AT91C_ADC_CH0 | AT91C_ADC_CH1 | AT91C_ADC_CH2 | AT91C_ADC_CH3));
23
        
24
  
25
  // enable interrupt of the last ADC channel 3
26
  AT91F_ADC_EnableIt(AT91C_BASE_ADC, (AT91C_ADC_CH3));
27
  
28
  // configure AIC
29
  AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, 
30
                        AT91C_ID_ADC,
31
                        AT91C_AIC_PRIOR_HIGHEST,
32
      AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, 
33
                        adc_ISR);
34
  
35
  // enable AIC
36
  AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_ADC);
37
38
  return 0;
39
}
40
41
static void adc_ISR(void)
42
{
43
  unsigned int uiStatus   = 0;
44
  
45
46
  // read status register
47
  uiStatus = AT91C_BASE_ADC->ADC_SR;
48
  uiStatus = uiStatus;
49
50
  if(uiStatus & AT91C_ADC_CH3)
51
  {
52
    // read ADC value
53
    ui_ValueCH0 = AT91F_ADC_GetConvertedDataCH0(AT91C_BASE_ADC);
54
    ui_ValueCH1 = AT91F_ADC_GetConvertedDataCH1(AT91C_BASE_ADC);
55
    ui_ValueCH2 = AT91F_ADC_GetConvertedDataCH2(AT91C_BASE_ADC);
56
    ui_ValueCH3 = AT91F_ADC_GetConvertedDataCH3(AT91C_BASE_ADC);
57
    
58
    // set valid
59
    adc_bool_Conversation_Valid = TRUE;
60
61
  }
62
 
63
  // clear interrupt
64
  AT91F_AIC_ClearIt(AT91C_BASE_AIC, AT91C_ID_ADC);
65
}
66
67
unsigned int adc_StartConversation(void)
68
{
69
  adc_bool_Conversation_Valid = FALSE;
70
  AT91F_ADC_StartConversion(AT91C_BASE_ADC);
71
  return 0;
72
}

Der Anstoss für die ADC erfolgt asynchron durch einen Softwaretrigger.
Mein Problem ist jetzt, dass die ADC genau einmal sauber funktioniert. 
Bei allen weiteren 
Softwaretriggers(AT91F_ADC_StartConversion(AT91C_BASE_ADC)) wird die ISR 
nicht mehr ausgeführt.

Hat jemand eine Idee woran das liegen kann?

Danke Nobbie

von Carsten (Gast)


Lesenswert?

Ich weiß dass ich zu spät dran bin, aber was solls :-)

Damit schaltest du den Interrrupt wieder aus:
1
AT91F_AIC_ClearIt(AT91C_BASE_AIC, AT91C_ID_ADC);

Du musst ihn wieder einschalten
1
AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_ADC);

oder den Interrrupt eingeschaltet lassen ...

Bitte,

Carsten

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.