Hallo zusammen, ich habe ein STM32F4 Discovery Board und will ein Programm schreiben, welches nach dem Drücken des user buttons auf dem Board einen Interrupt auslöst. Daraufhin soll dann ein Array mit ADC Samples gefüllt werden. Das ganze auch noch in Verbindung mit dem DMA Controller. Wenn das Array gefüllt ist, soll wieder ein Interrupt ausgelöst werden. Ich habe es vorher schon geschafft mit DMA Controller und ADC ein Array mit ADC Samples zu füllen. Der Interrupt des user buttons wird richtig ausgelöst, aber dann schaff ich es nicht die Analog-Digital-Wandlungen ans laufen zu bringen. Hier mal mein Code, kann gut sein, dass die eine oder andere Stelle aktuell keinen Sinn macht, weil ich recht viel rumprobiert habe. #include <stdbool.h> #include "misc.h" #include "stm32f4xx.h" #include "stm32f4xx_gpio.h" #include "stm32f4xx_rcc.h" #include "stm32f4xx_adc.h" #include "stm32f4xx_dma.h" #include "stm32f4xx_tim.h" #include "stm32f4xx_exti.h" #include "stm32f4xx_syscfg.h" //################GLOBAL VARIABLES############### #define BUFFER_SIZE 2048 volatile uint32_t dest_array[BUFFER_SIZE]; volatile uint16_t result = 0; //################LOCAL FUNCTIONS############### void Delay(__IO uint32_t nCount) { while(nCount--) { } } //function to initialize interrupt on user button pressed static void EXTILine0_Config(void) { EXTI_InitTypeDef EXTI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; // Enable GPIOA clock RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); // Enable SYSCFG clock RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); // Configure PA0 pin as input floating GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_Init(GPIOA, &GPIO_InitStructure); // Connect EXTI Line0 to PA0 pin SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0); // Configure EXTI Line0 EXTI_InitStructure.EXTI_Line = EXTI_Line0; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); // Enable and set EXTI Line0 Interrupt to the lowest priority NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } //function to initialize ADC2 static void ADC2_Init(void) { //Init GPIOA GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStructure); //initialize ADC2 //enable clock RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE); //create ADC_Init structure ADC_CommonInitTypeDef ADC_CommonInitStructure; ADC_InitTypeDef ADC_InitStructure; //initialize initStructs ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2; ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1; //WTF doesn't change anything ADC_InitStructure.ADC_NbrOfConversion = 1; ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; ADC_InitStructure.ADC_ScanConvMode = ENABLE; //adc init ADC_CommonInit(&ADC_CommonInitStructure); ADC_Init(ADC2, &ADC_InitStructure); //configurate channel ADC_RegularChannelConfig(ADC2, ADC_Channel_4, 1, ADC_SampleTime_480Cycles); //enable ADC EOC IT //ADC_ITConfig(ADC2, ADC_IT_EOC, ENABLE); } //function to initialize DMA2 static void DMA2_Init(void) { // Clock Enable RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); //initialize DMA controller DMA_InitTypeDef DMA_InitStructure; // DMA-Disable DMA_Cmd(DMA2_Stream2, DISABLE); DMA_DeInit(DMA2_Stream2); //initialize DMA_Init structure DMA_InitStructure.DMA_BufferSize = BUFFER_SIZE; DMA_InitStructure.DMA_Channel = DMA_Channel_1; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&dest_array; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC2->DR; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; DMA_Init(DMA2_Stream2, &DMA_InitStructure); DMA_Cmd(DMA2_Stream2, ENABLE); ADC_DMARequestAfterLastTransferCmd(ADC2, DISABLE); DMA_ITConfig(DMA2_Stream2, DMA_IT_TC, ENABLE); } //interrupt handler for EXTI0 (user button pressed) void EXTI0_IRQHandler(void) { if(EXTI_GetITStatus(EXTI_Line0) != RESET) { //do 2048 ADC conversions and save data with DMA controller //start ADC2 once, interrupt does the rest ADC_SoftwareStartConv(ADC2); } // Clear the EXTI line 0 pending bit EXTI_ClearITPendingBit(EXTI_Line0); } //interrupt handler for ADC2 (end of conversion EOC IT) //interrupt currently deactivated void ADC1_2_IRQHandler(void) { if(ADC_GetITStatus(ADC2, ADC_IT_EOC) != RESET) { Delay(1000); } } void DMA2_Stream2_IRQHandler(void) { //should be reached if buffer is filled complete //disable adc2; enable on next user button pressed ADC_Cmd(ADC2, DISABLE); //TODO: generate software interrupt } //#########################MAIN####################### int main(void) { SystemInit(); // set clock settings EXTILine0_Config(); ADC2_Init(); DMA2_Init(); int i; for(i=0;i<BUFFER_SIZE;i++) { dest_array[i] = i; } while(1) { //interrupt does the job } }
Ich kann dir zwar nicht genau helfen, aber an deiner Stelle würde ich versuchen den ADC/DMA Start erst einmal nicht mit einem interrupt, sondern "normal" über eine if-abfrage zu starten. Wenn das dann läuft, weißt du es liegt am interrupt für den Taster, ansonsten beim ADC/DMA
So, hab aufjedenfall einen Fehler gefuden. Habe dummerweise vergessen den ADC zu starten. //enable ADC ADC_DMACmd(ADC2, ENABLE); ADC_Cmd(ADC2, ENABLE); ADC_DMARequestAfterLastTransferCmd(ADC2, ENABLE); In den Interrupt vom user button wird schön reingesprungen. Da starte ich jetzt die ADC conversion. Das klappt soweit. Allerdings wird nicht in den Interrupt vom ADC (ADC_IT_EOC) und nicht in den vom DMA Controller (DMA_IT_TC) gesprungen. Kann mir jemand dabei helfen woran das liegt? Ziel ist es, wie oben schon beschrieben, nach dem Drücken des Buttons beispielsweise 2048 Messwerte mit dem ADC aufzunehmen, diese mit dem DMA wegzuschreiben und danach einen Interrupt zu erzeugen. Ich könnte natürlich eine Schleife schreiben und 2048 ADC conversions starten, aber ich denke das muss auch irgendwie schöner gehen. Vielen Dank schonmal.
> DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; Warum lößt du den DMA Interrupt bei Halbvoll aus wenn du aber eigentlich 2048 Sampels haben willst? > //interrupt handler for EXTI0 (user button pressed) > void EXTI0_IRQHandler(void) > { Hier fehlt eine Sperrflag das verhindert das dass Tastenprellen (oder auch ein erneutes drücken) den ADC immer wieder neu startet wenn es schon/noch läuft. > //interrupt handler for ADC2 (end of conversion EOC IT) > //interrupt currently deactivated > void ADC1_2_IRQHandler(void) > { > if(ADC_GetITStatus(ADC2, ADC_IT_EOC) != RESET) > { > Delay(1000); > } > } > Delay innerhalb einer ISR. Der bloße Gedanke daran gehört eigentlich schon mit heftigen ..... bestraft:-) > void DMA2_Stream2_IRQHandler(void) > { Hier eine Flag setzen das die Daten "fertig" sind und weiterverarbeitet werden können. Wenn die main die Daten verarbeitet hat kann sie dann beide Flags zurücksetzen uns das System ist bereit für einen neuen Start...
Peter N. schrieb: > Allerdings wird nicht in den Interrupt vom ADC (ADC_IT_EOC) und nicht in > den vom DMA Controller (DMA_IT_TC) gesprungen. Kann mir jemand dabei > helfen woran das liegt? Vielleicht noch die Interrupts mit NVIC aktivieren?
Danke für deine Antwort Irgendwer. Ich habe jetzt mal die DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; gesetzt. Aber das macht eigentlich keinen Unterschied. Ich habe bisher gedacht, dass diese Option einstellt, wie lange der DMA Daten in seinem FIFO zwischenspeichert, bis er einmal alles an die destination schreibt. Ich glaub eigentlich nicht, dass das irgendwas mit dem DMA Interrupt zu tun hat oder? Habe jetzt ein Sperrflag im EXTI0_IRQHandler eingebaut. Gute Idee.
Peter N. schrieb: > Ich habe jetzt mal die DMA_InitStructure.DMA_FIFOThreshold = > DMA_FIFOThreshold_Full; gesetzt. Aber das macht eigentlich keinen > Unterschied. Ich habe bisher gedacht, dass diese Option einstellt, wie > lange der DMA Daten in seinem FIFO zwischenspeichert, bis er einmal > alles an die destination schreibt. Ja, sorry. Hier hatte ich auf die schnelle was verwechselt (es gibt auch einen Mode wo bei "Half-transfer" bereits ein irq ausgelößt wird). Du hast ja ohnehin DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; so das die Einstellungen für den FiFo egal sind. Was mir aber noch merkwürdig erscheint ist: > volatile uint32_t dest_array[BUFFER_SIZE]; > DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; Das Arrey ist DWord, du stellst aber unter Size Word ein(was ja durchaus zum ADC passt). Beim auslesen das Arrys hast du dann aber zwei Werte in einer 32Bit Variable. Und warum: > DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; wenn du am ende eh anhalten willst und manuell neustarten? Was ich irgendwie garnicht bei dir finde ist das Gegenstück zu z.B. > // Transfer complete interrupt enable > DMA1_S5_CR.TCIE=1; (keine Ahnung wo das genau in den ST-Beispielfunktionen versteckt ist) wo du den "Transfer complete" Interrupt überhaupt aktivierst? Table 43. DMA interrupt requests Half-transfer HTIF HTIE Transfer complete TCIF TCIE Transfer error TEIF TEIE FIFO overrun/underrun FEIF FEIE Direct mode error DMEIF DMEIE
Thomas W. schrieb: > Vielleicht noch die Interrupts mit NVIC aktivieren? Okay danke, das hab ich gemacht und jetzt funktionieren die Interrupts. Irgendwer schrieb: > Ja, sorry. Hier hatte ich auf die schnelle was verwechselt (es gibt auch > einen Mode wo bei "Half-transfer" bereits ein irq ausgelößt wird). > Du hast ja ohnehin DMA_InitStructure.DMA_FIFOMode = > DMA_FIFOMode_Disable; so das die Einstellungen für den FiFo egal sind. Jo, hab den FIFO jetzt mal aktiviert und auf full transfer gestellt. Jetzt wartet der immer, bis 4 Messwerte vorliegen und schreibt die dann ins dest_array. > Was mir aber noch merkwürdig erscheint ist: >> volatile uint32_t dest_array[BUFFER_SIZE]; >> DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; > Das Arrey ist DWord, du stellst aber unter Size Word ein(was ja durchaus > zum ADC passt). Beim auslesen das Arrys hast du dann aber zwei Werte in > einer 32Bit Variable. Also ich weiß nicht warum, aber die Werte im Array passen. Ich hab den Pin den ich auslese auf 3V gezogen und ich hab Werte im Array, die meist recht nahe bei 4095 liegen. Das Array muss aber scheinbar uint32_t sein, weil die Adresse dieses Format hat? > Was ich irgendwie garnicht bei dir finde ist das Gegenstück zu z.B. >> // Transfer complete interrupt enable >> DMA1_S5_CR.TCIE=1; (keine Ahnung wo das genau in den ST-Beispielfunktionen > versteckt ist) > wo du den "Transfer complete" Interrupt überhaupt aktivierst? Den aktiviere ich in der letzten Zeile der Funktion DMA2_Init() und halt jetzt noch mir NVIC...
1 | DMA_ITConfig(DMA2_Stream2, DMA_IT_TC, ENABLE); |
Soweit läuft das jetzt. Ich versuche jetzt den ADC mit einem Timer zu triggern. Vielen Dank für eure Hilfe, schönes Wochenende.
Hey, leider habe ich auch Probleme damit den ADC mit einem Timer zu triggern. Ich habe mich unter anderem an diesem Beispiel orientiert: Beitrag "stm32F4 + ADC + Timer + DMA" Aber der ADC wird irgendwie nicht durch den Timer getriggert. Wenn ich den user button des Discoveryboards drücke, wird eine ADC Wandlung durchgeführt. Ziel ist es nach dem Drücken des Buttons das Array mit Messwerten voll zu schreiben, die mit der Frequenz mit der der Timer triggert gesamplet wurden. Hier mein aktueller Code:
1 | //#include "main.h"
|
2 | #include <stdbool.h> |
3 | #include "misc.h" |
4 | #include "stm32f4xx.h" |
5 | #include "stm32f4xx_gpio.h" |
6 | #include "stm32f4xx_rcc.h" |
7 | #include "stm32f4xx_adc.h" |
8 | #include "stm32f4xx_dma.h" |
9 | #include "stm32f4xx_tim.h" |
10 | #include "stm32f4xx_exti.h" |
11 | #include "stm32f4xx_syscfg.h" |
12 | |
13 | //################GLOBAL VARIABLES###############
|
14 | #define BUFFER_SIZE 2048
|
15 | volatile uint32_t dest_array[BUFFER_SIZE]; |
16 | volatile uint16_t result = 0; |
17 | volatile bool button_pressed = false; |
18 | volatile bool conversion_finished = false; |
19 | |
20 | //#################LOCAL FUNCTIONS###############
|
21 | void Delay(__IO uint32_t nCount) { |
22 | while(nCount--) { |
23 | }
|
24 | }
|
25 | |
26 | //function to initialize interrupt on user button pressed
|
27 | static void EXTILine0_Config(void) |
28 | {
|
29 | [...]
|
30 | }
|
31 | |
32 | //function to initialize ADC2
|
33 | static void ADC2_Init(void) |
34 | {
|
35 | //Init GPIOA
|
36 | GPIO_InitTypeDef GPIO_InitStructure; |
37 | |
38 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; |
39 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; |
40 | GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; |
41 | GPIO_Init(GPIOA, &GPIO_InitStructure); |
42 | |
43 | //initialize ADC2
|
44 | |
45 | //enable clock
|
46 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE); |
47 | |
48 | //create ADC_Init structure
|
49 | ADC_CommonInitTypeDef ADC_CommonInitStructure; |
50 | ADC_InitTypeDef ADC_InitStructure; |
51 | |
52 | //initialize initStructs
|
53 | ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; |
54 | ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; |
55 | ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2; |
56 | ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles; |
57 | |
58 | ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; |
59 | ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; |
60 | ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising; |
61 | ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO; |
62 | ADC_InitStructure.ADC_NbrOfConversion = 1; |
63 | ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; |
64 | ADC_InitStructure.ADC_ScanConvMode = DISABLE; |
65 | |
66 | //adc init
|
67 | ADC_CommonInit(&ADC_CommonInitStructure); |
68 | ADC_Init(ADC2, &ADC_InitStructure); |
69 | |
70 | //configurate channel
|
71 | ADC_RegularChannelConfig(ADC2, ADC_Channel_4, 1, ADC_SampleTime_15Cycles); |
72 | |
73 | //enable ADC EOC IT
|
74 | //ADC_ITConfig(ADC2, ADC_IT_EOC, ENABLE);
|
75 | |
76 | //enable ADC
|
77 | ADC_DMARequestAfterLastTransferCmd(ADC2, ENABLE); |
78 | ADC_DMACmd(ADC2, ENABLE); |
79 | ADC_Cmd(ADC2, ENABLE); |
80 | |
81 | //init ADC interrupt
|
82 | NVIC_InitTypeDef NVIC_InitStructure; |
83 | |
84 | NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQn; |
85 | NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; |
86 | NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; |
87 | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; |
88 | NVIC_Init(&NVIC_InitStructure); |
89 | }
|
90 | |
91 | //function to initialize DMA2
|
92 | static void DMA2_Init(void) |
93 | {
|
94 | // Clock Enable
|
95 | RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); |
96 | |
97 | //initialize DMA controller
|
98 | DMA_InitTypeDef DMA_InitStructure; |
99 | |
100 | // DMA-Disable
|
101 | DMA_Cmd(DMA2_Stream2, DISABLE); |
102 | DMA_DeInit(DMA2_Stream2); |
103 | |
104 | //initialize DMA_Init structure
|
105 | DMA_InitStructure.DMA_BufferSize = BUFFER_SIZE; |
106 | DMA_InitStructure.DMA_Channel = DMA_Channel_1; |
107 | DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; |
108 | DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable; |
109 | DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; |
110 | DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&dest_array; |
111 | DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; |
112 | DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; |
113 | DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; |
114 | DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; |
115 | DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC2->DR; |
116 | DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; |
117 | DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; |
118 | DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; |
119 | DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; |
120 | |
121 | DMA_Init(DMA2_Stream2, &DMA_InitStructure); |
122 | DMA_Cmd(DMA2_Stream2, ENABLE); |
123 | |
124 | ADC_DMARequestAfterLastTransferCmd(ADC2, ENABLE); |
125 | DMA_ITConfig(DMA2_Stream2, DMA_IT_TC, ENABLE); |
126 | |
127 | NVIC_InitTypeDef NVIC_InitStructure; |
128 | |
129 | NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream2_IRQn; |
130 | NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; |
131 | NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; |
132 | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; |
133 | |
134 | NVIC_Init(&NVIC_InitStructure); |
135 | }
|
136 | |
137 | //function to initialize Timer 2
|
138 | static void Timer_Init(void) |
139 | {
|
140 | RCC_AHB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); |
141 | |
142 | //TIM intit structure
|
143 | TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; |
144 | |
145 | //config init structure
|
146 | TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; |
147 | TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; |
148 | TIM_TimeBaseStructure.TIM_Period = 84-1; |
149 | TIM_TimeBaseStructure.TIM_Prescaler = 1000-1; |
150 | //TIM_TimeBaseStructure.TIM_RepetitionCounter = ?;
|
151 | |
152 | TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); |
153 | TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update); |
154 | //TIM_Cmd(TIM2, ENABLE);
|
155 | |
156 | }
|
157 | |
158 | //interrupt handler for EXTI0 (user button pressed)
|
159 | void EXTI0_IRQHandler(void) |
160 | {
|
161 | if(EXTI_GetITStatus(EXTI_Line0) != RESET) |
162 | {
|
163 | if(button_pressed == false) |
164 | {
|
165 | button_pressed = true; |
166 | //start ADC2 once, interrupt does the rest
|
167 | ADC_SoftwareStartConv(ADC2); |
168 | }
|
169 | }
|
170 | // Clear the EXTI line 0 pending bit
|
171 | EXTI_ClearITPendingBit(EXTI_Line0); |
172 | }
|
173 | |
174 | //interrupt handler for ADC2 (end of conversion EOC IT)
|
175 | void ADC_IRQHandler() |
176 | {
|
177 | //ADC_SoftwareStartConv(ADC2);
|
178 | }
|
179 | |
180 | void DMA2_Stream2_IRQHandler(void) |
181 | {
|
182 | //should be reached if buffer is filled complete
|
183 | //TODO: generate software interrupt
|
184 | if(conversion_finished == false) |
185 | {
|
186 | conversion_finished = true; |
187 | }
|
188 | }
|
189 | |
190 | |
191 | |
192 | //#########################MAIN#######################
|
193 | int main(void) |
194 | {
|
195 | SystemInit(); // set clock settings |
196 | EXTILine0_Config(); |
197 | Timer_Init(); |
198 | ADC2_Init(); |
199 | DMA2_Init(); |
200 | |
201 | int i; |
202 | for(i=0;i<BUFFER_SIZE;i++) |
203 | {
|
204 | dest_array[i] = i; |
205 | }
|
206 | //enable timer
|
207 | TIM_Cmd(TIM2, ENABLE); |
208 | |
209 | while(1) |
210 | {
|
211 | //interrupt does the job
|
212 | }
|
213 | }
|
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.