mit dieser Library kann der ADC per DMA zyklisch ausgelesen werden um die CPU last zu senken. Es können maximal 16 ADC-Kanäle pro AD-Wandler festgelegt werden.
die Einstellung erfolgt (wie in der ADC-Single-Conversation-Library) als Struktur im C-File. Dort müssen die ADC-Pins den Port-Pins zugeordnet werden.
es sind wieder drei LIBs getrennt für ADC1, ADC2 und ADC3. Die können aber auch gleichzeitig benutzt werden falls mehr als 16 ADC-Kanäle notwendig sind.
im Beispiel werden nur 2 Kanäle benutzt um das Prinzip zu verdeutlichen.
1 | PA5, PC3 |
Enumerationen (für ADC1) :
1 2 3 4 | typedef enum { ADC_PA5 = 0, // PA5 ADC_PC3 = 1 // PC3 }ADC1d_NAME_t; |
Funktionen (für ADC1) :
1 2 | void UB_ADC1_DMA_Init(void); // zum initialisieren und starten uint16_t UB_ADC1_DMA_Read(ADC1d_NAME_t adc_name); // zum auslesen eines ADC-Kanals |
Beispiel :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | //-------------------------------------------------------------- // File : main.c // Datum : 31.10.2013 // Version : 1.0 // Autor : UB // EMail : mc-4u(@)t-online.de // Web : www.mikrocontroller-4u.de // CPU : STM32F429 // IDE : CooCox CoIDE 1.7.4 // GCC : 4.7 2012q4 // Module : CMSIS_BOOT, M4_CMSIS_CORE // Funktion : Demo der ADC-DMA-Library // Hinweis : Diese zwei Files muessen auf 8MHz stehen // "cmsis_boot/stm32f4xx.h" // "cmsis_boot/system_stm32f4xx.c" // In Configuration diese Define hinzufügen : // "STM32F429_439xx" , "__ASSEMBLY__" , "USE_STDPERIPH_DRIVER" //-------------------------------------------------------------- #include "main.h" #include "stm32_ub_lcd_ili9341.h" #include "stm32_ub_font.h" #include "stm32_ub_adc1_dma.h" #include <stdio.h> int main(void) { uint16_t adc_wert; char buf[20]; SystemInit(); // Quarz Einstellungen aktivieren // Init vom LCD UB_LCD_Init(); // Init vom ADC (im DMA-Mode) UB_ADC1_DMA_Init(); // Init der Layer UB_LCD_LayerInit_Fullscreen(); // auf Hintergrund schalten UB_LCD_SetLayer_1(); // Hintergrund komplett mit einer Farbe füllen UB_LCD_FillLayer(RGB_COL_WHITE); // auf Vordergrund schalten UB_LCD_SetLayer_2(); // Vordergrund komplett mit einer Farbe füllen UB_LCD_FillLayer(RGB_COL_GREEN); // Ueberschrift UB_Font_DrawString(10,10,"Demo_10 : ",&Arial_11x18,RGB_COL_WHITE,RGB_COL_RED); UB_Font_DrawString(10,30,"ADC-DMA ",&Arial_11x18,RGB_COL_WHITE,RGB_COL_RED); while(1) { // ADC-Wert auslesen adc_wert=UB_ADC1_DMA_Read(ADC_PA5); sprintf(buf,"PA5 = %4d",adc_wert); UB_Font_DrawString(10,100,buf,&Arial_11x18,RGB_COL_BLACK,RGB_COL_GREEN); // ADC-Wert auslesen adc_wert=UB_ADC1_DMA_Read(ADC_PC3); sprintf(buf,"PC3 = %4d",adc_wert); UB_Font_DrawString(10,150,buf,&Arial_11x18,RGB_COL_BLACK,RGB_COL_GREEN); } } |
Hier die Library zum Download :
Hier der komplette CooCox-Projektordner zum Download :
Hallo,
erstmals Vielen Dank für die schönen Beispiele.
Ich habe eine Frage zu dem DMA Beispiel. Ich möchte gerne mit 2,4MSPS sampeln.
Wenn ich nun in der Zeile “ADC_RegularChannelConfig(ADC1, ADC1d[adc_name].ADC_CH, adc_name+1, ADC_SampleTime_28Cycles);” die Cycles auf 3 stelle anstatt 28 geht es nicht mehr. Verstehe nicht ganz warum.
Die Zeit hatte ich auch schonmal versucht im Interrupt zu überprüfen. Leider hängt er dann dort fest.
Vielen Dank
Gruß
Björn
ja…scheint ein BUG zu sein k.A. warum. Die CPU läuft noch, nur der ADC “hängt”.