Picproje Elektronik Sitesi

PICPROJE PROGRAMLAMA DERSLERİ => STM32 Örnekleri => Konuyu başlatan: Klein - 18 Kasım 2012, 23:08:00

Başlık: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: Klein - 18 Kasım 2012, 23:08:00
STM 32 içerisindeki ADC'lerde Regular kanalların tümü için sadece 1 adet sonuç registeri var.
Eğer ADC scan modda ise ve birden fazla kanal çevirime giriyorsa; ADC çevrimi tamamlayınca değer bu registere yazılıyor ve bir sonraki çevrime geiliyor. Bu çevrim de bittiğinde, sonuç yine aynı registere yazılıyor. 
Bir sonraki çevirim bitmeden ADC'yi okudunuz okudunuz. Okuyamazsanız o kanalın verisine elveda deyin.

ADC'yi  tek kanal çalıştırıp, Scan modu kapatıp, her çevirim bittiğinde değeri okumak ve birsonraki kanalı SQR registerine yazıp, çevirimi tekrar başlatmak bir çözüm.

Eğer ben her seferinde tüm kanalları taramayayım ADC kendisi SCAN etsin istiyorsanız, yukarıda bahsettiğim sebepten ötürü işler biraz karışıyor.   Eğer scan mode kullanılıyorsa, loop içinde bu çevirimlere yetişmek mümkün değil. İlla ki interrupt kullanmak gerekiyor. 
STM32F1'de  interrupt kullanmak ta çözüm değil.  Çünkü kesme  tüm kanalların çevirimi bittikten sonra geliyor.
STM32F4'te CR2 registerinde EOCS biti vardı. Bunu set ederek , her kanalın çevirimi bittiğinde kesme üret diyebiliyorduk. Ama STM32F1'de bu bit yok. (Belki benzer bir şey var ama ben bulamadım)

Bu durumda geriye tek seçenek  DMA kullanmak kalıyor. DMA kullandığınızda her kanalın çevrimi bittiğinde DMA bu değeri alıp, sırayla istediğiniz adreslere yazıyor. 

Önce donanımlara saat sinyali sağlayalım ve port ayarlarını yapalım.

void init_gpio(void){
GPIO_InitTypeDef  GPIO_InitStructure;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1 | GPIO_Pin_2 |GPIO_Pin_3 | \
   GPIO_Pin_4 |GPIO_Pin_5 | GPIO_Pin_6 |GPIO_Pin_7 ;
GPIO_Init(GPIOA, &GPIO_InitStructure);

}

void init_rcc(void){
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1 | RCC_APB2Periph_AFIO,ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
}


uint16_t ADC_ValArray[8]; // ADC değerlerimiz bu diziye atılacak


ADC Ayarlarımızı yapalım.
void init_adc1(void)
{
ADC_InitTypeDef  ADC_InitStructure;

  RCC_ADCCLKConfig(RCC_PCLK2_Div2);
  ADC_DeInit(ADC1);

  ADC_InitStructure.ADC_ScanConvMode = ENABLE; // tarama modu açık
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; // sürekli çevirim yapacağız
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfChannel = 8; // sekiz kanal tarayacağız.
  ADC_Init(ADC1, &ADC_InitStructure);

  ADC_Cmd(ADC1, ENABLE);

  ADC_ResetCalibration(ADC1);
  while(ADC_GetResetCalibrationStatus(ADC1));

  ADC_StartCalibration(ADC1);
  while(ADC_GetCalibrationStatus(ADC1));
}


Hangi kanalların çevirime gireceğini ve hangi sırada çevirime gireceklerini ayarlayalım.
void adc_channel_config(void){
ADC_RegularChannelConfig(ADC1,ADC_Channel_0, 1, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_1, 2, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_2, 3, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_3, 4, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_4, 5, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_5, 6, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_6, 7, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_7, 8, ADC_SampleTime_239Cycles5);
}


ADC1 için DMA Ayarlarını yapalım.


void ADC1_DMAConfig(void){
DMA_InitTypeDef DMA_InitStructure;

  DMA_Cmd(DMA1_Channel1,DISABLE);
  DMA_DeInit ( DMA1_Channel1);

  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)0x4001244C; // ADC->DR Adresi
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) ADC_ValArray; // hedef adresimiz
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; // ADC kaynak. Veri yönü ADC -> Hafıza
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // ADC adresi sabit kalacak
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // Her değer alındığına memory adresi 1 artırılacak
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;  // Kaynaktan alınacak veri 16 bit
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // Hedef büyüklüğü 16 bit
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // 8 veri alındıktan sonra başa dönülecek.
  DMA_InitStructure.DMA_Priority = DMA_Priority_High ; // Kanal Önceliği yüksek. ( bu bize kalmış)
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; // hafızadan hafızaya transfer kapalı.
  DMA_InitStructure.DMA_BufferSize = 8; // Alacağımız verisayısı 8 ( 8 kanal adc okuyacağız)
 
  DMA_Init(DMA1_Channel1, &DMA_InitStructure);
  DMA_Cmd(DMA1_Channel1,ENABLE);

}
 


int main(void){
     init_rcc();
     init_gpio();
     adc_channel_config();
     init_adc1();
    ADC1_DMAConfig();
    ADC_DMACmd(ADC1,ENABLE);
    ADC_SoftwareStartConvCmd(ADC1,ENABLE); // çevirimi başlatıyoruz.
while(1)
{
}

}


8 kanalın değeri dizimizde hazır.
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: X-Fi - 19 Kasım 2012, 07:50:14
Ben buna benzer bir işlemi tek adc kanalıyla arka arkaya okuyup buffer a yükleyerek yapmakya çalışmıştım amacım sinyal örneklemekti . F1 DMA sında adc okunup buffera kaydediyor ama ikinci çevrimde bufferı arttırmıyordu.

Sonra injected modunu denedim burda arka arkaya 4 örnek alıyor her çevrimin okuma adresleri belli DMA busefer istediğim gibi bufferlamıştı ama örnekleme sayısını yetersiz görüp bıraktım.

ADC+DMA ile sinyal örnekleme üzerine fikri olan varsa alabilirim kullandığım işlemci STM32L152D.
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: Klein - 19 Kasım 2012, 12:38:24
Az önce sizin yapmaya çalıştığınız gibi tek kanal , uzun buffer ayarlayarak denedim. bir sorun görünmüyor.
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: X-Fi - 19 Kasım 2012, 12:57:13
Ben tetiklemede timer kullanmadım belki ondan olabilir normalde dma modülün  adc flaglarıyla tetiklenebilmesi gerekir diye düşünüyorum.
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: Erhan YILMAZ - 19 Kasım 2012, 13:10:01
Hocam elinize sağlık adc ve dma kullanımıyla ilgili güzel bir örnek olmuş. Yol gösterici örnekler gerçekten.
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: Klein - 19 Kasım 2012, 14:32:57
Alıntı yapılan: X-Fi - 19 Kasım 2012, 12:57:13
Ben tetiklemede timer kullanmadım belki ondan olabilir normalde dma modülün  adc flaglarıyla tetiklenebilmesi gerekir diye düşünüyorum.
Ben de timer kullanmadım zaten. Tetiklemeyi ADC yapıyor.

Eğer veriyi alırken circular buffer kullanmıyorsanız, dma  işini bitirdikten sonra  DMA yı disable yapıp, yeni transfer için tekrar enable yapmak gerekiyor. 
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: X-Fi - 19 Kasım 2012, 15:28:08
Hocam sonuçları rame yüklüyorum örnekleme uzayabiliyor. Söylediğiniz mantıklı onu denememiştim denerim aslında amacım kod yazmamak işi donanıma yaptırmak değildi en hızlı şekilde örnekleme almaktı. DMAyı açıp kapatmak bir zaman kaybı olabilir belkide bukadar zamanda ben ADC DR bufferı okuyup yeniden çevrimide başlatabilirim.

Konu dağılmasın DMA lazımsız bir donanım değil tabiki özellikle DAC olan tüm uygulamalarda kullanmak isteyeceksiniz. Herkeze iyi çalışmalar.
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: XX_CİHAN_XX - 03 Şubat 2013, 15:22:38
STM32F4, 4 kanal ADC1 - DMA uygulaması


uint16_t ADC_ValArray[4];

void ADC1_CH2_DMA_Config(void)
{
  ADC_InitTypeDef       ADC_InitStructure;
  ADC_CommonInitTypeDef ADC_CommonInitStructure;
  DMA_InitTypeDef       DMA_InitStructure;
  GPIO_InitTypeDef      GPIO_InitStructure;

  /* Enable ADC1, DMA1 and GPIO clocks ****************************************/
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

  /* DMA2 Stream0 channel0 configuration **************************************/
  DMA_InitStructure.DMA_Channel = DMA_Channel_0; 
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_ADDRESS;
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)ADC_ValArray;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
  DMA_InitStructure.DMA_BufferSize = 4;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  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(DMA2_Stream0, &DMA_InitStructure);
  DMA_Cmd(DMA2_Stream0, 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_5Cycles;
  ADC_CommonInit(&ADC_CommonInitStructure);

  /* ADC1 Init ****************************************************************/
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  ADC_InitStructure.ADC_ScanConvMode = ENABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfConversion = 4;
  ADC_Init(ADC1, &ADC_InitStructure);

  /* ADC regular channel2 configuration *************************************/
  ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_3Cycles);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 2, ADC_SampleTime_3Cycles);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 3, ADC_SampleTime_3Cycles);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 4, 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);
}



int main (void)
{

  ADC1_CH2_DMA_Config();
  ADC_SoftwareStartConv(ADC1);

           .................

}


ADC_ValArray in içine adc verilerini göndermeyi başaramadım bir türlü

Edit:
Bütün olay yanlış DMA kanalını seçtiğim içinmiş... ADC1, DMA Channel  0 dan kullanılması gerekiyormuş.
Kodlar düzgün çalışır vaziyette editlenmiştir...
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: Klein - 28 Şubat 2013, 16:50:59
Örnekte küçük bir hata varmış. Daha doğrusu eksik varmış.  GPIO ve RCC init rutinleri olduğu halde hiç çağırılmamış. Önce bu dutinlerin çağırılması gerekiyor.  Yer kaplamasın diye  örnek üzerinde düzenleme yaptım.
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: respected - 25 Mart 2013, 15:22:36
XX_CİHAN_XX;

Merhaba, hangi ADC kanalının hangi DMA yı kullandığını nereden anlıyoruz.  Ya da hangi dökümanda var bunlar. Teşekkürler
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: XX_CİHAN_XX - 25 Mart 2013, 19:44:34
Alıntı yapılan: respected - 25 Mart 2013, 15:22:36
XX_CİHAN_XX;

Merhaba, hangi ADC kanalının hangi DMA yı kullandığını nereden anlıyoruz.  Ya da hangi dökümanda var bunlar. Teşekkürler

RM0090 Referance Manual Sayfa 164 Channel Selection kısmına bakınız.
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: SpeedyX - 25 Mart 2013, 23:03:11
3 adc yi 3 dma ile ayrı ayrı kullanabiliriz öyle değil mi?


#include "stm32f10x.h"

/** @addtogroup STM32F10x_StdPeriph_Examples
  * @{
  */

/** @addtogroup ADC_3ADCs_DMA
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define ADC1_DR_Address    ((uint32_t)0x4001244C)
#define ADC3_DR_Address    ((uint32_t)0x40013C4C)

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
ADC_InitTypeDef ADC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
__IO uint16_t ADC1ConvertedValue = 0, ADC3ConvertedValue = 0;
ErrorStatus HSEStartUpStatus;   

/* Private function prototypes -----------------------------------------------*/
void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
 
/* Private functions ---------------------------------------------------------*/

/**
  * @brief   Main program
  * @param  None
  * @retval None
  */
int main(void)
{
  /* System clocks configuration ---------------------------------------------*/
  RCC_Configuration();

  /* NVIC configuration ------------------------------------------------------*/
  NVIC_Configuration();

  /* GPIO configuration ------------------------------------------------------*/
  GPIO_Configuration();

  /* DMA1 channel1 configuration ----------------------------------------------*/
  DMA_DeInit(DMA1_Channel1);
  DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC1ConvertedValue;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = 1;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  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_M2M = DMA_M2M_Disable;
  DMA_Init(DMA1_Channel1, &DMA_InitStructure); 
  /* Enable DMA1 channel1 */
  DMA_Cmd(DMA1_Channel1, ENABLE);

  /* DMA2 channel5 configuration ----------------------------------------------*/
  DMA_DeInit(DMA2_Channel5);
  DMA_InitStructure.DMA_PeripheralBaseAddr = ADC3_DR_Address;
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC3ConvertedValue;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = 1;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  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_M2M = DMA_M2M_Disable;
  DMA_Init(DMA2_Channel5, &DMA_InitStructure); 
  /* Enable DMA2 channel5 */
  DMA_Cmd(DMA2_Channel5, ENABLE);
     
  /* ADC1 configuration ------------------------------------------------------*/
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfChannel = 1;
  ADC_Init(ADC1, &ADC_InitStructure);
  /* ADC1 regular channels configuration */
  ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_28Cycles5);   
  /* Enable ADC1 DMA */
  ADC_DMACmd(ADC1, ENABLE);

  /* ADC2 configuration ------------------------------------------------------*/
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfChannel = 1;
  ADC_Init(ADC2, &ADC_InitStructure);
  /* ADC2 regular channels configuration */
  ADC_RegularChannelConfig(ADC2, ADC_Channel_13, 1, ADC_SampleTime_28Cycles5);
  /* Enable ADC2 EOC interupt */
  ADC_ITConfig(ADC2, ADC_IT_EOC, ENABLE);

  /* ADC3 configuration ------------------------------------------------------*/
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfChannel = 1;
  ADC_Init(ADC3, &ADC_InitStructure);
  /* ADC3 regular channel14 configuration */
  ADC_RegularChannelConfig(ADC3, ADC_Channel_12, 1, ADC_SampleTime_28Cycles5);
  /* Enable ADC3 DMA */
  ADC_DMACmd(ADC3, ENABLE);

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

  /* Enable ADC1 reset calibaration register */   
  ADC_ResetCalibration(ADC1);
  /* Check the end of ADC1 reset calibration register */
  while(ADC_GetResetCalibrationStatus(ADC1));

  /* Start ADC1 calibaration */
  ADC_StartCalibration(ADC1);
  /* Check the end of ADC1 calibration */
  while(ADC_GetCalibrationStatus(ADC1));

  /* Enable ADC2 */
  ADC_Cmd(ADC2, ENABLE);

  /* Enable ADC2 reset calibaration register */   
  ADC_ResetCalibration(ADC2);
  /* Check the end of ADC2 reset calibration register */
  while(ADC_GetResetCalibrationStatus(ADC2));

  /* Start ADC2 calibaration */
  ADC_StartCalibration(ADC2);
  /* Check the end of ADC2 calibration */
  while(ADC_GetCalibrationStatus(ADC2));

  /* Enable ADC3 */
  ADC_Cmd(ADC3, ENABLE);

  /* Enable ADC3 reset calibaration register */   
  ADC_ResetCalibration(ADC3);
  /* Check the end of ADC3 reset calibration register */
  while(ADC_GetResetCalibrationStatus(ADC3));

  /* Start ADC3 calibaration */
  ADC_StartCalibration(ADC3);
  /* Check the end of ADC3 calibration */
  while(ADC_GetCalibrationStatus(ADC3));

  /* Start ADC1 Software Conversion */
  ADC_SoftwareStartConvCmd(ADC1, ENABLE);
  /* Start ADC2 Software Conversion */
  ADC_SoftwareStartConvCmd(ADC2, ENABLE);
  /* Start ADC3 Software Conversion */
  ADC_SoftwareStartConvCmd(ADC3, ENABLE);

  while (1)
  {
  }
}

/**
  * @brief  Configures the different system clocks.
  * @param  None
  * @retval None
  */
void RCC_Configuration(void)
{
  /* RCC system reset(for debug purpose) */
  RCC_DeInit();

  /* Enable HSE */
  RCC_HSEConfig(RCC_HSE_ON);

  /* Wait till HSE is ready */
  HSEStartUpStatus = RCC_WaitForHSEStartUp();

  if(HSEStartUpStatus == SUCCESS)
  {
    /* Enable Prefetch Buffer */
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

    /* Flash 2 wait state */
    FLASH_SetLatency(FLASH_Latency_2);
 
    /* HCLK = SYSCLK */
    RCC_HCLKConfig(RCC_SYSCLK_Div1);
 
    /* PCLK2 = HCLK */
    RCC_PCLK2Config(RCC_HCLK_Div1);

    /* PCLK1 = HCLK/2 */
    RCC_PCLK1Config(RCC_HCLK_Div2);

    /* ADCCLK = PCLK2/4 */
    RCC_ADCCLKConfig(RCC_PCLK2_Div4);
   
    /* PLLCLK = 8MHz * 7 = 56 MHz */
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_7);

    /* Enable PLL */
    RCC_PLLCmd(ENABLE);

    /* Wait till PLL is ready */
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
    {
    }

    /* Select PLL as system clock source */
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

    /* Wait till PLL is used as system clock source */
    while(RCC_GetSYSCLKSource() != 0x08)
    {
    }
  }

/* Enable peripheral clocks --------------------------------------------------*/
  /* Enable DMA1 and DMA2 clocks */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 | RCC_AHBPeriph_DMA2, ENABLE);

  /* Enable ADC1, ADC2, ADC3 and GPIOC clocks */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 |
                         RCC_APB2Periph_ADC3 | RCC_APB2Periph_GPIOC, ENABLE);
}

/**
  * @brief  Configures the different GPIO ports.
  * @param  None
  * @retval None
  */
void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  /* Configure PC.02, PC.03 and PC.04 (ADC Channel12, ADC Channel13 and
     ADC Channel14) as analog inputs */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
}

