STM32F103 ADC per Timer triggern (SPL)

Gast #4742621
Lesenswert?

Ich finde leider den Fehler nicht: Capture 2 funktioniert (Interrupt), 
löst aber nicht den ADC aus. Offenbar fehlt etwas - aber was?

1
#include "stm32f10x_conf.h"
2

3
int main(void)
4
{
5

6
    SystemInit();
7

8

9
    // Interrupts
10
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
11

12
    NVIC_InitTypeDef NVIC_InitStructure;
13

14
    NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;
15
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
16
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;
17
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
18
    NVIC_Init(&NVIC_InitStructure);
19

20

21
    NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
22
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
23
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;
24
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
25
    NVIC_Init(&NVIC_InitStructure);
26

27

28

29
    // Clocks
30

31
    RCC_ADCCLKConfig(RCC_PCLK2_Div6);
32

33
    RCC_APB2PeriphClockCmd(
34
        RCC_APB2Periph_GPIOA |
35
        RCC_APB2Periph_GPIOB |
36
        RCC_APB2Periph_AFIO  |
37
        RCC_APB2Periph_TIM1  |
38
        RCC_APB2Periph_ADC1  ,
39
        ENABLE
40
        );
41

42

43

44
    // IO
45

46
    GPIO_InitTypeDef GPIO_InitStructure;
47

48
    GPIO_StructInit(&GPIO_InitStructure);
49

50
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
51
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;       // AF: adc
52
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
53

54
    GPIO_Init(GPIOA, &GPIO_InitStructure);
55

56

57
    GPIO_StructInit( &GPIO_InitStructure );
58

59
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
60
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;     // AF: timer 1 pwm
61
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
62

63
    GPIO_Init(GPIOA, &GPIO_InitStructure);
64

65

66
    GPIO_StructInit( &GPIO_InitStructure );
67

68
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
69
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
70
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
71

72
    GPIO_Init(GPIOB, &GPIO_InitStructure);
73

74

75

76
    // ADC
77

78
    ADC_InitTypeDef ADC_InitStructure;
79

80
    ADC_StructInit(&ADC_InitStructure);
81

82
    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
83
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC2;
84
    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
85
    ADC_InitStructure.ADC_ScanConvMode = DISABLE;
86
    ADC_InitStructure.ADC_NbrOfChannel = 1;
87
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
88

89
    ADC_Init(ADC1, &ADC_InitStructure);
90

91
    ADC_RegularChannelConfig(
92
         ADC1,
93
         ADC_Channel_1,
94
         1,                         // The rank in the regular group sequencer. This parameter must be between 1 to 16.
95
         ADC_SampleTime_1Cycles5
96
         );
97

98
    ADC_ExternalTrigConvCmd(ADC1, ENABLE);
99

100
    ADC_ClearITPendingBit(ADC1, ADC_IT_EOC);
101
    ADC_ITConfig(ADC1, ADC1_2_IRQn, ENABLE);
102

103

104
    ADC_Cmd(ADC1, ENABLE);
105

106

107
    // calibrate
108
    ADC_ResetCalibration(ADC1);
109
    while(ADC_GetResetCalibrationStatus(ADC1));
110

111
    ADC_StartCalibration(ADC1);
112
    while(ADC_GetCalibrationStatus(ADC1));
113

114

115

116

117
/*
118
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);
119
    while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
120
    ADC_ClearFlag(ADC1, ADC_FLAG_EOC);
121
    uint16_t value = ADC_GetConversionValue(ADC1);
122
*/
123

124
    // PWM Timer 1
125

126
    TIM_TimeBaseInitTypeDef TIM_TimeBase_InitStructure;
127

128
    TIM_TimeBaseStructInit( &TIM_TimeBase_InitStructure );
129

130
    TIM_TimeBase_InitStructure.TIM_CounterMode =    TIM_CounterMode_Up;
131
    TIM_TimeBase_InitStructure.TIM_ClockDivision =  TIM_CKD_DIV1;
132
    TIM_TimeBase_InitStructure.TIM_Prescaler =      32;
133
    TIM_TimeBase_InitStructure.TIM_Period =         1023;
134

135
    TIM_TimeBaseInit(TIM1, &TIM_TimeBase_InitStructure);
136

137

138

139
    // CC1 PWM
140
    TIM_OCInitTypeDef   TIM_OC_InitStructure;
141

142
    TIM_OCStructInit( &TIM_OC_InitStructure );
143

144
    TIM_OC_InitStructure.TIM_OCMode =       TIM_OCMode_PWM1;
145
    TIM_OC_InitStructure.TIM_OCIdleState =  TIM_OCIdleState_Reset;
146
    TIM_OC_InitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
147
    TIM_OC_InitStructure.TIM_OCPolarity =   TIM_OCPolarity_High;
148
    TIM_OC_InitStructure.TIM_OCNPolarity =  TIM_OCNPolarity_Low;
149
    TIM_OC_InitStructure.TIM_Pulse =        127;
150
    TIM_OC_InitStructure.TIM_OutputState =  TIM_OutputState_Enable;
151
    TIM_OC_InitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
152
    TIM_OC1Init(TIM1, &TIM_OC_InitStructure);
153

154
    TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
155

156

157
    // CC2 ADC
158
    TIM_OCStructInit( &TIM_OC_InitStructure );
159
    TIM_OC_InitStructure.TIM_Pulse =        511;
160
    TIM_OC2Init(TIM1, &TIM_OC_InitStructure);
161

162
    TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
163

164

165
    TIM_ClearITPendingBit(TIM1, TIM_IT_CC2);
166
    TIM_ITConfig(TIM1, TIM_IT_CC2, ENABLE);
167

168

169

170
    TIM_Cmd(TIM1, ENABLE);
171

172
    TIM_CtrlPWMOutputs(TIM1, ENABLE);
173

174

175

176
  while(1)
177
  {
178

179
  }
180
}
181

