Forum: Mikrocontroller und Digitale Elektronik STM32 ADC Messung


von Mark (Gast)


Lesenswert?

Hallo,
ich möchte Pegel ausmessen und habe die Spannung an den ADC geführt, bei 
einem Pegelwechsel wird Zeitverzögert der ADC ausgelesen (Zeiten im 
Bereich von etwa 20 µs). Ist der folgende Code dafür brauchbar? Ich 
bekomme nämlich immer falsche Messungen.
1
ADC_SoftwareStartConvCmd(ADC1, ENABLE);   //Start ADC Konvertierung
2
3
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);  //Warte bis Konvertierung abgeschlossen
4
5
ADC1_Konv_Wert = ADC_GetConversionValue(ADC1);//Konvertierten Wert auslesen
6
7
ADC_ClearFlag(ADC1, ADC_FLAG_EOC);

in "ADC1_Konv_Wert" stehen jetzt falsche Werte. Ich habe einen Ausgang 
vor der Messung gesetzt und danach wieder rückgesetzt. Laut Oszi wird an 
der reichtigen Stelle gemessen.

Ist es so, dass der ADC die Messungen trotzdem willkürlich vorher 
durchführt und ich mit diesem Code auch nur die vorher gemessenen Werte 
konvertiere?

von RP6Conrad (Gast)


Lesenswert?

Wenn du die Konfig von ADC-Clock, GPIO, ADC_Kalibrierung - und ADC 
Einzelabtastung richtig haben wird mit folgende Code eine ADC_Messung 
gemacht :
1
u16 readADC1(u8 channel,u8 sample_time){    //0=ADC_SampleTime_1Cycles5, 3=ADC_SampleTime_28Cycles5
2
  ADC_RegularChannelConfig(ADC1, channel, 1,sample_time);  // Start the conversion  
3
  ADC_SoftwareStartConvCmd(ADC1, ENABLE);  // Wait until conversion completion  
4
  while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);  // Get the conversion value  return ADC_GetConversionValue(ADC1);}
5
  return ADC_GetConversionValue(ADC1);}
Aber schoner und ohne processor belastung geht das mit DMA ! Einfach 
einmal richtig konfigurieren, und die ADC-Werte von die gewunschte 
Kanalen werden ueber DMA in der Speicher geschrieben.

von Noname (Gast)


Lesenswert?

Zu einer korrekten und vollständigen AD-Konfiguration gehört noch mehr.
Der IO-Port muss konfiguriert werden. Der Takt für Port und AD-Wandler.
Ausrichtung der Werte. Wandlungszeit.

Zeige doch bitte mal vollständigen, kompilierbaren Code der den Fehler 
aufweist. (Entferne alles was nicht nötig ist um den Fehler zu 
demonstrieren). Beschreibe bitte genau, was Du meinst, wenn Du 
schreibst: "Ich bekomme nämlich immer falsche Messungen."

>bei einem Pegelwechsel wird Zeitverzögert der ADC ausgelesen
Wie sind die zeitlichen Verhältnisse dieses Steuersignals, auf dessen 
Pegelwechsel reagiert wird; auch in Beziehung zum zu messenden Signal?

von Mark (Gast)


Lesenswert?

Ich hatte mir mal sagen lassen, dass es wohl bei einzelnen Messungen 
nachteilig wäre die DMA zu nutzen, deswegen hatte ich sie jetzt wieder 
raus genommen.

Das Messen bei konstanten Signalen funktioniert ja mit der Variante 
grundsätzlich, eben nur scheinbar nicht in dem genannte Fall. Damit 
sollten die Konfiguration eigentlich stimmen. Den ADC und den Port hatte 
ich wie folgt konfiguriert:


1
//ADC1 Port-Konfiguration
2
// PC4 (ADC Channel_12) als analoger Eingang
3
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
4
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
5
GPIO_Init(GPIOC, &GPIO_InitStructure);
6
7
8
9
/* ADC1 configuration -------------------------------------------------*/
10
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
11
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
12
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
13
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
14
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
15
ADC_InitStructure.ADC_NbrOfChannel = 1;
16
ADC_Init(ADC1, &ADC_InitStructure);
17
18
/* ADC1 regular channel12 configuration */
19
ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1, ADC_SampleTime_55Cycles5);
20
21
/* Enable ADC1 DMA */
22
//ADC_DMACmd(ADC1, ENABLE);
23
24
// Aktiviere ADC1
25
ADC_Cmd(ADC1, ENABLE);
26
27
28
//## ADC kalibirieren
29
30
// Freigabe ADC1 Reset des Kalibrierungs Registers
31
ADC_ResetCalibration(ADC1);
32
// Warte auf das Ende des ADC1 Kalibrierungs Registers Resets
33
while(ADC_GetResetCalibrationStatus(ADC1));
34
35
// Start ADC1 Kalibration
36
ADC_StartCalibration(ADC1);
37
// Warte auf das Ende der Kalibration
38
while(ADC_GetCalibrationStatus(ADC1));
39
40
41
42
43
44
/* Takte Zuschalten*/
45
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC     |
46
         RCC_APB1Periph_TIM2    |
47
         RCC_APB1Periph_TIM4  , ENABLE);
48
49
/* Takte Zuschalten*/
50
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1  |
51
         RCC_APB2Periph_GPIOC |
52
             RCC_APB2Periph_GPIOA, ENABLE);


Nach der Flanke hatte ich aus Testzwecken mit einer 20 µs Verzögerung 
die Messung vorgenommen. Vor der Messung habe ich einen Pin gesetzt und 
nach der Messung hatte ich ihn Rückgesetzt. Der sich daraus ergebende 
Impuls liegt jetzt genau dort wo ich die Messung machen wollte.

Ich hoffe das reicht um mir weiter helfen zu können. Ich baue das ganze 
jetzt noch mal als kontinuierliche DMA Messung auf und ziehe mir die 
gewünschten Werte heraus, vielleicht sind diese Einzelmessungen auch 
nicht möglich.

Danke für die bisherigen Antworten.

von RP6Conrad (Gast)


Lesenswert?

Wen ich das richtig verstehen wollen sie auf eine bestimmte Zeitpunkt 
eine ADC_Messung machen. Und mit ihre heutige code stimmt der Messung 
nicht. Liegt ein stabiles Signal, oder ist das ein schwankende Spannung 
? Sind sie sicher das die Ergebnis von ADC komplett falsch ist, oder ist 
ihre Signal stark verrauscht ?
Konne sie ein stabiles Signal richtig messen (Potimeter, oder ausgang 
von DAC), oder sind da auch schon Problemen ?

von Icke (Gast)


Lesenswert?

Hallo zusammen,

was beinhalten die Funktionen, die unter //## ADC kalibirieren (in Marks 
Post) aufgeführt sind?
Braucht man das?
Kann diese Funktionalitäten in der Standardbibliothek nicht finden...

LG

von Joe-C (Gast)


Lesenswert?

Moin,

Im Kommentar steht PinC4 aber ausgelegt scheint alles auf PinC2 (Ain12) 
zu sein.
Wie dem auch sei, ich benutze eine ähnliche Variante wie RP6Conrad:
1
 u16 readADC1(u8 channel) {
2
  ADC_RegularChannelConfig(ADC1, channel, 1, ADC_SampleTime_1Cycles5);
3
  ADC_SoftwareStartConvCmd(ADC1, ENABLE);
4
  while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
5
  return ADC_GetConversionValue(ADC1);
6
}
Hat bei mir immer gut funktioniert (außer man verwendet Ain0, der hat so 
seine Eigenheiten).

Was aber noch Probleme machen könnte... du konfigurierst erst den ADC 
und versorgst ihn dann erst mit dem Takt. Ich glaube, der Takt muss 
vorher schon da sein, um die Konfiguration zu ermöglichen. Pack die 
"RCC_APB2PeriphClockCmd..." Sache mal ganz nach oben... vielleicht 
geht’s dann.

MFG

von Icke (Gast)


Lesenswert?

Hallo,

kann mir jemand erklären,
was das mit der ADC SampleTime (in Zyklen) und den "NbrOfConversion" auf 
sich hat?

Wie rechne ich die SampleZeit aus?
z.B. ist im Datenblatt des STM32F2xx angegeben, dass der 
Temperatursensor eine Samplezeit von min. 2.2us braucht... wieviel muss 
ich dann einstellen?

wenn ich die NbrOfConversion ändere, habe ich dann eine 
Mittelwertbildung?

Danke + Gruß


hier einige Clockangaben:

*        Supported STM32F2xx device revision    | Rev B and Y
  *----------------------------------------------------------------------- 
---
*        System Clock source                    | PLL (HSE)
  *----------------------------------------------------------------------- 
---*         SYSCLK(Hz)                             | 120000000
  *----------------------------------------------------------------------- 
---*         HCLK(Hz)                               | 120000000
  *----------------------------------------------------------------------- 
---*         AHB Prescaler                          | 1
  *----------------------------------------------------------------------- 
---*         APB1 Prescaler                         | 4
  *----------------------------------------------------------------------- 
---*         APB2 Prescaler                         | 2
  *----------------------------------------------------------------------- 
---*         HSE Frequency(Hz)                      | 25000000
  *----------------------------------------------------------------------- 
---*         PLL_M                                  | 25
  *----------------------------------------------------------------------- 
---*         PLL_N                                  | 240
  *----------------------------------------------------------------------- 
---*         PLL_P                                  | 2
  *----------------------------------------------------------------------- 
---*         PLL_Q                                  | 5

von Mark (Gast)


Lesenswert?

Die Messwerte waren ursprünglich derart falsch, dass die Messung bei 
einer Highflanke niedriger war als die bei einer Low Flanke und das bei 
3V und 0V Pegeln. Ich habe allerdings aus Testzwecken die Soundkarte 
genutzt und einen Komparator nachgeschaltet. Ich habe festgestellt, dass 
beim Setzen eines Breakpoints oft eine weitere Highflanke erkannt wird 
die garnicht existiert. Dadurch wurde wohl ab und zu an den falschen 
Stellen gemessen. Jetzt scheint es zu funktionieren. Danke!


Zu den Fragen und Antworten:

-Eure Vorschläge habe ich hier schon mal gesehen:
http://www.micromouseonline.com/2009/05/26/simple-adc-use-on-the-stm32/#axzz1iwuhrYOS

Ist es wirklich notwendig die Einstellung erst kurz vor dem Messen zu 
machen?:
ADC_RegularChannelConfig(ADC1, channel, 1, ADC_SampleTime_1Cycles5);


>>//## ADC kalibirieren (in Marks Post) aufgeführt sind? Braucht man das?
Schau mal in die ST-Beispiele rein, da wird das immer gemacht. Damit 
erreichst du eine höhere Genauigkeit. Das steht auch so im Datenblatt 
unter ADC. (nicht das RM0008 sondern das Datenblatt) Sonst einfach mal 
coden und F3.. dann wirst du eigentlich verklinkt.


>>Im Kommentar steht PinC4 aber ausgelegt scheint alles auf PinC2 (Ain12)
>>zu sein.
Mist schon wieder vergessen. Ich habe den Teil aus einem anderen 
Codeteil von mir herausgenommen um ihn nicht neu zu schreiben. Der 
Channel im Kommentar wird für ein anderes Signal in einem anderen Modus 
genutzt. Den Kommentar hatte ich vergessen zu ändern denke ich ... sry.


>>außer man verwendet Ain0, der hat so seine Eigenheiten
Richtig, im ERRATA-Scheet steht dass der Pin für ADC-Messungen 
ungeeignet ist und die Messungen versaut.


>>du konfigurierst erst den ADC und versorgst ihn dann erst mit dem Takt.
>>Ich glaube, der Takt muss vorher schon da sein
Es geht nun auch so, aber möglicherweise ist deine Variante korrekter... 
kann da jemand eine Aussage zu machen?

@Icke
Das ist jetzt vielleicht etwas mies von mir, aber guck mal ins AN3116 
rein, da gehts nur um die grobe ADC-Theorie und Berechnungen. Vielleicht 
beantwortet dir das deine Fragen besser als ich es könnte. Für 
Oversampling wäre noch das AM2668 empfehlenswert.


Kann mir noch jemand sagen wie sich das mit der DMA bei solchen 
Einzelwerten verhält? Bringt das was? Ich habe mir sagen lassen erst ab 
einer gewissen Anzahl, weil der Aufwand die CPU zu umgehen und nur einen 
Wert zu übermitteln größer ist als den durch die CPU zu schaufeln? Ist 
ja nicht so als könnte die CPU während DMA weiter arbeiten.


Gruß Mark

von Icke (Gast)


Lesenswert?

Mark - ich werd mal schaun...

passt schon - ist doch ein guter Tipp.

von Icke (Gast)


Lesenswert?

Mark schrieb:
> Ist es wirklich notwendig die Einstellung erst kurz vor dem Messen zu
> machen?:
> ADC_RegularChannelConfig(ADC1, channel, 1, ADC_SampleTime_1Cycles5);

hierzu kann ich sagen, dass es nur dann nötig ist, wenn du mit einem 
ADCx verschiedene Kanäle wandeln möchtest... sonst reicht das einmalig 
und ADC_GetConversionValue( ) liefert dir immer das Ergebnis vom 
gewählten Kanal.


kann mir niemand was zu den NumberOfConversions sagen?

von Mark (Gast)


Lesenswert?

Soweit ich das verstanden habe ist die Number of Conversations einfach 
nur die Anzahl der Channel die du in die Konvertierung einbeziehen 
möchtest.

The regular group is composed of up to 16 conversions. The regular 
channels and
their order in the conversion sequence must be selected in the ADC_SQRx 
registers.
The total number of conversions in the regular group must be written in 
the L[3:0] bits in
the ADC_SQR1 register.

Siehe: http://www.galexander.org/stm32/stm32f100x-RM.pdf

Deswgen gibts auch nur 4 Bit = 16 Channel.
Wie in den Sheets die ich dir vorhin genannt habe sollte hervorgehen wie 
das gemeint ist. Du kannst nämlich die Channel nacheinander mit einem 
ADC konvertieren.

von RP6Conrad (Gast)


Angehängte Dateien:

Lesenswert?

Das kalibrieren von den ADC ist absolut notwendig. Ich habe die ADC ohne 
Kalbibrierung  mal gemessen : da war eine Abweichung von fast 70 bit 
ueber das ganse Spannungsbereich ! Mit Kalibrierung war die Abweichung 
immer kleiner dan 5 bit. Für so eine Messung lasst sich den DAC gut 
gebrauchen : einfach den DAC ansteuern mit Werte von 0 bis4095 bit, und 
den ADC Wert jeden mal vermessen. Mit den DAC-Buffer auf disable war das 
Differenz immer kleiner dan 5 bit. Mit den DAC Buffer auf Enable geht 
der Differenz von +40 bit bei 0V nach -50bit bei +Vref.

von Icke (Gast)


Lesenswert?

RP6Conrad schrieb:
> Für so eine Messung lasst sich den DAC gut
> gebrauchen...

Hast du mir/uns hierfür Code?
Dann brauch ich das net selbst machen :-)

Danke

von RP6Conrad (Gast)


Lesenswert?

Alles in main, Delay in interrupthandler !!
1
/**
2
  ******************************************************************************
3
  * @file DAC-ADC /main.c 
4
  * @author  Jan Heynen
5
  * @version V1
6
  * @date    1/1/2012
7
  * @brief   Main program body.
8
  ******************************************************************************
9
  * @copy
10
  * The DAC_Channel1 will send a Voltage to pin PA4, DAC channel2 to pin PA5. The ADC is measured on
11
  * pin PA4 and pin PA5. DAC PA4, the Buffer is diasable, DAC PA5, the Buffer is enabled.
12
  * The differens between DAC and ADC is printed via USART1 (38400 baud)
13
  */ 
14
15
/* Includes ------------------------------------------------------------------*/
16
#include "stm32f10x.h"
17
#include <stdio.h>
18
/* Private typedef -----------------------------------------------------------*/
19
#define LEDC8_OFF GPIOC->BRR = 1<<8 ;
20
#define LEDC9_OFF GPIOC->BRR = 1<<9 ;
21
#define LEDC8_ON GPIOC->BSRR = 1<<8 ;  
22
#define LEDC9_ON GPIOC->BSRR = 1<<9 ;  
23
/* Private define ------------------------------------------------------------*/
24
#define DAC_DHR12RD_Address      0x40007420
25
26
/* Init Structure definition */
27
DAC_InitTypeDef            DAC_InitStructure;
28
DMA_InitTypeDef            DMA_InitStructure;
29
TIM_TimeBaseInitTypeDef    TIM_TimeBaseStructure;
30
/* Private macro -------------------------------------------------------------*/
31
/* Private variables ---------------------------------------------------------*/
32
uint8_t Idx = 0;
33
uint16_t adc0=0;
34
uint16_t i=0;
35
volatile uint16_t Delay;
36
/* Private function prototypes -----------------------------------------------*/
37
void RCC_Configuration(void);
38
void GPIO_Configuration(void);
39
void delay(uint16_t tijd);
40
void USART_Config(void);
41
#ifdef __GNUC__
42
  /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
43
     set to 'Yes') calls __io_putchar() */
44
  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
45
#else
46
  //#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
47
  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE*f)
48
#endif /* __GNUC__ */
49
PUTCHAR_PROTOTYPE   //in main achteraan
50
{
51
  /* Place your implementation of fputc here */
52
  /* e.g. write a character to the USART */
53
  USART_SendData(USART1, (uint8_t) ch);
54
55
  /* Loop until the end of transmission */
56
  while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
57
  {}
58
59
  return ch;
60
}
61
/* Private functions ---------------------------------------------------------*/
62
static __IO uint32_t TimingDelay;
63
void TimingDelay_Decrement(void)
64
{
65
  if (TimingDelay != 0x00)
66
  { 
67
    TimingDelay--;
68
  }
69
}
70
void ADC_Configuration(void){
71
ADC_InitTypeDef  ADC_InitStructure;  /* PCLK2 is the APB2 clock */  /* ADCCLK = PCLK2/6 = 72/6 = 12MHz*/  
72
RCC_ADCCLKConfig(RCC_PCLK2_Div6);  /* Enable ADC1 clock so that we can talk to it */  
73
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);  /* Put everything back to power-on defaults */  
74
ADC_DeInit(ADC1);  /* ADC1 Configuration -*/  /* ADC1 and ADC2 operate independantly */  
75
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;  /* Disable the scan conversion so we do one at a time */  
76
ADC_InitStructure.ADC_ScanConvMode = DISABLE;  /* Don't do contimuous conversions - do them on demand */  
77
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;  /* Start conversin by software, not an external trigger */  
78
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;  /* Conversions are 12 bit - put them in the lower 12 bits of the result */  
79
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;  /* Say how many channels would be used by the sequencer */  
80
ADC_InitStructure.ADC_NbrOfChannel = 1;  /* Now do the setup */  
81
ADC_Init(ADC1,&ADC_InitStructure);  /* Enable ADC1 */  
82
ADC_Cmd(ADC1, ENABLE);  /* Enable ADC1 reset calibaration register */  
83
84
ADC_ResetCalibration(ADC1);  /* Check the end of ADC1 reset calibration register */  
85
while(ADC_GetResetCalibrationStatus(ADC1));  /* Start ADC1 calibaration */  
86
ADC_StartCalibration(ADC1);  /* Check the end of ADC1 calibration */  
87
while(ADC_GetCalibrationStatus(ADC1));
88
}
89
90
u16 readADC1(u8 channel){  
91
ADC_RegularChannelConfig(ADC1, channel, 1, ADC_SampleTime_41Cycles5);  // Start the conversion  
92
ADC_SoftwareStartConvCmd(ADC1, ENABLE);  // Wait until conversion completion  
93
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);  // Get the conversion value  return ADC_GetConversionValue(ADC1);}
94
return ADC_GetConversionValue(ADC1);}
95
/**
96
  * @brief   Main program.
97
  * @param  None
98
  * @retval None
99
  */
100
int main(void)
101
{
102
  /* System Clocks Configuration */
103
  RCC_Configuration();   
104
  GPIO_Configuration();
105
  ADC_Configuration();    //configuratie ADC1
106
  /* Once the DAC channel is enabled, the corresponding GPIO pin is automatically 
107
     connected to the DAC converter. In order to avoid parasitic consumption, 
108
     the GPIO pin should be configured in analog */
109
  /* DAC channel1 Configuration */
110
  DAC_InitStructure.DAC_Trigger = DAC_Trigger_None ;
111
  DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None ;
112
  DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;
113
  DAC_Init(DAC_Channel_1, &DAC_InitStructure);
114
  /* DAC channel2 Configuration */
115
  DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
116
  DAC_Init(DAC_Channel_2, &DAC_InitStructure);
117
  /* Enable DAC Channel1: Once the DAC channel1 is enabled, PA.04 is 
118
     automatically connected to the DAC converter. */
119
  DAC_Cmd(DAC_Channel_1, ENABLE);
120
  /* Enable DAC Channel2: Once the DAC channel2 is enabled, PA.05 is 
121
     automatically connected to the DAC converter. */
122
  DAC_Cmd(DAC_Channel_2, ENABLE);
123
  /* Set DAC dual channel DHR12RD register */
124
  DAC_SetDualChannelData(DAC_Align_12b_R, 0x100, 0x100);//was 0x100,0x100
125
   
126
  /* USARTx configured as follow:
127
        - BaudRate = 38400 baud  
128
        - Word Length = 8 Bits
129
        - One Stop Bit
130
        - No parity
131
        - Hardware flow control disabled (RTS and CTS signals)
132
        - Receive and transmit enabled
133
  */
134
  USART_InitTypeDef USART_InitStructure;
135
  USART_InitStructure.USART_BaudRate = 38400;
136
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
137
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
138
  USART_InitStructure.USART_Parity = USART_Parity_No;
139
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
140
  USART_InitStructure.USART_Mode = USART_Mode_Tx; 
141
  
142
143
  /* USART configuration */
144
  USART_Init(USART1, &USART_InitStructure);
145
    
146
  /* Enable USART */
147
  USART_Cmd(USART1, ENABLE);
148
 /* Systick timer----- ------------------------------------------------------*/
149
   /* Setup SysTick Timer for 1 msec interrupts  */
150
  if (SysTick_Config(SystemFrequency / 1000))
151
  { 
152
    while (1);/* Capture error */ 
153
  }  
154
  /* Display Demo start */
155
LEDC8_ON;
156
delay(1000);
157
printf("\n\r\n                    STMICROELECTRONICS\n\r");
158
printf("\n\r      ********** STM32 - DAC-ADC Demo **********\n\r");
159
printf("\n\r      Gebruik FULL voor de library configurator !!!    \n\r");
160
LEDC8_OFF;
161
//Main Schleife
162
  while (1)
163
  {
164
    for (;i<4096;){  
165
      DAC_SetDualChannelData(DAC_Align_12b_R, i,i);//Dacchannel 1 + 2 Ansteuern mit Werte i
166
      LEDC9_ON; 
167
      delay(10);  //Wartezeit 10 ms
168
      LEDC9_OFF;
169
      delay(10);
170
      adc0=readADC1(4); //ADC Einzelabtastung Channel 4 = pin A4
171
      printf("DAC: %d ",i); //Print Soll wert DAC
172
      printf(" ADC4: %d ",(i-adc0)); //Print differenz DAC - ADC Messwert channel 4
173
      adc0=readADC1(5);
174
      printf(" ADC5: %d\n ",(i-adc0));//Print differenz DAC - ADC Messwert channel 5
175
      i=i+10; //DAC Werte mit 10 erhohen
176
    }
177
  }
178
}
179
180
/* @brief  Configures the different system clocks. */
181
void RCC_Configuration(void)
182
{   
183
  /* Setup the microcontroller system. Initialize the Embedded Flash Interface,  
184
     initialize the PLL and update the SystemFrequency variable. */
185
  SystemInit();
186
/* Enable peripheral clocks --------------------------------------------------*/
187
  /* GPIOA and GPIOC Periph clock enable */
188
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC, ENABLE);
189
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
190
  /* DAC Periph clock enable */
191
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
192
   /* Enable UART clock */
193
   RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1, ENABLE);   
194
}
195
196
/* @brief  Configures the different GPIO ports */
197
void GPIO_Configuration(void)
198
{
199
  GPIO_InitTypeDef GPIO_InitStructure;
200
  /* Once the DAC channel is enabled, the corresponding GPIO pin is automatically 
201
     connected to the DAC converter. In order to avoid parasitic consumption, 
202
     the GPIO pin should be configured in analog */
203
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_4 | GPIO_Pin_5;
204
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
205
  GPIO_Init(GPIOA, &GPIO_InitStructure);
206
   /* Configure USART Tx as alternate function push-pull */
207
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
208
  GPIO_InitStructure.GPIO_Pin =   GPIO_Pin_9;
209
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
210
  GPIO_Init(GPIOA, &GPIO_InitStructure);
211
  /* Configure USART Rx as input floating */
212
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
213
  GPIO_InitStructure.GPIO_Pin =   GPIO_Pin_10;
214
  GPIO_Init(GPIOA, &GPIO_InitStructure);
215
    //configure LEDS C8/C9 as output
216
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_8 | GPIO_Pin_9; //LEDS C8 en C9
217
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
218
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
219
  GPIO_Init(GPIOC, &GPIO_InitStructure);
220
}
221
222
/**
223
  * @brief  Inserts a delay time.
224
  * @param  nCount: specifies the delay time length.
225
  * @retval None
226
  */
227
228
void delay(uint16_t tijd){
229
  Delay=tijd;
230
  while (Delay){}
231
}
232
#ifdef  USE_FULL_ASSERT
233
234
/**
235
  * @brief  Reports the name of the source file and the source line number
236
  *   where the assert_param error has occurred.
237
  * @param  file: pointer to the source file name
238
  * @param  line: assert_param error line source number
239
  * @retval None
240
  */
241
void assert_failed(uint8_t* file, uint32_t line)
242
{ 
243
  /* User can add his own implementation to report the file name and line number,
244
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
245
246
  /* Infinite loop */
247
  while (1)
248
  {
249
  }
250
}
251
#endif
252
253
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
in interupthandler : stm32f10x_it.c
1
void SysTick_Handler(void)
2
{if(Delay)Delay--;}

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.