STM32F2 ADC Continous Scan mit DMA, Softwareproblem

OP #2781116
Lesenswert?

Hi Leute,

ich versuche aktuell auf einem STM32F205VG mit ADC1 im continuous scan 
modus zwei pins und den Temperatursensor einzulesen. Die Daten sollen 
via DMA in ein struct kopiert werden.

Folgenden Quelltext hab ich mir aus den Herstellerbeispielen zusammen 
gestellt und inzwischen auch einiges an Zeit mit Fehlersuche verbraten, 
da das struct sich einfach nicht füllen will. Wenn jemand von euch den 
Fehler sieht wärs super.

Da das einlesen von mehreren Pins erfolglos war habe ich die (mMn) 
zuständigen Stellen auskommentiert um mit den eingefügten Pendants es 
erstmal mit einem Pin zum Laufen zu kriegen, wieder erfolglos...

#define HMI_GIER_PORT          GPIOA
#define HMI_GIER_PIN          GPIO_Pin_5
#define HMI_GIER_CLK          RCC_AHB1Periph_GPIOA
#define HMI_GIER_ADC_CHANNEL      ADC_Channel_5
#define HMI_THROTTLE_PORT        GPIOC
#define HMI_THROTTLE_PIN        GPIO_Pin_1
#define HMI_THROTTLE_CLK        RCC_AHB1Periph_GPIOC
#define HMI_THROTTLE_ADC_CHANNEL    ADC_Channel_11

#define HMI_ADC              ADC1
#define HMI_ADC_CLK            RCC_APB2Periph_ADC1

#define HMI_DMA              DMA2
#define HMI_DMA_CHANNEL          DMA_Channel_0
#define HMI_DMA_STREAM          DMA2_Stream0
#define HMI_DMA_CLK            RCC_AHB1Periph_DMA2
#define HMI_ADC_DR_Address        ((uint32_t)HMI_ADC+0x10)

...

typedef struct {
  uint8_t    start;
  uint16_t  gier;
  uint16_t  throttle;
  uint16_t  cpu_temp;
  uint8_t    stop;
} SENSORS_t;
__IO SENSORS_t SENSOR_States;

...

/*!< Enable ADC1, DMA2 and GPIO clocks */
  RCC_AHB1PeriphClockCmd(HMI_DMA_CLK | HMI_GIER_CLK | HMI_THROTTLE_CLK, 
ENABLE);
  RCC_APB2PeriphClockCmd(HMI_ADC_CLK, ENABLE);

  /*!< DMA2 Stream0 configuration */
  DMA_DeInit(HMI_DMA_STREAM);
  DMA_InitStructure.DMA_Channel = HMI_DMA_CHANNEL;
  DMA_InitStructure.DMA_PeripheralBaseAddr = 
(uint32_t)HMI_ADC_DR_Address;
  DMA_InitStructure.DMA_Memory0BaseAddr = 
(uint32_t)&(SENSOR_States.gier);
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
  //DMA_InitStructure.DMA_BufferSize = 3;
  DMA_InitStructure.DMA_BufferSize = 1;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  //DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
  DMA_InitStructure.DMA_PeripheralDataSize = 
DMA_PeripheralDataSize_HalfWord;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
  DMA_Init(HMI_DMA_STREAM, &DMA_InitStructure);
  DMA_Cmd(HMI_DMA_STREAM, ENABLE);

  /*!< Configure pins as analog input */
  GPIO_InitStructure.GPIO_Pin = HMI_GIER_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(HMI_GIER_PORT, &GPIO_InitStructure);
  GPIO_InitStructure.GPIO_Pin = HMI_THROTTLE_PIN;
  GPIO_Init(HMI_THROTTLE_PORT, &GPIO_InitStructure);

  /*!< TempSensor and VrefInt Init */
  ADC_TempSensorVrefintCmd(ENABLE);

  /*!< ADC Common Init */
  ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
  ADC_CommonInitStructure.ADC_DMAAccessMode = 
ADC_DMAAccessMode_Disabled;
  ADC_CommonInitStructure.ADC_TwoSamplingDelay = 
ADC_TwoSamplingDelay_20Cycles;
  ADC_CommonInit(&ADC_CommonInitStructure);

  /*!< ADC1 Init */
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  //ADC_InitStructure.ADC_ScanConvMode = ENABLE;
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConvEdge = 
ADC_ExternalTrigConvEdge_None;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  //ADC_InitStructure.ADC_NbrOfConversion = 3;
  ADC_InitStructure.ADC_NbrOfConversion = 1;
  ADC_Init(ADC1, &ADC_InitStructure);

  /*!< ADC1 regular channel configuration */
  ADC_RegularChannelConfig(ADC1, HMI_GIER_ADC_CHANNEL, 1, 
ADC_SampleTime_3Cycles);
  //ADC_RegularChannelConfig(ADC1, HMI_THROTTLE_ADC_CHANNEL, 2, 
ADC_SampleTime_3Cycles);
  //ADC_RegularChannelConfig(ADC1, ADC_Channel_TempSensor, 3, 
ADC_SampleTime_3Cycles);

  /*!< Enable DMA request after last transfer (Single-ADC mode) */
  ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);

  /*!< Enable ADC1 DMA */
  ADC_DMACmd(ADC1, ENABLE);

  /*!< Enable ADC1 */
  ADC_Cmd(ADC1, ENABLE);

  /*!< Start ADC1 Software Conversion */
  ADC_SoftwareStartConv(ADC1);

Danke für eure Hilfe im Voraus,
Alex
Gast #2782035
Lesenswert?

>funktioniert aber immer noch nicht.

Was funktioniert nicht?
Ich wäre da ganz vorsichtig per DMA Daten in eine
so ungünstig aufgebaute Struktur zu übertragen.
Stichworte Alignment und Padding.
Und lass dir mal sizeof(SENSORS_t); ausgeben.
Das wird nicht 8 sein;)
Gast #2782198
Lesenswert?

>So, Start- und Stopmarkierung auf uint16_t aufgeblasen und jetzt
>funktioniert's (auch im scanmode).
>Das Seltsame: sollte die DMA nicht trotz misalignment Daten kopieren,
>nur um 1 Byte verschoben?

Dann hast du wohl ein pack-struct in den Compileroptionen?
In dem Fall wolltest du Halfwords auf ungerade Adressen schreiben.
Und das geht laut Datenblatt nicht mit dem DMA.
Gast #2782237
Lesenswert?

>Nicht das ich wüsste. Für's makefile benutze ich das Eclipse GNU ARM
>plugin und darin sind alle pack-structures deaktiviert.

Hmm. Dann hätte das gehen müssen.
Oder du warst nicht darauf vorbereitet das:

typedef struct {
  uint8_t    start;

hier ein Padding Byte eingefügt wird.

  uint16_t  gier;
  uint16_t  throttle;


>Hast du sonst noch eine Idee?

Das alte Programm das nicht funktioniert noch mal hernehmen
und dann mal im Map File nachsehen was da los ist.
An welcher Adresse liegt die Struktur und wie groß ist sie.
OP #2782249
Lesenswert?

Es sind zwei paddingbytes vorhanden, die Addresse sieht gut aus.
Wie gesagt, das die Daten misaligned sind war zu erwarten, aber das die 
DMA erst gar keine Daten schreibt kann ich nicht nachvollziehen.
Bzw.: da ich nie mit SENSOR_States+x sondern mit SENSOR_states.stelle 
arbeite, sollte der Compiler nicht automatisch das paddingbyte bei der 
Addressberechnung berücksichtigen?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren