Forum: Mikrocontroller und Digitale Elektronik STM32 Cortex M3, ADC-Ergebnisse mittels DMA


von Michl (Gast)


Lesenswert?

Guten Morgen zusammen,

ich benutze eine STM32F103, und zwar geht es um den ADC/DMA Teil.

Ich schreibe diesen Teil um von 15 auf 27 Kanäle.
Die Ergebnisse werden mittels Pointer in "AdcResults" gespeichert, wie 
man an der Konfig vom DMA sehen kann. Allerdings frage ich mich, woher 
genau der DMA/(ADC) weiß, wann dieses Feld (es hat natürlich die Länge 
27 f. die Kanäle) zu Ende ist, und wieder von vorne beginnt.

Es ist so, das Hardware-seitig alle Kanäle über Multiplexer an einem 
einzigen Pin hängen. Je nach "multiplexer-Stand" schreibt er dann in die 
zugehörige Speicherzelle. Aber genau diesen Zusammenhang finde ich 
nicht.

Ok, ich hab den Teil:
  DMA_InitStructure.DMA_BufferSize = ADC_CH_NBR; 
// DMA buffer size (in data unit)
und
  ADC_InitStructure.ADC_NbrOfChannel = ADC_CH_NBR; 
// channels to convert

aber ich kann mir nicht vorstellen, dass er Anhand von dem Buffer die 
Länge erkennt, und wieder von vorne Anfängt.

Anmerkung zu Funktion:
Ich habe wie gesagt 27 Kanäle, die sich in der Reihenfolge:
3 allgemeine
12 Temperatur low
12 Temperatur high
zusammensetzen.

Für die beiden 12er Blöcke Temperatur benutze ich jeweils die gleichen 
12 I/O bits um die jeweilgen Multiplexer zu aktivieren. Nur dass ich für 
die oberen nochmal ein extra I/O habe um den "haupt-multiplexer" für die 
höheren 12 Kanäle zu aktivieren.

Und genau um die Situation geht es nämlich. Vorher war es 1:1. Sprich 
genauso viel Multiplexer Ausgänge wie Kanäle. Nun muss das geändert 
werden, aber ich finde den Zusammenhang zw. ADC-Ergebnis und 
Multiplexer-Bits nicht so recht, bzw. ich bin mir nicht sicher.

Vielen Dank für Tips!

Initialisierungen:
1
  // DMA1 CH1 configuration
2
  DMA_DeInit(DMA1_Channel1);
3
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) ADC1_DR_Address;       // Peripheral base address
4
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&AdcResults;                // Memory base address
5
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;                           // Peripheral is the source
6
  DMA_InitStructure.DMA_BufferSize = ADC_CH_NBR;                               // DMA buffer size (in data unit)
7
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;             // Disable peripheral register incrementation
8
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                      // Enable memory address register incrementation
9
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;  // Peripheral data width = 32 bits
10
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;          // Memory data width = 32 bits
11
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                              // Circular buffer mode is used
12
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;                          // DMA channel has a high priority
13
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                                 // DMA channel not configured for memory-to memory transfer
14
  DMA_Init(DMA1_Channel1, &DMA_InitStructure);                                 // Init DMA1
15
  DMA_Cmd(DMA1_Channel1, ENABLE);                                              // Enable DMA1 channel 1
16
17
  // ADC1 initialisation
18
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;                           // ADC's operate simultaneously
19
  ADC_InitStructure.ADC_ScanConvMode = ENABLE;                                 // Scan multiple channels of this regular channel group consecutively
20
  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;                          // Single conversion of this regular channel group
21
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC2;        // Conversion started by Timer2 Capture Compare2
22
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;                       // Data right aligned
23
  ADC_InitStructure.ADC_NbrOfChannel = ADC_CH_NBR;                             // channels to convert
24
  ADC_Init(ADC1, &ADC_InitStructure);                                          // Init ADC1
25
26
  /* ADC1 regular configuration */
27
  ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_71Cycles5);    // Convert channel 0 (PA.0) with 71.5 cycles sample time
28
  ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 2, ADC_SampleTime_71Cycles5);    // Convert channel 0 (PA.0) with 71.5 cycles sample time
29
  ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 3, ADC_SampleTime_71Cycles5);    // Convert channel 0 (PA.0) with 71.5 cycles sample time
30
  ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 4, ADC_SampleTime_71Cycles5);    // Convert channel 0 (PA.0) with 71.5 cycles sample time
31
  ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 5, ADC_SampleTime_71Cycles5);    // Convert channel 0 (PA.0) with 71.5 cycles sample time
32
  ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 6, ADC_SampleTime_71Cycles5);    // Convert channel 0 (PA.0) with 71.5 cycles sample time
33
  ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 7, ADC_SampleTime_71Cycles5);    // Convert channel 0 (PA.0) with 71.5 cycles sample time
34
  ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 8, ADC_SampleTime_71Cycles5);    // Convert channel 0 (PA.0) with 71.5 cycles sample time
35
  ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 9, ADC_SampleTime_71Cycles5);    // Convert channel 0 (PA.0) with 71.5 cycles sample time
36
  ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 10, ADC_SampleTime_71Cycles5);   // Convert channel 0 (PA.0) with 71.5 cycles sample time
37
  ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 11, ADC_SampleTime_71Cycles5);   // Convert channel 0 (PA.0) with 71.5 cycles sample time
38
  ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 12, ADC_SampleTime_71Cycles5);   // Convert channel 0 (PA.0) with 71.5 cycles sample time
39
  
40
  ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 13, ADC_SampleTime_71Cycles5);   // Convert channel 0 (PA.0) with 71.5 cycles sample time
41
  ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 14, ADC_SampleTime_71Cycles5);   // Convert channel 0 (PA.0) with 71.5 cycles sample time


