von
Michl (Gast)
09.01.2012 09:32
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.