Forum: Mikrocontroller und Digitale Elektronik [STM32] Einfaches Beispiel für AD Wandler gesucht


von peterguy (Gast)


Lesenswert?

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 :-))

von Matthias K. (matthiask)


Lesenswert?

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
}

von peterguy (Gast)


Lesenswert?

Oha coool, denke das wird mir weiterhelfen.
Dank dir!

von Maximilian (Gast)


Lesenswert?

/**
  ************************************************************************ 
******
  * @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"

von Stefan F. (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.