Hi, bin auf de Suche nach einem einfachen Beispiel, wie man die AD Wandler vom STM32 ansteuert. Habe bisher nur komplexere Beispiele mit DMA gefunden, allerdings möchte ich nur alle 10ms zwei Werte abfragen, also wäre DMA ein bisschen übertrieben. Vielleicht hat ja jemand sogar schon eine komplett fertige Bibliothek für das Auslesen von Touchpads für dei DOGM128 Display Reihe :-))
Hier ein Bsp. für 4 Pin analoges Touch von meinen TFT 320x240. Musst es noch etwas anpassen. Arbeitet auch ohne DMA mit 2 analogen Kanälen.
1 | // ARM 32-bit CORTEX-M3 - STM32F103RB8
|
2 | // EVA-Borad "STM32-P103" / Olimex
|
3 | // Quarz: 8MHz, PLL: 72MHz
|
4 | // Speicher: 128KB FLASH, 20KB SRAM
|
5 | // TOUCH (analog, 4 Anschlüsse)
|
6 | //***********************************************************************************************
|
7 | |
8 | //***********************************************************************************************
|
9 | // TOUCH Initialisierung
|
10 | // AD-Wandler 12-Bit, 1-Kanal-Mode
|
11 | //***********************************************************************************************
|
12 | void init_touch (void) { |
13 | ADC_InitTypeDef ADC_InitStructure; // ADC Struktur |
14 | ADC_DeInit(ADC1); // ADC auf Init-Werte rücksetzen |
15 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); // ADC Takt freigeben |
16 | |
17 | ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; // Arbeitsweise unabhängig |
18 | ADC_InitStructure.ADC_ScanConvMode = DISABLE; // kein Scan-Mode (nur 1 Kanal verwendet) |
19 | ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; // kontinuierliche Abtastung |
20 | ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; // keine externe Triggerung |
21 | ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; // Datenformat der Wandlung (rechtsbündig 12-Bit) |
22 | ADC_InitStructure.ADC_NbrOfChannel = 1; // 1 Kanal |
23 | ADC_Init(ADC1, &ADC_InitStructure); // ADC initialisieren |
24 | |
25 | ADC_Cmd(ADC1, ENABLE); // ADC freigeben |
26 | |
27 | ADC_ResetCalibration(ADC1); // ADC Kalibrierungswerte rücksetzen |
28 | while(ADC_GetResetCalibrationStatus(ADC1)); // Ende abwarten |
29 | |
30 | ADC_StartCalibration(ADC1); // ADC Kalibrierung |
31 | while(ADC_GetCalibrationStatus(ADC1)); // Ende abwarten |
32 | |
33 | ADC_SoftwareStartConvCmd(ADC1, ENABLE); // ADC Abtastung starten |
34 | |
35 | // Touch Variablen rücksetzen
|
36 | touch.x = 0; |
37 | touch.y = 0; |
38 | |
39 | // Später im FLASH
|
40 | touch.x_offset = TOUCH_OFFSET_X_DEFALUT; |
41 | touch.x_gain = TOUCH_GAIN_X_DEFALUT; |
42 | touch.y_offset = TOUCH_OFFSET_Y_DEFALUT; |
43 | touch.y_gain = TOUCH_GAIN_Y_DEFALUT; |
44 | |
45 | touch.taste = 0; |
46 | }
|
47 | |
48 | //***********************************************************************************************
|
49 | // TOUCH Test auf Touch-Druck (Position wird nicht ermittel!)
|
50 | // Rückgabe: 1: Touch gedrückt
|
51 | // 0: Touch nicht gedrückt
|
52 | //***********************************************************************************************
|
53 | uint8_t touch_pressed (void) { |
54 | GPIO_InitTypeDef GPIO_InitStructure; |
55 | |
56 | GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_0 | GPIO_Pin_2); // Ausgänge |
57 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // Pin-Mode |
58 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // Pin Taktung |
59 | GPIO_Init(GPIOC, &GPIO_InitStructure); // Port-Einstellung |
60 | |
61 | GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_1 | GPIO_Pin_3); // Eingänge |
62 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // Pin-Mode (Pull-Up) |
63 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // Pin Taktung |
64 | GPIO_Init(GPIOC, &GPIO_InitStructure); // Port-Einstellung |
65 | |
66 | TOUCH_PIN1_L; |
67 | TOUCH_PIN3_L; |
68 | delay_us(1000); // ca. 80us |
69 | |
70 | return (!TOUCH_PIN2); |
71 | }
|
72 | |
73 | //***********************************************************************************************
|
74 | // TOUCH X-Wert ermitteln
|
75 | // Rückgabe: ADC-Wert der X-Koordinate (0000 - 0FFF)
|
76 | //***********************************************************************************************
|
77 | uint16_t touch_x (void) { |
78 | GPIO_InitTypeDef GPIO_InitStructure; |
79 | |
80 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // Ausgang |
81 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; // Pin-Mode |
82 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // Pin Taktung |
83 | GPIO_Init(GPIOC, &GPIO_InitStructure); // Port-Einstellung |
84 | |
85 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; // Ausgang |
86 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // Pin-Mode |
87 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // Pin Taktung |
88 | GPIO_Init(GPIOC, &GPIO_InitStructure); // Port-Einstellung |
89 | |
90 | GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_1 | GPIO_Pin_3); // analoge Eingänge |
91 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; // Pin Mode |
92 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // Pin Taktung |
93 | GPIO_Init(GPIOC, &GPIO_InitStructure); // Port-Einstellung |
94 | |
95 | TOUCH_PIN1_L; // Spannungsteiler für X |
96 | TOUCH_PIN3_H; |
97 | |
98 | // 1Cycles5, 7Cycles5, 13Cycles5, 28Cycles5, 41Cycles5, 55Cycles5, 71Cycles5, 239Cycles5
|
99 | ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_28Cycles5); // Kanalauswahl 11=PC1 |
100 | delay_us(1000); // ca. 80us Pause |
101 | |
102 | while (ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == RESET); |
103 | return ADC_GetConversionValue(ADC1); // ADC-Daten (int) abholen, gleichzeitig wird EOC rückgesetzt |
104 | }
|
105 | |
106 | //***********************************************************************************************
|
107 | // TOUCH Y-Wert ermitteln
|
108 | // Rückgabe: ADC-Wert der Y-Koordinate (0000 - 0FFF)
|
109 | //***********************************************************************************************
|
110 | uint16_t touch_y (void) { |
111 | GPIO_InitTypeDef GPIO_InitStructure; |
112 | |
113 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; // Ausgang |
114 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // Pin-Mode |
115 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // Pin Taktung |
116 | GPIO_Init(GPIOC, &GPIO_InitStructure); // Port-Einstellung |
117 | |
118 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; // Ausgang |
119 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; // Pin-Mode |
120 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // Pin Taktung |
121 | GPIO_Init(GPIOC, &GPIO_InitStructure); // Port-Einstellung |
122 | |
123 | GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_0 | GPIO_Pin_2); // analoge Eingänge |
124 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; // Pin Mode |
125 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // Pin Taktung |
126 | GPIO_Init(GPIOC, &GPIO_InitStructure); // Port-Einstellung |
127 | |
128 | TOUCH_PIN2_H; // Spannungsteiler für Y |
129 | TOUCH_PIN4_L; |
130 | |
131 | ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1, ADC_SampleTime_28Cycles5); // Kanalauswahl 12=PC2 |
132 | delay_us(1000); // ca. 80us Pause |
133 | |
134 | while (ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == RESET); |
135 | return ADC_GetConversionValue(ADC1); // ADC-Daten (int) abholen, gleichzeitig wird EOC rückgesetzt |
136 | }
|
137 | |
138 | //***********************************************************************************************
|
139 | // TOUCH Koordinaten und Tastencode ermitteln
|
140 | // Rückgabe 1: Touch gedrückt und Koordinate gültig
|
141 | // 0: keine Touchaktivität
|
142 | //***********************************************************************************************
|
143 | uint8_t get_touch (void) { |
144 | |
145 | if (touch_pressed()) { |
146 | // Touchaktivität
|
147 | |
148 | touch.x = ((320 * touch_x() / 4096) - touch.x_offset) * touch.x_gain / 100; |
149 | touch.y = ((240 * touch_y() / 4096) - touch.y_offset) * touch.y_gain / 100; |
150 | |
151 | return 1; |
152 | } else { |
153 | // keine Touchaktivität
|
154 | touch.x = 0; |
155 | touch.y = 0; |
156 | touch.taste = 0; |
157 | return 0; |
158 | }
|
159 | }
|
160 | |
161 | ....
|
162 | |
163 | MAIN
|
164 | |
165 | |
166 | #define TOUCH_PIN1_H GPIO_SetBits(GPIOC,GPIO_Pin_0)
|
167 | #define TOUCH_PIN1_L GPIO_ResetBits(GPIOC,GPIO_Pin_0)
|
168 | |
169 | #define TOUCH_PIN2_H GPIO_SetBits(GPIOC,GPIO_Pin_1)
|
170 | #define TOUCH_PIN2_L GPIO_ResetBits(GPIOC,GPIO_Pin_1)
|
171 | |
172 | #define TOUCH_PIN3_H GPIO_SetBits(GPIOC,GPIO_Pin_2)
|
173 | #define TOUCH_PIN3_L GPIO_ResetBits(GPIOC,GPIO_Pin_2)
|
174 | |
175 | #define TOUCH_PIN4_H GPIO_SetBits(GPIOC,GPIO_Pin_3)
|
176 | #define TOUCH_PIN4_L GPIO_ResetBits(GPIOC,GPIO_Pin_3)
|
177 | |
178 | #define TOUCH_PIN1 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_0)
|
179 | #define TOUCH_PIN2 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_1)
|
180 | #define TOUCH_PIN3 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2)
|
181 | #define TOUCH_PIN4 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3)
|
182 | |
183 | #define TOUCH_KAL_X_DEFAULT 3800
|
184 | #define TOUCH_KAL_Y_DEFAULT 3700
|
185 | |
186 | #define TOUCH_OFFSET_X_DEFALUT 30 /* Offsetwert X in Pixel */ |
187 | #define TOUCH_OFFSET_Y_DEFALUT 30 /* Offsetwert Y in Pixel */ |
188 | #define TOUCH_GAIN_X_DEFALUT 125 /* Verstärkung X (Faktor 100) 125 = 1.25 */ |
189 | #define TOUCH_GAIN_Y_DEFALUT 133 /* Verstärkung Y (Faktor 100) */ |
190 | |
191 | // Touch-Werte
|
192 | struct touch_struc { |
193 | volatile uint16_t x; // X-Koordinate (0...319) |
194 | volatile uint16_t y; // Y-Koordinate (0...239) |
195 | volatile uint8_t x_offset; // Kalibrierung in X Offset |
196 | volatile uint8_t y_offset; // Kalibrierung in Y Offset |
197 | volatile uint8_t x_gain; // Kalibrierung in X Verstärkung |
198 | volatile uint8_t y_gain; // Kalibrierung in Y Verstärkung |
199 | volatile uint8_t taste; // Tastencode |
200 | };
|
201 | |
202 | struct touch_struc touch; // Touch Variablen |
203 | |
204 | ....
|
205 | |
206 | |
207 | // Abfrage
|
208 | if (get_touch()) { |
209 | touch.x touch.y; enthalten die Koordinaten des Druckpunktes |
210 | }
|
Oha coool, denke das wird mir weiterhelfen. Dank dir!
/** ************************************************************************ ****** * @file main.c * @author Ac6 * @version V1.0 * @date 01-December-2013 * @brief Default main function. * Programmiert mit der Standard Peripheral Library * MAIN C für Siebensegment Anzeige ************************************************************************ ****** */ #include "stm32f4xx.h" #include "uart.h" #define DELAYTIME 350000 #define LONGDELAY 750000 #define TWOSECOND 5600000 #define SECOND 2800000 #define HALFSECOND 1400000 #define QUARTERSECOND 700000 #define D1_USART_TX GPIO_Pin_2 //GPIOA #define D0_USART_RX GPIO_Pin_3 //GPIOA #define BAUDRATE 9600 #define ADC_A1 GPIO_Pin_0; int main(void) { SystemInit(); //-------------------------------------------------------------Clocks--- -------------------------------------------------------- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //-------------------------------------------------------------GPIO----- ------------------------------------------------------ GPIO_InitTypeDef G_Struct; G_Struct.GPIO_Pin = D0_USART_RX; G_Struct.GPIO_Mode = GPIO_Mode_AF; G_Struct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &G_Struct); G_Struct.GPIO_Pin = D1_USART_TX; G_Struct.GPIO_Mode = GPIO_Mode_AF; G_Struct.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOA, &G_Struct); //-------------------------------------------------------Alternate Function USART----------------------------------------------------------- GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_USART2); GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2); //-------------------------------------------------------------USART---- ------------------------------------------------------- USART_InitTypeDef USART_Struct; USART_Struct.USART_BaudRate = BAUDRATE; USART_Struct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_Struct.USART_Mode = USART_Mode_Tx; USART_Struct.USART_Parity = USART_Parity_No; USART_Struct.USART_StopBits = USART_StopBits_1; USART_Struct.USART_WordLength = USART_WordLength_8b; USART_Init(USART2, &USART_Struct); USART_Cmd(USART2, ENABLE); //-------------------------------------------------------------ADC------ ----------------------------------------------------- G_Struct.GPIO_Pin = ADC_A1; G_Struct.GPIO_Mode = GPIO_Mode_AF; //Konfiguration für den ADC In Pin - Keine ALTERNATE FUNCTION BENOETIGT G_Struct.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOA, &G_Struct); ADC_CommonInitTypeDef ADC_InitStruct; ADC_InitTypeDef ADC_Settings; ADC_InitStruct.ADC_Mode = ADC_Mode_Independent; ADC_InitStruct.ADC_Prescaler = ADC_Prescaler_Div2; // ADC_InitStruct.ADC_DMAAccessMode = ADC_DMAAccessMode_1; // ADC_InitStruct.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_10Cycles; ADC_CommonInit(&ADC_InitStruct); ADC_Settings.ADC_ContinuousConvMode = ENABLE; ADC_Settings.ADC_DataAlign = ADC_DataAlign_Right; //?? ADC_Settings.ADC_ExternalTrigConv = ADC_ExternalTrigConvEdge_None; ADC_Settings.ADC_NbrOfConversion = 1; ADC_Settings.ADC_Resolution = ADC_Resolution_12b; ADC_Settings.ADC_ScanConvMode = ENABLE; ADC_Init(ADC1, &ADC_Settings); ADC_Cmd(ADC1, ENABLE); ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_480Cycles ); ADC_SoftwareStartConv(ADC1); //-----------------------------------------------------------ADC - AF ----------------------------------------------------------- // GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_A); //kein AFIO fuer ADC //-----------------------------------------------------------SPI ----------------------------------------------------------- while (1) { int adcReturn = 0; int wait = 0; do { adcReturn = adcReturn + ADC_GetConversionValue(ADC1); USART_SendData(USART2, adcReturn); for(wait = 0; wait < TWOSECOND; wait++); } while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == 1); sendText(" Kein ADC \n"); for(wait = 0; wait < TWOSECOND; wait++); } return 0; } Leider bekomme ich den AD Wandler nicht zum laufen. Lande immer wieder bei der Ausgabe "Kein ADC"
Ich glaube, 6 Jahre später sucht er nicht mehr. Die SPL ist inzwischen auch längst deprecated. Ein aktuelles sollte entweder die HAL (iiieh baah) oder gar kein Framework verwenden. Hier ein einfaches Beispiel für die STM32F1 Serie auf Basis der CMSIS (also ohne Framework): http://stefanfrings.de/stm32/index.html#analog
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.