/**
  * @brief  Configures Vector Table base location.
  * @param  None
  * @retval None
  */
void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;

  /* Configure and enable ADC interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

#ifdef  USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *   where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif

/**
  * @}
  */

/**
  * @}
  */

/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: respected - 25 Mart 2013, 23:54:18
Evet buldum.  Teşekkürler. Bendeki RM0090 Referance Manual Sayfa 216 imiş.
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: SpeedyX - 26 Mart 2013, 10:14:49
/**
  ******************************************************************************
  * @file    ADC/3ADCs_DMA/main.c
  * @author  MCD Application Team
  * @version V3.5.0
  * @date    08-April-2011
  * @brief   Main program body
  ******************************************************************************
  * @attention
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"

/** @addtogroup STM32F10x_StdPeriph_Examples
  * @{
  */

/** @addtogroup ADC_3ADCs_DMA
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define ADC1_DR_Address    ((uint32_t)0x4001244C)
#define ADC3_DR_Address    ((uint32_t)0x40013C4C)

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
ADC_InitTypeDef ADC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
__IO uint16_t ADC1ConvertedValue = 0, ADC3ConvertedValue = 0;

/* Private function prototypes -----------------------------------------------*/
void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);

/* Private functions ---------------------------------------------------------*/

/**
  * @brief   Main program
  * @param  None
  * @retval None
  */
int main(void)
{
  /*!< At this stage the microcontroller clock setting is already configured,
       this is done through SystemInit() function which is called from startup
       file (startup_stm32f10x_xx.s) before to branch to application main.
       To reconfigure the default setting of SystemInit() function, refer to
       system_stm32f10x.c file
     */     
       
  /* System clocks configuration ---------------------------------------------*/
  RCC_Configuration();

  /* NVIC configuration ------------------------------------------------------*/
  NVIC_Configuration();

  /* GPIO configuration ------------------------------------------------------*/
  GPIO_Configuration();

  /* DMA1 channel1 configuration ----------------------------------------------*/
  DMA_DeInit(DMA1_Channel1);
  DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC1ConvertedValue;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = 1;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  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_M2M = DMA_M2M_Disable;
  DMA_Init(DMA1_Channel1, &DMA_InitStructure); 
  /* Enable DMA1 channel1 */
  DMA_Cmd(DMA1_Channel1, ENABLE);

  /* DMA2 channel5 configuration ----------------------------------------------*/
  DMA_DeInit(DMA2_Channel5);
  DMA_InitStructure.DMA_PeripheralBaseAddr = ADC3_DR_Address;
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC3ConvertedValue;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = 1;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  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_M2M = DMA_M2M_Disable;
  DMA_Init(DMA2_Channel5, &DMA_InitStructure); 
  /* Enable DMA2 channel5 */
  DMA_Cmd(DMA2_Channel5, ENABLE);

  /* ADC1 configuration ------------------------------------------------------*/
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfChannel = 1;
  ADC_Init(ADC1, &ADC_InitStructure);
  /* ADC1 regular channels configuration */
  ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_28Cycles5);   
  /* Enable ADC1 DMA */
  ADC_DMACmd(ADC1, ENABLE);

  /* ADC2 configuration ------------------------------------------------------*/
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfChannel = 1;
  ADC_Init(ADC2, &ADC_InitStructure);
  /* ADC2 regular channels configuration */
  ADC_RegularChannelConfig(ADC2, ADC_Channel_13, 1, ADC_SampleTime_28Cycles5);
  /* Enable ADC2 EOC interrupt */
  ADC_ITConfig(ADC2, ADC_IT_EOC, ENABLE);

  /* ADC3 configuration ------------------------------------------------------*/
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfChannel = 1;
  ADC_Init(ADC3, &ADC_InitStructure);
  /* ADC3 regular channel14 configuration */
  ADC_RegularChannelConfig(ADC3, ADC_Channel_12, 1, ADC_SampleTime_28Cycles5);
  /* Enable ADC3 DMA */
  ADC_DMACmd(ADC3, ENABLE);

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

  /* Enable ADC1 reset calibration register */   
  ADC_ResetCalibration(ADC1);
  /* Check the end of ADC1 reset calibration register */
  while(ADC_GetResetCalibrationStatus(ADC1));

  /* Start ADC1 calibration */
  ADC_StartCalibration(ADC1);
  /* Check the end of ADC1 calibration */
  while(ADC_GetCalibrationStatus(ADC1));

  /* Enable ADC2 */
  ADC_Cmd(ADC2, ENABLE);

  /* Enable ADC2 reset calibration register */   
  ADC_ResetCalibration(ADC2);
  /* Check the end of ADC2 reset calibration register */
  while(ADC_GetResetCalibrationStatus(ADC2));

  /* Start ADC2 calibration */
  ADC_StartCalibration(ADC2);
  /* Check the end of ADC2 calibration */
  while(ADC_GetCalibrationStatus(ADC2));

  /* Enable ADC3 */
  ADC_Cmd(ADC3, ENABLE);

  /* Enable ADC3 reset calibration register */   
  ADC_ResetCalibration(ADC3);
  /* Check the end of ADC3 reset calibration register */
  while(ADC_GetResetCalibrationStatus(ADC3));

  /* Start ADC3 calibration */
  ADC_StartCalibration(ADC3);
  /* Check the end of ADC3 calibration */
  while(ADC_GetCalibrationStatus(ADC3));

  /* Start ADC1 Software Conversion */
  ADC_SoftwareStartConvCmd(ADC1, ENABLE);
  /* Start ADC2 Software Conversion */
  ADC_SoftwareStartConvCmd(ADC2, ENABLE);
  /* Start ADC3 Software Conversion */
  ADC_SoftwareStartConvCmd(ADC3, ENABLE);

  while (1)
  {
  }
}

/**
  * @brief  Configures the different system clocks.
  * @param  None
  * @retval None
  */
void RCC_Configuration(void)
{
  /* ADCCLK = PCLK2/4 */
  RCC_ADCCLKConfig(RCC_PCLK2_Div4);
   
  /* Enable peripheral clocks ------------------------------------------------*/
  /* Enable DMA1 and DMA2 clocks */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 | RCC_AHBPeriph_DMA2, ENABLE);

  /* Enable ADC1, ADC2, ADC3 and GPIOC clocks */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 |
                         RCC_APB2Periph_ADC3 | RCC_APB2Periph_GPIOC, ENABLE);
}

/**
  * @brief  Configures the different GPIO ports.
  * @param  None
  * @retval None
  */
void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  /* Configure PC.02, PC.03 and PC.04 (ADC Channel12, ADC Channel13 and
     ADC Channel14) as analog inputs */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
}

/**
  * @brief  Configures Vector Table base location.
  * @param  None
  * @retval None
  */
void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;

  /* Configure and enable ADC interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

#ifdef  USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}

#endif

/**
  * @}
  */

/**
  * @}
  */

/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: camby - 26 Mart 2013, 10:25:41
Timer event tetiklemeli ADC örneği var mı ? ST örneklerinde de bulamadım.

EXTSEL[3:0] ile istediğim timer event'ını seçeceğim , daha sonra timer taşması adc'yi başlatacak mı direk nasıl olacak ?
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: SpeedyX - 03 Nisan 2013, 14:25:33
Dual Simultaneous Sampling (http://wiki.leaflabs.com/index.php?title=Dual_Simultaneous_Sampling) ile ilgilenen var mı?

Örneğin ADC1 ile 2 kanal, ADC3 ile 2 kanal (ve ADC2 ile 2 kanal) ölçümü DMA ve Dual modda mümkün olan en hızlı şekilde nasıl yapabiliriz?
ADC1 i dual mod kurup DMA ile okutup sonucu RAM e yazabiliriz, aynı şekilde başka DMA kanallarıyla da ADC3 (ve ADC2) yi okutabilir miyiz? Aynı DMA da bir de DAC işlemleri olsa DMA her işlemi sırayla mı yapar yoksa tüm kanallar paralel çalışabiliyor mu?


Yukarıdaki kodun, eksiklerinin tamamlanmış hali:
/**
  ******************************************************************************
  * @file    ADC/3ADCs_DMA/main.c
  * @author  MCD Application Team
  * @version V3.5.0
  * @date    08-April-2011
  * @brief   Main program body
  ******************************************************************************
  * @attention
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"

/** @addtogroup STM32F10x_StdPeriph_Examples
  * @{
  */

/** @addtogroup ADC_3ADCs_DMA
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define ADC1_DR_Address    ((uint32_t)0x4001244C)
#define ADC3_DR_Address    ((uint32_t)0x40013C4C)

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
__IO uint16_t ADC1ConvertedValue = 0, ADC3ConvertedValue = 0, ADC2ConvertedValue = 0;

/* Private function prototypes -----------------------------------------------*/

/* Private functions ---------------------------------------------------------*/

void ADC1_2_IRQHandler(void)
{
  /* Get injected channel13 converted value */
  ADC2ConvertedValue = ADC_GetConversionValue(ADC2);
}

/**
  * @brief   Main program
  * @param  None
  * @retval None
  */
void ADC_DMA_INIT(void)
{
  ADC_InitTypeDef ADC_InitStructure;
  DMA_InitTypeDef DMA_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;

  /*!< At this stage the microcontroller clock setting is already configured,
       this is done through SystemInit() function which is called from startup
       file (startup_stm32f10x_xx.s) before to branch to application main.
       To reconfigure the default setting of SystemInit() function, refer to
       system_stm32f10x.c file
     */     
       
  /* System clocks configuration ---------------------------------------------*/
  /* ADCCLK = PCLK2/4 */
  RCC_ADCCLKConfig(RCC_PCLK2_Div4);
  /* Enable peripheral clocks ------------------------------------------------*/
  /* Enable DMA1 and DMA2 clocks */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 | RCC_AHBPeriph_DMA2, ENABLE);

  /* Enable ADC1, ADC2, ADC3 and GPIOC clocks */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 |
                         RCC_APB2Periph_ADC3 | RCC_APB2Periph_GPIOC, ENABLE);


  /* NVIC configuration ------------------------------------------------------*/
  /* Configure and enable ADC interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);


  /* GPIO configuration ------------------------------------------------------*/
  /* Configure PC.02, PC.03 and PC.04 (ADC Channel12, ADC Channel13 and
     ADC Channel14) as analog inputs */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
 
 
  /* DMA1 channel1 configuration ----------------------------------------------*/
  DMA_DeInit(DMA1_Channel1);
  DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC1ConvertedValue;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = 1;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  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_M2M = DMA_M2M_Disable;
  DMA_Init(DMA1_Channel1, &DMA_InitStructure); 
  /* Enable DMA1 channel1 */
  DMA_Cmd(DMA1_Channel1, ENABLE);

  /* DMA2 channel5 configuration ----------------------------------------------*/
  DMA_DeInit(DMA2_Channel5);
  DMA_InitStructure.DMA_PeripheralBaseAddr = ADC3_DR_Address;
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC3ConvertedValue;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = 1;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  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_M2M = DMA_M2M_Disable;
  DMA_Init(DMA2_Channel5, &DMA_InitStructure); 
  /* Enable DMA2 channel5 */
  DMA_Cmd(DMA2_Channel5, ENABLE);

  /* ADC1 configuration ------------------------------------------------------*/
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfChannel = 1;
  ADC_Init(ADC1, &ADC_InitStructure);
  /* ADC1 regular channels configuration */
  ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_28Cycles5);   
  /* Enable ADC1 DMA */
  ADC_DMACmd(ADC1, ENABLE);

  /* ADC2 configuration ------------------------------------------------------*/
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfChannel = 1;
  ADC_Init(ADC2, &ADC_InitStructure);
  /* ADC2 regular channels configuration */
  ADC_RegularChannelConfig(ADC2, ADC_Channel_13, 1, ADC_SampleTime_28Cycles5);
  /* Enable ADC2 EOC interrupt */
  ADC_ITConfig(ADC2, ADC_IT_EOC, ENABLE);

  /* ADC3 configuration ------------------------------------------------------*/
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfChannel = 1;
  ADC_Init(ADC3, &ADC_InitStructure);
  /* ADC3 regular channel14 configuration */
  ADC_RegularChannelConfig(ADC3, ADC_Channel_12, 1, ADC_SampleTime_28Cycles5);
  /* Enable ADC3 DMA */
  ADC_DMACmd(ADC3, ENABLE);

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

  /* Enable ADC1 reset calibration register */   
  ADC_ResetCalibration(ADC1);
  /* Check the end of ADC1 reset calibration register */
  while(ADC_GetResetCalibrationStatus(ADC1));

  /* Start ADC1 calibration */
  ADC_StartCalibration(ADC1);
  /* Check the end of ADC1 calibration */
  while(ADC_GetCalibrationStatus(ADC1));

  /* Enable ADC2 */
  ADC_Cmd(ADC2, ENABLE);

  /* Enable ADC2 reset calibration register */   
  ADC_ResetCalibration(ADC2);
  /* Check the end of ADC2 reset calibration register */
  while(ADC_GetResetCalibrationStatus(ADC2));

  /* Start ADC2 calibration */
  ADC_StartCalibration(ADC2);
  /* Check the end of ADC2 calibration */
  while(ADC_GetCalibrationStatus(ADC2));

  /* Enable ADC3 */
  ADC_Cmd(ADC3, ENABLE);

  /* Enable ADC3 reset calibration register */   
  ADC_ResetCalibration(ADC3);
  /* Check the end of ADC3 reset calibration register */
  while(ADC_GetResetCalibrationStatus(ADC3));

  /* Start ADC3 calibration */
  ADC_StartCalibration(ADC3);
  /* Check the end of ADC3 calibration */
  while(ADC_GetCalibrationStatus(ADC3));

  /* Start ADC1 Software Conversion */
  ADC_SoftwareStartConvCmd(ADC1, ENABLE);
  /* Start ADC2 Software Conversion */
  ADC_SoftwareStartConvCmd(ADC2, ENABLE);
  /* Start ADC3 Software Conversion */
  ADC_SoftwareStartConvCmd(ADC3, ENABLE);
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}

#endif

/**
  * @}
  */

/**
  * @}
  */

/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: camby - 09 Nisan 2013, 14:06:57
Alıntı yapılan: Klein - 18 Kasım 2012, 23:08:00
STM 32 içerisindeki ADC'lerde Regular kanalların tümü için sadece 1 adet sonuç registeri var.
Eğer ADC scan modda ise ve birden fazla kanal çevirime giriyorsa; ADC çevrimi tamamlayınca değer bu registere yazılıyor ve bir sonraki çevrime geiliyor. Bu çevrim de bittiğinde, sonuç yine aynı registere yazılıyor. 
Bir sonraki çevirim bitmeden ADC'yi okudunuz okudunuz. Okuyamazsanız o kanalın verisine elveda deyin.

ADC'yi  tek kanal çalıştırıp, Scan modu kapatıp, her çevirim bittiğinde değeri okumak ve birsonraki kanalı SQR registerine yazıp, çevirimi tekrar başlatmak bir çözüm.

Eğer ben her seferinde tüm kanalları taramayayım ADC kendisi SCAN etsin istiyorsanız, yukarıda bahsettiğim sebepten ötürü işler biraz karışıyor.   Eğer scan mode kullanılıyorsa, loop içinde bu çevirimlere yetişmek mümkün değil. İlla ki interrupt kullanmak gerekiyor. 
STM32F1'de  interrupt kullanmak ta çözüm değil.  Çünkü kesme  tüm kanalların çevirimi bittikten sonra geliyor.
STM32F4'te CR2 registerinde EOCS biti vardı. Bunu set ederek , her kanalın çevirimi bittiğinde kesme üret diyebiliyorduk. Ama STM32F1'de bu bit yok. (Belki benzer bir şey var ama ben bulamadım)

Bu durumda geriye tek seçenek  DMA kullanmak kalıyor. DMA kullandığınızda her kanalın çevrimi bittiğinde DMA bu değeri alıp, sırayla istediğiniz adreslere yazıyor. 

Önce donanımlara saat sinyali sağlayalım ve port ayarlarını yapalım.

void init_gpio(void){
GPIO_InitTypeDef  GPIO_InitStructure;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1 | GPIO_Pin_2 |GPIO_Pin_3 | \
   GPIO_Pin_4 |GPIO_Pin_5 | GPIO_Pin_6 |GPIO_Pin_7 ;
GPIO_Init(GPIOA, &GPIO_InitStructure);

}

void init_rcc(void){
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1 | RCC_APB2Periph_AFIO,ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
}


uint16_t ADC_ValArray[8]; // ADC değerlerimiz bu diziye atılacak


ADC Ayarlarımızı yapalım.
void init_adc1(void)
{
ADC_InitTypeDef  ADC_InitStructure;

  RCC_ADCCLKConfig(RCC_PCLK2_Div2);
  ADC_DeInit(ADC1);

  ADC_InitStructure.ADC_ScanConvMode = ENABLE; // tarama modu açık
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; // sürekli çevirim yapacağız
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfChannel = 8; // sekiz kanal tarayacağız.
  ADC_Init(ADC1, &ADC_InitStructure);

  ADC_Cmd(ADC1, ENABLE);

  ADC_ResetCalibration(ADC1);
  while(ADC_GetResetCalibrationStatus(ADC1));

  ADC_StartCalibration(ADC1);
  while(ADC_GetCalibrationStatus(ADC1));
}


Hangi kanalların çevirime gireceğini ve hangi sırada çevirime gireceklerini ayarlayalım.
void adc_channel_config(void){
ADC_RegularChannelConfig(ADC1,ADC_Channel_0, 1, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_1, 2, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_2, 3, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_3, 4, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_4, 5, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_5, 6, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_6, 7, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_7, 8, ADC_SampleTime_239Cycles5);
}


ADC1 için DMA Ayarlarını yapalım.


void ADC1_DMAConfig(void){
DMA_InitTypeDef DMA_InitStructure;

  DMA_Cmd(DMA1_Channel1,DISABLE);
  DMA_DeInit ( DMA1_Channel1);

  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)0x4001244C; // ADC->DR Adresi
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) ADC_ValArray; // hedef adresimiz
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; // ADC kaynak. Veri yönü ADC -> Hafıza
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // ADC adresi sabit kalacak
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // Her değer alındığına memory adresi 1 artırılacak
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;  // Kaynaktan alınacak veri 16 bit
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // Hedef büyüklüğü 16 bit
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // 8 veri alındıktan sonra başa dönülecek.
  DMA_InitStructure.DMA_Priority = DMA_Priority_High ; // Kanal Önceliği yüksek. ( bu bize kalmış)
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; // hafızadan hafızaya transfer kapalı.
  DMA_InitStructure.DMA_BufferSize = 8; // Alacağımız verisayısı 8 ( 8 kanal adc okuyacağız)
 
  DMA_Init(DMA1_Channel1, &DMA_InitStructure);
  DMA_Cmd(DMA1_Channel1,ENABLE);

}
 


int main(void){
     init_rcc();
     init_gpio();
     adc_channel_config();
     init_adc1();
    ADC1_DMAConfig();
    ADC_DMACmd(ADC1,ENABLE);
    ADC_SoftwareStartConvCmd(ADC1,ENABLE); // çevirimi başlatıyoruz.
while(1)
{
}

}


8 kanalın değeri dizimizde hazır.

---------------------------

Hocam bu örnekler , hangi st lib versiyonu ile yazılmış ? Kullanmaya çalışıyorum direk ama dma.c ve dma.h dosyası içindeki neredeyse tüm tanımlamalar farklı. ADC ve diğer modüller için de bu geçerli. Acaba benim kullandığım mı eski sizinki mi ?


Benim kullandıklarım :

  * @file    stm32f4xx_dma.c
  * @author  MCD Application Team
  * @version V1.0.2
  * @date    05-March-2012


------------------

İşin garibi zipli bir şekilde indirdim driver dosyası içindeki kütüphane ve örnek kodlar arasında uyuşmazlık var.

İndirdiğim dosyanın adı : STM32F4xx_DSP_StdPeriph_Lib_V1.0.1

Dosya içindeki "STM32F4xx_StdPeriph_Driver" klasöründe bulunan library dosyalarının versiyonları hep V1.0.2

Aynı dosya içinde example bölümünde yazılmış olan kodlar da V1.0.1 için yazılmış.

.h header dosyalarında tanımlamalar v1.0.2'de farklı olduğu için çalışmıyor.

ST neden böyle bir şey yapıyor ? Ben bir birşeyleri karıştırıyorum acaba , kontrol edebilir misiniz ?

--------------------

Sitede şimdi de v.1.1.0 diye bir şey gördüm , onu indiriyorum...

Sürekli ST driverlarını değiştirecek , eski yazılmış programlar birbirine girecek.....


ADC_Init içinden , ADC_CommonInitStructure diye birşey türetmişler , bazı parametreleri oraya almışlar flan filan uzayıp gidiyor.....

/* 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_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: Klein - 09 Nisan 2013, 14:28:54
Örnek STM32F10x için.
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: camby - 09 Nisan 2013, 14:41:35
Alıntı yapılan: Klein - 09 Nisan 2013, 14:28:54
Örnek STM32F10x için.

Evet hocam ama V1.0.1 ile V1.0.2 arasında farklılıklar var. Yukarıdaki mesajımda sonradan yazdım , stm'den indirilen dosyadaki library ve örnek kodlar bile birbiri ile uyumsuz versiyonda gözüküyor. Neyse karıştırıp çözeceğim..


Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: Klein - 09 Nisan 2013, 16:39:29
/**
  ******************************************************************************
  * @file    stm32f10x_dma.h
  * @author  MCD Application Team
  * @version V3.5.0
  * @date    11-March-2011
  * @brief   This file contains all the functions prototypes for the DMA firmware
  *          library.
  ******************************************************************************
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: camby - 09 Nisan 2013, 17:05:47
tamam çalıştırdım..

V1.0.1 ile V1.0.2 gibi farklılar görünce stm32f4 library'de sıkıntı var diye düşündüm. Sıkıntı yok gibi.
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: Klein - 09 Nisan 2013, 17:52:23
DMA kanalları paralel çalışmıyor. Ancak Öncelik (veya önem) sırası ayarlanabiliyor.

Çok kanallı multiplex ADC'lerde kanalların birbirine sarkması gibi bir sorun var. Bu sadece STM32'nin ADC'si için geçerli değil. Tümünde böyle bir sorun var. Sorun ölçüm yönteminin doğasından kaynaklanıyor. Daha Önce de Z hocam bahsetmişti bir başlıkta.
Çok hızlı örnekleme ve kanal değişimi yaptığınızda , sample-hold kapasitesi tam boşalmadığı için diğer kanalın ölçüm sonucu değişiyor.
Eğer ADC girişini besleyen kaynağın empedansı yüksekse, bu daha da belirgin oluyor.
Eğer çok hızlı bir uygulama yapılacaksa , analog gerilim bir opamptan geçirilmeli. Ya da hız düşürülmeli.
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: SpeedyX - 09 Nisan 2013, 19:54:09
Hocam Dual Sampling de adc 2 kanalından aynı anda okuyor gibi bir durum olmalı. Örneğin DAC ı dual kullanarak 2 kanala ait 16 bit verileri 32 bitlik bir sayı olarak direkt update edebiliyorsunuz.

Örneğin DMA1 = DAC oldu, DMA3=ADC oldu. Bunlar paralel çalışır diye düşünüyorum. Fakat aynı DMA nın farklı kanalları seri çalışıyor.
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: Klein - 09 Nisan 2013, 21:06:28
Sözüm Aynı DMA'nın farklı kanalları içindi zaten.
Ancak
Farklı DMA kanalları bile olsa, ikisi de belleğe yazma ve bellekten okuma yaparken adres ve veri yolunu kullanacaklar. Biri belleğe yazarken diğeri bekleyecek.
Veri yolu ve adres yolununun nasıl paylaşıldığını bilmiyorum. 
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: SpeedyX - 09 Nisan 2013, 21:15:09
Muhtemelen priority mantığına göre yürüyordur.

ADC DAC mantığında işlemler paralel sayılabilir, çünkü ADC max 1us de sample alabiliyorsa, DAC da 0.25us de update edilsin, 36Mhz veri yolu hızı olduğuna göre... Zaten adc done bayrağı 1 Mhz hızla set oluyor.
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: mistek - 05 Eylül 2013, 02:13:01
Klein hocam ilk mesajınızda anlattığınız durumda DMA bizim ADC dizimizi her kanalın verisiyle doldurduktan sonra circular ayarladığımız için 2. turu atarken 1. turdaki verileri okuduk okuduk okuyamazsak onlarıda kaybedeceğiz değil mi?

Birde mesela 8 kanal ADC kullanıyorum ancak 1 ADC kanalının t=3 süresindeki değerini almak istiyorum. Bunu yapmak için ADC dizisinin ilgili elemanını t=3 anında okumam ile doğrudan o kanalı okumam arasında bir fark var mı?
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: Klein - 05 Eylül 2013, 07:04:35
Evet veri kaybolur.  Eğer T=3 verisini okumak istiyorsanız , Buffer uzunluğunu 3 kat artırıp, DMA buffer uzunluğunu 3 kat verirseniz 3 tur sonunda başa döner. Bufferin 3. bölümünü işlersiniz.
Doğrudan o kanalı okumaktan kasıt nedir? DMA kullanmadan mı?
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: mistek - 05 Eylül 2013, 09:42:23
Alıntı yapılan: Klein - 05 Eylül 2013, 07:04:35
Evet veri kaybolur.  Eğer T=3 verisini okumak istiyorsanız , Buffer uzunluğunu 3 kat artırıp, DMA buffer uzunluğunu 3 kat verirseniz 3 tur sonunda başa döner. Bufferin 3. bölümünü işlersiniz.
Doğrudan o kanalı okumaktan kasıt nedir? DMA kullanmadan mı?

Evet hocam DMA kullanmadan.

7 kanal sürekli olarak okunması gerekiyor sadece 1 tanesinin t=3  t=8 t=n anındaki değeri lazım, sadece bu kanala ait t=1 ve t=2 değerleri kaybolabilir problem değil.
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: Klein - 05 Eylül 2013, 12:01:10
Doğrudan okumanı önermem. Hatta 7 kanalı doğrudan okuman neredeyse imkansız. Eğer programda ADC okuma dışında pek bir şey yoksa, kesme ile belki. ADC hızını çok düşürmen gerekir.
Sebebini aynı başlıkta açıklamıştım.
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: mistek - 06 Eylül 2013, 02:10:25
DMA modülü ile 3 elemanlı adc dizisini dolduruyorum ancak sıralaması düşündüğüm gibi olmadı.
uint16_t adc[3] = {0};
Sıra olarak

ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 2, ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 3, ADC_SampleTime_55Cycles5);

ayarladım.

Beklediğim sonuç ise
adc[0] = Kanal 10 verisi
adc[1] = kanal 11 verisi
adc[2] = kanal 12 verisi

şeklindeydi.

Ancak öyle olmadı ve sonuç şu şekilde.
adc[0] = Kanal 11 verisi
adc[1] = kanal 12 verisi
adc[2] = kanal 10 verisi

DMA neden benim dizimi son elemandan başlayıp başa dönerek dolduruyor ? Bu bilgi nerede yazar?
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: Klein - 06 Eylül 2013, 15:14:38
DMA ayarla,
ADC çalıştır
çevirimi başlat. bu sıralamaya dikkat ettin mi?.
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: magnetron - 29 Ocak 2014, 16:54:43
hocam merhaba,
sizin örneğinizdeki ADC DMA çalıştırdım ( işlemcim STM32F103 )
2 kanal ADC ölçüyorum
potans bağladım ama sanki ADC girişleri floating bırakmışım gibi ikisinde de 2000 değeri etrafında oynayan bir değer alıyorum

değiştirdiğim yerler şunlar


main{} başında
    RCC_APB2PeriphClockCmd( RCC_APB2Periph_ADC1, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);

    adc_channel_config();
    init_adc1();
    ADC1_DMAConfig();
    ADC_DMACmd(ADC1,ENABLE);
    ADC_SoftwareStartConvCmd(ADC1,ENABLE); // çevirimi başlatıyoruz.
********
    ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_28Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 2, ADC_SampleTime_28Cycles5);
********
  DMA_InitStructure.DMA_BufferSize = 2; // Alacağımız verisayısı 8 ( 8 kanal adc okuyacağız)
********
  ADC_InitStructure.ADC_NbrOfChannel = 2; // sekiz kanal tarayacağız.
********
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5 ;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
********
main döngü içinde kendi değişkenime aktarıyorum
        uint16_t *RAMptr=&RAM[PARAMETERS+100*2];
        *RAMptr=ADC_ValArray[0];
********


GPIO clockları da açtım
sorun nerde olabilir ? teşekkür
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: Klein - 11 Ocak 2015, 05:47:36
Yaptığınız değişikliklerde bir sorun göremedim.  çalışmaması için bir sebep görünmüyor.
Ölçüm sonucunun  Tam skala / 2 gibi bir değer gösteriyor olmasından bir şeyler çıkarabilir miyim diye bakındım , çıkaramadım.
Donanım sorunu olabileceğinden kuşkuluyum.  Girişi VCC ve GND'ye çekip sonucu yazar mısınız?
Bir de AVDD ve AVSS bağlantılarında bir sorun olup olmadığını gözden geçirirseniz iyi olur.
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: ea - 11 Ocak 2015, 18:09:22
Merhaba. Bu ölçüm değerlerinin 2000 civarında olması benimde başıma geldi stm32f0 da adc girişlerine pot bağladım potu cevirsemde değişmedi fakat potun bi ucunu + ya orta ucu da pine bağlamıştım daha sonra boşta olan ucu gnd ye bağlayınca duzeldi.Bu ara da benimde bir sorum olacak. daha once dma ile adc cok detaylı kullanmadım ama  su anda 4 kanaldan veriyi dma ile okuyup dizye yazıyorum.cevrim sonunda degerleri görüyorum fakat ben diyelim ki kanallardan 10 ar tane örnek alsın ve dma sırasısı ile dizi adreslerini artırarak toplamda 40 adet adc ölcümünü dizide bulundursun istiyorum. bunu dma ile yapabilir miyim.. teşekkürler.
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: Klein - 13 Ocak 2015, 03:17:10
Yaparsınız fakat veriler sıralı olmaz.  Dizideki sıralama şu şekilde olur
Kanal 0 1. örnek
Kanal 1 1. örnek
Kanal 2 1. örnek
Kanal 3 1. örnek
..
..
..
..
Kanal 0 10. örnek
Kanal 1 10. örnek
Kanal 2 10. örnek
Kanal 3 10. örnek

Bu şekilde olması işinizi görüyorsa, dizi boyunu kanal sayısı*örnek sayısı olarak ayarlayıp , DMA'ya da bu boyu verirseniz olur.
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: magnetron - 13 Ocak 2015, 10:06:23
Klein hocam merhaba ,

dma ile ölçüm yaparken

benim verdiğim komutla başlamasını
ve diyelim 100 örnek aldıktan sonra durup interrupt vermesini nasıl sağlarım ?

teşekkür

Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: usahin - 22 Nisan 2015, 21:37:47
Hocam Selamlar,

stm32f103cbt6  mikrodenetleyicisini kullanıyorum. Yazılımı denediğimde tüm kanallarda birinci kanalın değerini görüyorum. Diğer kanallar boşta değil. Bazılarını GND'ye çektim bir kaçına da pot bağladım. Biraz kurcaladım ama bir şey çıkaramadım. Sorun ne olabilir ?
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: Klein - 25 Nisan 2015, 01:42:32
@magnetron.
ContiniousConversion yerine SingleConversion seç.
DMA  veriuzunluğunu 100 seç. 
çevirim  zaten senin komutunla başlıyor.

ADC_SoftwareStartConvCmd(ADC1,ENABLE);

@usahin
aşağıdaki bölümleri bir kontrol et. Taranacak kanal sayısını yanlış girmiş oılabilirsin. Veya kanalk konfigürasyonunda hata olabilir.

ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_28Cycles);
...
...
ADC_RegularChannelConfig(ADC1, ADC_Channel_n, 8, ADC_SampleTime_28Cycles);

ADC_InitStructure.ADC_NbrOfChannel = 8; // sekiz kanal tarayacağız.
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: usahin - 25 Nisan 2015, 03:24:19
Klein Hocam,

Geri dönüşünüz için teşekkürler, yazılımı register seviyesinde kendim yazmayı denemiştim çalışmayınca sizin örneği birebir kopyaladım derledim ancak bahsettiğim gibi bir sorun oluştu. Buffer boyutundan bağımsız tüm kanallarda +-2(4096 üzerinden) ilk kanalın değeri görünüyor o da gürültüdendir diye düşündüm.
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: usahin - 26 Nisan 2015, 19:51:55
Sorunu çözdüm, bir başka arkadaşın da başına gelirse izlediğim adımlar aşağıda :

Sistem Clock'unu 72MHz'e ayarladım.
ADC Prescaler 6
Çevrim zamanı 28.5 saykıl.
Çevrim başlangıcını T1 CC1 event tetiklemeli olarak yaptım.

Zamanlamayla ilgili bir sıkıntı vardı sanırım. Şu an sorunsuz bir şekilde 64 verilik buffer ile 8 kanal okuyorum.
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: magnetron - 17 Eylül 2016, 16:24:28
Klein hocam merhaba ,

DMA ile ölçüm yaparken

benim verdiğim komutla başlamasını anladım ( yukarda verdiğiniz cevap )
ama diyelim 100 örnek aldıktan sonra durup interrupt vermesini nasıl sağlarım ?

teşekkür
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: skara1214 - 17 Eylül 2016, 20:26:43
Alıntı yapılan: magnetron - 17 Eylül 2016, 16:24:28
Klein hocam merhaba ,

DMA ile ölçüm yaparken

benim verdiğim komutla başlamasını anladım ( yukarda verdiğiniz cevap )
ama diyelim 100 örnek aldıktan sonra durup interrupt vermesini nasıl sağlarım ?

teşekkür
sağlayamazsın.  her iş bitişte dma bitti interruptina girip 1 artırdıktan sonra  100 sefer işlem yapacaksın. Ama 100 seferde interrupta gir diye bir şey yok
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: Mucit23 - 17 Eylül 2016, 20:53:01
Bildiğim kadarıyla dma buffer boyutu kadar veriyi aktardiktan kesme oluşturur. Buna dma transfer complete kesmesi deniyor. Buffer boyutu 100 ise dma 100 kez tetiklendikden sonra kesme oluşturur.  Birde half transfer complete var oda buffer boyutunun yarısına ulaştığında kesme olusturuyordu yanılmıyorsam.

Eğer her bir transfer işleminde kesme oluşturulması isteniyorsa kesme vektörü dma yı tetikleyen donanıma bağlanır.
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: skara1214 - 17 Eylül 2016, 21:00:13
Alıntı yapılan: Mucit23 - 17 Eylül 2016, 20:53:01
Bildiğim kadarıyla dma buffer boyutu kadar veriyi aktardiktan kesme oluşturur. Buna dma transfer complete kesmesi deniyor. Buffer boyutu 100 ise dma 100 kez tetiklendikden sonra kesme oluşturur.  Birde half transfer complete var oda buffer boyutunun yarısına ulaştığında kesme olusturuyordu yanılmıyorsam.

Eğer her bir transfer işleminde kesme oluşturulması isteniyorsa kesme vektörü dma yı tetikleyen donanıma bağlanır.
hocam sizin dediğinizde 1 kanalı 100 kere taşıdıktan sonra interrupt oluştur demektir. arkadaş 5(temsili multikanal) kanalı 100 kere çevirdikten sonra  interrupta girmek istiyor.yani dma  işini 100 kere bitirip yeniden başlatması gerekiyor.Öyle bir opsiyonun olduğunu zannetmiyorum.
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: magnetron - 18 Eylül 2016, 02:58:10
hocam tek kanal

100 kere ölçüm yapılacak

yani  DMA_InitStructure.DMA_BufferSize = 100;

bitince ADC duracak interrupt verecek

interrupt nasıl kuracağım ? kod örneği verebilir misiniz ?
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: skara1214 - 18 Eylül 2016, 10:37:43
Alıntı yapılan: magnetron - 18 Eylül 2016, 02:58:10
hocam tek kanal

100 kere ölçüm yapılacak

yani  DMA_InitStructure.DMA_BufferSize = 100;

bitince ADC duracak interrupt verecek

interrupt nasıl kuracağım ? kod örneği verebilir misiniz ?
o dediğin olur. Cube mx kullaniyorsan dmayi kurduktan sonra interrupti zaten otomatik geliyor.
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: erdem54 - 18 Kasım 2016, 23:42:13
Merhaba
benim bir proje için farklı sensörlerden veri almam gerekeiyor verileri tek tek alırken herhangi bir problemle karşılaşmıyorum fakat iki farklı sensörden veri alırken ilk sefer doğru sonuç geliyor ardından sonuçlar hep hatalı dönüyor verinin birini SPI ile diğerini ise I2C ile alıyorum
bu problemi dma ile aşabilirmiyim
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: skara1214 - 19 Kasım 2016, 19:18:18
Hiç alakası yok dma işi kolaylaştırır caliayam birşey düzeltme ilkönce düzgün çalıştırın daha sonra dma ile ugrasirsiniz
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: muhittin_kaplan - 20 Kasım 2016, 18:52:39
@Klein Hocam Aşağıdaki kodu embitz ve stm32f103c8t6 kullanarak çalıştıramadım.
8 kanal yapmışsınız ama sadece 2 kanalına potans bağladım. (PA0-PA1) hep 4095 ölçüyorum. Acaba diyerek pa0 ı Gnd ye bağladım 4095 ölçmeye devam ettim.
(kanal sayısı vs değiştirmedim.) kodlar aşağıda.

/*
**
**                           Main.c
**
**
**********************************************************************/
/*
   Last committed:     $Revision: 00 $
   Last changed by:    $Author: $
   Last changed date:  $Date:  $
   ID:                 $Id:  $

**********************************************************************/
#include "stm32f10x_conf.h"

uint16_t ADC_ValArray[8]; // ADC değerlerimiz bu diziye atılacak



void ADC1_DMAConfig(void){
DMA_InitTypeDef DMA_InitStructure;

  DMA_Cmd(DMA1_Channel1,DISABLE);
  DMA_DeInit ( DMA1_Channel1);

  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)0x4001244C; // ADC->DR Adresi
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) ADC_ValArray; // hedef adresimiz
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; // ADC kaynak. Veri yönü ADC -> Hafıza
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // ADC adresi sabit kalacak
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // Her değer alındığına memory adresi 1 artırılacak
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;  // Kaynaktan alınacak veri 16 bit
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // Hedef büyüklüğü 16 bit
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // 8 veri alındıktan sonra başa dönülecek.
  DMA_InitStructure.DMA_Priority = DMA_Priority_High ; // Kanal Önceliği yüksek. ( bu bize kalmış)
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; // hafızadan hafızaya transfer kapalı.
  DMA_InitStructure.DMA_BufferSize = 8; // Alacağımız verisayısı 8 ( 8 kanal adc okuyacağız)

  DMA_Init(DMA1_Channel1, &DMA_InitStructure);
  DMA_Cmd(DMA1_Channel1,ENABLE);

}


//Hangi kanalların çevirime gireceğini ve hangi sırada çevirime gireceklerini ayarlayalım.
void adc_channel_config(void){
ADC_RegularChannelConfig(ADC1,ADC_Channel_0, 1, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_1, 2, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_2, 3, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_3, 4, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_4, 5, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_5, 6, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_6, 7, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_7, 8, ADC_SampleTime_239Cycles5);
}

void init_adc1(void)
{
ADC_InitTypeDef  ADC_InitStructure;

  RCC_ADCCLKConfig(RCC_PCLK2_Div2);
  ADC_DeInit(ADC1);

  ADC_InitStructure.ADC_ScanConvMode = ENABLE; // tarama modu açık
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; // sürekli çevirim yapacağız
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfChannel = 8; // sekiz kanal tarayacağız.
  ADC_Init(ADC1, &ADC_InitStructure);

  ADC_Cmd(ADC1, ENABLE);

  ADC_ResetCalibration(ADC1);
  while(ADC_GetResetCalibrationStatus(ADC1));

  ADC_StartCalibration(ADC1);
  while(ADC_GetCalibrationStatus(ADC1));
}

void init_gpio(void){
GPIO_InitTypeDef  GPIO_InitStructure;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1 | GPIO_Pin_2 |GPIO_Pin_3 | \
   GPIO_Pin_4 |GPIO_Pin_5 | GPIO_Pin_6 |GPIO_Pin_7 ;
GPIO_Init(GPIOA, &GPIO_InitStructure);

}

void init_rcc(void){
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1 | RCC_APB2Periph_AFIO,ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
}

void CycleDelay(int Value){
    while (Value){
        __NOP();//ASM kod
        --Value;
    }
}

int main(void)
{
    SystemInit();

    init_rcc();
    init_gpio();
    adc_channel_config();
    init_adc1();
    ADC1_DMAConfig();
    ADC_DMACmd(ADC1,ENABLE);
    ADC_SoftwareStartConvCmd(ADC1,ENABLE); // çevirimi başlatıyoruz.
    while(1)
    {
        __NOP();// Breakpoint koymak için eklenmiştir.
    }

}
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: muhittin_kaplan - 20 Kasım 2016, 19:15:51
Yapı Olarak Ne farkı var ? bu çalışıyor.

#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_usart.h"
#include "stm32f10x_adc.h"
#include "stm32f10x_dma.h"
#include "stm32f10x_tim.h"
#include "misc.h"

volatile char buffer[80] = {'\0'};

volatile short FLAG_ECHO = 0;

void TIM4_IRQHandler(void)
{
    if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
    {
        FLAG_ECHO = 1;
        TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
    }
}

void usart_init(void)
{
        /* Enable USART1 and GPIOA clock */
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);

        /* NVIC Configuration */
        NVIC_InitTypeDef NVIC_InitStructure;
        /* Enable the USARTx Interrupt */
        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);


        /* Configure the GPIOs */
        GPIO_InitTypeDef GPIO_InitStructure;

        /* Configure USART1 Tx (PA.09) as alternate function push-pull */
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);

        /* Configure USART1 Rx (PA.10) as input floating */
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOA, &GPIO_InitStructure);

        /* Configure the USART1 */
        USART_InitTypeDef USART_InitStructure;

      /* USART1 configuration ------------------------------------------------------*/
        /* USART1 configured as follow:
              - BaudRate = 115200 baud
              - Word Length = 8 Bits
              - One Stop Bit
              - No parity
              - Hardware flow control disabled (RTS and CTS signals)
              - Receive and transmit enabled
              - USART Clock disabled
              - USART CPOL: Clock is active low
              - USART CPHA: Data is captured on the middle
              - USART LastBit: The clock pulse of the last data bit is not output to
                               the SCLK pin
        */
        USART_InitStructure.USART_BaudRate = 115200;
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;
        USART_InitStructure.USART_StopBits = USART_StopBits_1;
        USART_InitStructure.USART_Parity = USART_Parity_No;
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
        USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

        USART_Init(USART1, &USART_InitStructure);

        /* Enable USART1 */
        USART_Cmd(USART1, ENABLE);

        /* Enable the USART1 Receive interrupt: this interrupt is generated when the
             USART1 receive data register is not empty */
        //USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
}

void USARTSend(const unsigned char *pucBuffer)
{
    while (*pucBuffer)
    {
        USART_SendData(USART1, *pucBuffer++);
        while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
        {
        }
    }
}

void SetSysClockTo72(void)
{
    ErrorStatus HSEStartUpStatus;
    /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration -----------------------------*/
    /* RCC system reset(for debug purpose) */
    RCC_DeInit();

    /* Enable HSE */
    RCC_HSEConfig( RCC_HSE_ON);

    /* Wait till HSE is ready */
    HSEStartUpStatus = RCC_WaitForHSEStartUp();

    if (HSEStartUpStatus == SUCCESS)
    {
        /* Enable Prefetch Buffer */
        //FLASH_PrefetchBufferCmd( FLASH_PrefetchBuffer_Enable);

        /* Flash 2 wait state */
        //FLASH_SetLatency( FLASH_Latency_2);

        /* HCLK = SYSCLK */
        RCC_HCLKConfig( RCC_SYSCLK_Div1);

        /* PCLK2 = HCLK */
        RCC_PCLK2Config( RCC_HCLK_Div1);

        /* PCLK1 = HCLK/2 */
        RCC_PCLK1Config( RCC_HCLK_Div2);

        /* PLLCLK = 8MHz * 9 = 72 MHz */
        RCC_PLLConfig(0x00010000, RCC_PLLMul_9);

        /* Enable PLL */
        RCC_PLLCmd( ENABLE);

        /* Wait till PLL is ready */
        while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
        {
        }

        /* Select PLL as system clock source */
        RCC_SYSCLKConfig( RCC_SYSCLKSource_PLLCLK);

        /* Wait till PLL is used as system clock source */
        while (RCC_GetSYSCLKSource() != 0x08)
        {
        }
    }
    else
    { /* If HSE fails to start-up, the application will have wrong clock configuration.
     User can add here some code to deal with this error */

        /* Go to infinite loop */
        while (1)
        {
        }
    }
}

//=================================================================================
volatile uint16_t ADCBuffer[] = {0xAAAA, 0xAAAA, 0xAAAA, 0xAAAA};

void ADC_DMA_init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    ADC_InitTypeDef ADC_InitStructure;
    DMA_InitTypeDef DMA_InitStructure;

    RCC_ADCCLKConfig(RCC_PCLK2_Div6);
    /* Enable ADC1 and GPIOA clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE );

    DMA_InitStructure.DMA_BufferSize = 4;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADCBuffer;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_Init(DMA1_Channel1, &DMA_InitStructure);
    DMA_Cmd(DMA1_Channel1 , ENABLE ) ;

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
    ADC_InitStructure.ADC_NbrOfChannel = 4;
    ADC_InitStructure.ADC_ScanConvMode = ENABLE;
    ADC_Init(ADC1, &ADC_InitStructure);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 1, ADC_SampleTime_7Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 2, ADC_SampleTime_7Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 3, ADC_SampleTime_7Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 4, ADC_SampleTime_7Cycles5);
    ADC_Cmd(ADC1 , ENABLE ) ;
    ADC_DMACmd(ADC1 , ENABLE ) ;
    ADC_ResetCalibration(ADC1);

    while(ADC_GetResetCalibrationStatus(ADC1));
    ADC_StartCalibration(ADC1);

    while(ADC_GetCalibrationStatus(ADC1));
    ADC_SoftwareStartConvCmd ( ADC1 , ENABLE ) ;
}
//=================================================================================

int main(void)
{
    SetSysClockTo72();

    const unsigned char mytext[] = " Hello World!\r\n";

    //USART
    usart_init();
    USARTSend(mytext);

    //ADC
    ADC_DMA_init();

    // TIMER4
    TIM_TimeBaseInitTypeDef TIMER_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

    TIM_TimeBaseStructInit(&TIMER_InitStructure);
    TIMER_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIMER_InitStructure.TIM_Prescaler = 7200;
    TIMER_InitStructure.TIM_Period = 5000;
    TIM_TimeBaseInit(TIM4, &TIMER_InitStructure);
    TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
    TIM_Cmd(TIM4, ENABLE);

    /* NVIC Configuration */
    /* Enable the TIM4_IRQn Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    while (1)
    {
        if (FLAG_ECHO == 1) {
            sprintf(buffer, "\r\n%d : %d : %d : %d\r\n", ADCBuffer[0], ADCBuffer[1], ADCBuffer[2], ADCBuffer[3]);
            USARTSend(buffer);
            FLAG_ECHO = 0;
        }
    }
}
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: halil82ist - 29 Kasım 2016, 12:14:06
Stm32 dmaları konusunda tecrübeli arkadaşlara bir sorum olacak . stm32f0 serisi kullanıyorum . Dmayı çalıştırdım herhangi bir sorun yok . Adc ölçümleri düzgün bir şekilde alabiliyorum . Sorun şurada başlıyor . Dma kesmesinde işlemcinin ne kadar süre kaldığını görmek istiyorum . bu sebeple bir çıkış pinini set edince işlemci reset atıyor . aynı pin ana programda düzgün çalışıyor . Dma kesmesi içinde herhangi bir çıkış pinini değiştirince aynı sorun bunun bir çözümü var mı neden olabilir ?
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: skara1214 - 29 Kasım 2016, 16:30:20
debug etmeden anlayamazsınız
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: halil82ist - 29 Kasım 2016, 17:34:41
debug'ta en son resete hangi komuttan sonra girdiğini görebiliyormuyuz ? veya nasıl bakacağız
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: skara1214 - 29 Kasım 2016, 21:14:10
debugu açın adım adım yürütün. nerede reset attığını göreceksiniz
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: crazy - 21 Temmuz 2017, 22:57:52
#include "stm32f10x.h"                  // Device header

uint16_t   ADC_ConvertedValue[8] = {0x00}; // adc degerlerini atacagımız dizi

static void  ADC1_GPIO_Config(void)
{
  RCC->APB2ENR |= 0x00000214;//PORTC ->PORTA  -> ADC1 Clock Enabled.
  GPIOC->CRH   &= 0x00000000;//
  GPIOA->CRL   &= ~0xCCCCCCCC; //PORTA 0-7 analog giris
  GPIOC->CRH   |= 0x00300000;//PC13 cikis 50Mhz
 


}

static void ADC1_Mode_Config(void)
{
  RCC->AHBENR  |= 0x00000001; //DMA1 Clock aktif
  DMA1_Channel1->CCR     = 0x00000000; //DMA1 Channel1 kapali
  DMA1_Channel1->CPAR   |= (uint32_t)0x4001244C;
  DMA1_Channel1->CMAR   |= (uint32_t) &ADC_ConvertedValue; //hedef adresimiz
  DMA1_Channel1->CNDTR   = 8; //Alacağımız verisayısı 8 ( 8 kanal adc okuyacağız)
  DMA1_Channel1->CCR    |= 0x000025A0; 
  DMA1_Channel1->CCR    |= 0x00000001; //DMA1 Channel1 acik
  ADC1->SMPR2 |= (7<<0)|(7<<3)|(7<<6)|(7<<9)|(7<<12)|(7<<15)|(7<<18)|(7<<21); //239.5 cycle
  ADC1->SQR1   |= 0x00700000; // // sekiz kanal tarayacağız.
  ADC1->SQR2 |= 0x000000E6; //6 VE7 KANAL
  ADC1->SQR3 |= 0x0A418820; //tarama, 0, 1, 2, 3, 4, 5,
  ADC1->CR1   = 0x00000100;                       // use independant mode, SCAN mode
  ADC1->CR2   = 0x000E0103;                       // use data align right,continuous conversion
                                                  // EXTSEL = SWSTART
                                              // enable ADC, DMA mode, no external Trigger
  ADC1->CR2    |=  1 <<  3;             // Initialize calibration registers
  while (ADC1->CR2 & (1 << 3));         // Wait for initialization to finish
  ADC1->CR2    |=  1 <<  2;             // Start calibration
  while (ADC1->CR2 & (1 << 2));         // Wait for calibration to finish

  ADC1->CR2  |= 0x00500000;          // start SW conversion

}



int main()
{

  ADC1_GPIO_Config();
  ADC1_Mode_Config();

while(1)
{
   if(ADC_ConvertedValue[0]<1500)
{
GPIOC->ODR |= (1<<13);

}

else

{
   GPIOC->ODR &= ~(1<<13);

}

}
}



(https://s22.postimg.cc/oi6majyr1/ADC_SQR3.png) (https://postimg.cc/image/oi6majyr1/)
Klein hocanın std_lib ADC + DMA (Çok kanal)örneğini  register seviyesinde çalıştırdım, ADC1->SQR2 |= 0x000000E6; //6 VE7 KANAL
  ADC1->SQR3 |= 0x0A418820;   //tarama, 0, 1, 2, 3, 4, 5,    hangi kanalların çevirime gireceğini ve hangi sırada çevirime gireceklerini register seviyesinde nasıl ayarlıyoruz, acaba mantığı nedir ?
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: pax - 12 Aralık 2017, 17:45:24
Bir noktayı tam anlayamadım : kanal çevrimi bittiği zaman DMA bu değeri alır deniyor. DMA Kanal çevriminin bittiğini nasıl anlıyor.
Başlık: Ynt: Örnek:STM32 ST_Lib ADC + DMA (Çok kanal)
Gönderen: bymrz - 27 Aralık 2019, 10:32:22
Alıntı yapılan: Klein - 06 Eylül 2013, 15:14:38DMA ayarla,
ADC çalıştır
çevirimi başlat. bu sıralamaya dikkat ettin mi?.



Hocam gözünün yağını yeyim senin :)
2 gündür kafayı yiyordum...

Hızlı olsun diye kodları STM32 Cube MX üzerinden ürettim. Yeni versiyonunda da salak gibi DMA init rutinini ADCInit rutininden sonrasına koyuyordu. Dediğiniz gibi yaptım düzeldi...

Koskoca ST bir de,  :P
Cube MX e güvenilemeyeceği bir kez daha ispatlandı...