ADC Routine
1
void ADC1_2_IRQHandler(void)
2
{
3
  int i;
4
5
  //GPIO_SetBits(TEST0_PORT, TEST0_PIN);
6
7
  ADC_ClearITPendingBit(ADC1, ADC_IT_JEOC);        // Clear ADC1 JEOC pending interrupt bit
8
9
  // shift median buffer one position left
10
  for (i = 0; i < ADC_MEDIAN_BUFFERSIZE-1; i++)
11
      MedianBuffer[AdcTmpMux][i] = MedianBuffer[AdcTmpMux][i+1];
12
13
  //ACHTUNG: ADC results muss angepasst werden, 27 Kanäle!
14
  // store actual conversion result at last position of median buffer
15
  MedianBuffer[AdcTmpMux][ADC_MEDIAN_BUFFERSIZE-1] = AdcResults[AdcTmpMux];
16
17
18
  // Next Multiplexer State for temperature measurement
19
  AdcTmpMux++;
20
21
  //After the first 15 AD Conversions, Switch main-multiplexer for next 12 temp channels on
22
  if ((AdcTmpMux>ADC_SENS_ZONE_L)|(ToggleUpLowChannels=0)){
23
    AdcTmpMux=ADC_SENS_ZONE_A;          // Start again with First Zone, but -->
24
    ToggleUpLowChannels=1;            // Set main Mux Switch to get the upper 12 channels
25
  };
26
27
  //Check if all Channels are converted
28
  if (++AdcTmpMux >= ADC_SENS_MUX_CNT){
29
    AdcTmpMux = 0;                      // Restart with first channel
30
    ToggleUpLowChannels=0;              // Reset the main Mux to get the lower channels (next loop)
31
  }
32
  //AN dieser Stelle muss der zusätzliche GPIO Pin  T_SEL_SW_1 rein um die zweiten 12 Eingänge zu multiplexen
33
  //wenn adctempmux >12 oder so,
34
35
  // reset all active low temperature sensor selection signals
36
  GPIO_SetBits(TSEL_REF0_PORT, TSEL_REF0_PIN);
37
  GPIO_SetBits(TSEL_REF130_PORT, TSEL_REF130_PIN);
38
  GPIO_SetBits(TSEL_ZONE_A_PORT, TSEL_ZONE_A_PIN);
39
  GPIO_SetBits(TSEL_ZONE_B_PORT, TSEL_ZONE_B_PIN);
40
  GPIO_SetBits(TSEL_ZONE_C_PORT, TSEL_ZONE_C_PIN);
41
  GPIO_SetBits(TSEL_ZONE_D_PORT, TSEL_ZONE_D_PIN);
42
  GPIO_SetBits(TSEL_ZONE_E_PORT, TSEL_ZONE_E_PIN);
43
  GPIO_SetBits(TSEL_ZONE_F_PORT, TSEL_ZONE_F_PIN);
44
  GPIO_SetBits(TSEL_ZONE_G_PORT, TSEL_ZONE_G_PIN);
45
  GPIO_SetBits(TSEL_ZONE_H_PORT, TSEL_ZONE_H_PIN);
46
47
  GPIO_SetBits(TSEL_ZONE_I_PORT, TSEL_ZONE_I_PIN);
48
  GPIO_SetBits(TSEL_ZONE_J_PORT, TSEL_ZONE_J_PIN);
49
  GPIO_SetBits(TSEL_ZONE_K_PORT, TSEL_ZONE_K_PIN);
50
  GPIO_SetBits(TSEL_ZONE_L_PORT, TSEL_ZONE_L_PIN);
51
52
  GPIO_SetBits(TSEL_HCP_PORT, TSEL_HCP_PIN);
53
54
55
  // select next temperature sensor for following conversion
56
  switch (AdcTmpMux)
57
  {
58
    case ADC_REF0:
59
      GPIO_ResetBits(TSEL_REF0_PORT, TSEL_REF0_PIN);
60
      break;
61
62
    case ADC_REF130:
63
      GPIO_ResetBits(TSEL_REF130_PORT, TSEL_REF130_PIN);
64
      break;
65
66
    case ADC_SENS_ZONE_A:
67
      GPIO_ResetBits(TSEL_ZONE_A_PORT, TSEL_ZONE_A_PIN);
68
      break;
69
70
    case ADC_SENS_ZONE_B:
71
      GPIO_ResetBits(TSEL_ZONE_B_PORT, TSEL_ZONE_B_PIN);
72
      break;
73
74
    case ADC_SENS_ZONE_C:
75
      GPIO_ResetBits(TSEL_ZONE_C_PORT, TSEL_ZONE_C_PIN);
76
      break;
77
78
    case ADC_SENS_ZONE_D:
79
      GPIO_ResetBits(TSEL_ZONE_D_PORT, TSEL_ZONE_D_PIN);
80
      break;
81
82
    case ADC_SENS_ZONE_E:
83
      GPIO_ResetBits(TSEL_ZONE_E_PORT, TSEL_ZONE_E_PIN);
84
      break;
85
86
    case ADC_SENS_ZONE_F:
87
      GPIO_ResetBits(TSEL_ZONE_F_PORT, TSEL_ZONE_F_PIN);
88
      break;
89
90
    case ADC_SENS_ZONE_G:
91
      GPIO_ResetBits(TSEL_ZONE_G_PORT, TSEL_ZONE_G_PIN);
92
      break;
93
94
    case ADC_SENS_ZONE_H:
95
      GPIO_ResetBits(TSEL_ZONE_H_PORT, TSEL_ZONE_H_PIN);
96
      break;
97
98
99
100
    case ADC_SENS_ZONE_I:
101
      GPIO_ResetBits(TSEL_ZONE_I_PORT, TSEL_ZONE_I_PIN);
102
      break;
103
104
    case ADC_SENS_ZONE_J:
105
      GPIO_ResetBits(TSEL_ZONE_J_PORT, TSEL_ZONE_J_PIN);
106
      break;
107
108
    case ADC_SENS_ZONE_K:
109
      GPIO_ResetBits(TSEL_ZONE_K_PORT, TSEL_ZONE_K_PIN);
110
      break;
111
112
    case ADC_SENS_ZONE_L:
113
      GPIO_ResetBits(TSEL_ZONE_L_PORT, TSEL_ZONE_L_PIN);
114
      break;
115
116
    case ADC_SENS_HCP:
117
      GPIO_ResetBits(TSEL_HCP_PORT, TSEL_HCP_PIN);
118
      break;
119
120
    default:
121
      break;
122
123
      //ACHTUNG!! hier muss das toggle bit den zusätzlich ausgang setzen
124
  }
125
  //GPIO_ResetBits(TEST0_PORT, TEST0_PIN);
126
}

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.