182

183

184
void ADC1_2_IRQHandler(void){
185

186

187
        if( ADC_GetITStatus(ADC1, ADC_IT_EOC) == SET){
188
            ADC_ClearITPendingBit(ADC1, ADC_IT_EOC);
189

190
            GPIO_ResetBits(GPIOB, GPIO_Pin_14);
191
        }
192
}
193

194

195

196
void TIM1_CC_IRQHandler(void)
197
{
198
    if( TIM_GetITStatus(TIM1, TIM_IT_CC1) == SET ){
199
        TIM_ClearITPendingBit(TIM1, TIM_IT_CC1);
200
    }
201

202

203
    if( TIM_GetITStatus(TIM1, TIM_IT_CC2) == SET ){
204
        TIM_ClearITPendingBit(TIM1, TIM_IT_CC2);
205

206
        if(GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_14) == SET)
207
            GPIO_ResetBits(GPIOB, GPIO_Pin_14);
208
        else
209
            GPIO_SetBits(GPIOB, GPIO_Pin_14);
210

211
    }
212
}
Gast #4743957
Lesenswert?

Die Doku ist irreführend. Der externe Trigger des ADCs ist kein direktes 
"internes Signal" von der CC, sondern nutzt dessen Ausgangssignal, 
sprich, das (PWM-) Signal, und dort auch nur eine steigende Flanke. Um 
zum Comparezeitpunkt den ADC zu starten, muss also eine invertierte PWM 
erzeugt werden. Sie muss jedoch nicht zwangsläufig über den GPIO 
ausgegeben werden. Allerdings lässt sich dann wahrscheinlich eine 
weitere alternate function für den Pin nicht mehr nutzen, wenn dort 
schon der Timer aktiv ist.

Das ist etwas enttäuschend; ich hätte gedacht, 
timersynchrone/-gesteuerte Messungen wären an der Tagesordnung und daher 
einfach möglich, sprich per echtem, direktem "Event" von der 
Compare-Einheit.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren