welcom ! Handel home

2014年7月3日 星期四

st32 ADC for DMA Direct memory access mode control funtion note


/* ALIGN: Data alignement. */
#define ADC_CR2_ALIGN_RIGHT             (0 << 11)
#define ADC_CR2_ALIGN_LEFT              (1 << 11)
#define ADC_CR2_ALIGN                   (1 << 11)

 /* EOCS: End of conversion selection. */
#define ADC_CR2_EOCS                    (1 << 10)

 /* DDS: DMA disable selection */
#define ADC_CR2_DDS                     (1 << 9)

 /* DMA: Direct memory access mode. (ADC1 and ADC3 only!) */
#define ADC_CR2_DMA                     (1 << 8)

 /* Note: Bits [7:2] are reserved and must be kept at reset value. */

 /* CONT: Continous conversion. */
#define ADC_CR2_CONT                    (1 << 1)

 /* ADON: A/D converter On/Off. */
 /* Note: If any other bit in this register apart from ADON is changed at the
  * same time, then conversion is not triggered. This is to prevent triggering
  * an erroneous conversion.
  * Conclusion: Must be separately written.
  */
#define ADC_CR2_ADON                    (1 << 0)

void ADC_DMARequestAfterLastTransferCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
{
  /* Check the parameters */
  assert_param(IS_ADC_ALL_PERIPH(ADCx));
  assert_param(IS_FUNCTIONAL_STATE(NewState));

  if (NewState != DISABLE)
  {
    /* Enable the selected ADC DMA request after last transfer */
    ADCx->CR2  |= ADC_CR2_DDS;
  }
  else
  {
    /* Disable the selected ADC DMA request after last transfer */
    ADCx->CR2  &= (uint32_t)~ADC_CR2_DDS;
  }
}

/*
the DMA init and  ADC init by DMA read to data_buffer 16 word
*/
======================================================

//ADC pam
uint16_t ADCResult;

//DMA pam 
#define ADC1_DR_address   ((u32)0x4001244C) //AD轉換結果存放位址定義
#define SampleDepth = 64;
u32 Data_Buffer[SampleDepth];


//=======================
//DMA Channel 1 init  
//ADC1 DMA to Data_Buffer 64 Word 32bit 
//=======================

void DMA_ADC_Transfer_Reset(void)
{
    //開始DMA傳輸
    DMA1_Channel1->CCR &= ~(1<<0 font="" hannel="">
    DMA1->IFCR |= 0x0000000F;      //清除CHANNEL1的4個標誌
    DMA1_Channel1->CNDTR = (u16)SampleDepth;//重新設置要設置的DMA傳輸資料量
    DMA1_Channel1->CCR |= (1<<0 channel1="" font="" nbsp="">
    while(!(DMA1->ISR & DMA1_FLAG_TC1));
    DMA1_Channel1->CCR &= ~(1<<0 font="" hannel="" nbsp="">
}

void DMA_ADC_Transfer_Init(void)
{   
    //DMA_Channel_TypeDef     DMA_Channel1;
    DMA_InitTypeDef         DMA_InitStructure;
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
    
    DMA_DeInit(DMA1_Channel1);
    DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_address;  //ADC資料寄存器位址
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&Data_Buffer[0];//目標緩衝區位址
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;          //外設是源
    DMA_InitStructure.DMA_BufferSize = 0;                       //設置DMA讀取長度為
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外設地址不遞增
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;         //目標緩衝區位址遞增
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;//外設資料寬度
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;         //目標緩衝區資料寬度
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;               //DMA模式:Circular迴圈模式/Normal普通模式
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;     //優先順序
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                //記憶體到記憶體模式不使能
    DMA_Init(DMA1_Channel1, &DMA_InitStructure);
    //DMA_Cmd(DMA1_Channel1, ENABLE);
}


//=======================
//ADC1 init  PC0  
//in main ...
//while(1)
//{
//  uint16_t ADCResult = 0x1234;
//   
//  ADC_SoftwareStartConv(ADC1);
//  while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
//  ADCResult = ADC_GetConversionValue(ADC1);
//}

//=======================
void  Adc_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;  

  RCC_AHB1PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);// enable GPIO_A Clock 
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); // enable ADC1 clock 
  
  
  //GPIO_StructInit(&GPIO_InitStructure);
   
  //for ADC1 on PC0 using IN10
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; // define the Pin to analog mode
  //GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;// 
  GPIO_Init(GPIOC, &GPIO_InitStructure);
  
   //先初始化IO口
 //RCC->APB2ENR|=1<<2 font="" nbsp="">
 //GPIOC->CRL&=0XFFFF0000;//PA0 1 2 3 anolog輸入 
    
//通道10/11設置
    RCC->APB2ENR|=1<<9 font="" nbsp="">
    RCC->APB2RSTR|=1<<9 font="" nbsp="">
    RCC->APB2RSTR&=~(1<<9 font="">
    RCC->CFGR&=~(3<<14 font="" nbsp="">
    
//SYSCLK/DIV2=12M ADC時鐘設置為12M,ADC最大時鐘不能超過14M!
//否則將導致ADC準確度下降!
    RCC->CFGR|=2<<14 font="">

    ADC1->CR1&=0XF0FFFF;   //工作模式清零 DUALMOD[19:16] 0000 
    ADC1->CR1|=0<<16 font="" nbsp="">
    
    ADC1->CR1&=~(1<<8 cr1="" font="" nbsp="">
    ADC1->CR2&=~(1<<1 cr2="" font="" nbsp="">
    
    ADC1->CR2&=~(7<<17 111="" font="" nbsp="">
    ADC1->CR2|=7<<17 font="" nbsp="">
    
    ADC1->CR2|=1<<20 font="" nbsp="">
    
    ADC1->CR2&=~(1<<11 align="" font="" nbsp="">
    
    ADC1->SQR1&=~(0XF<<20 font="">
    ADC1->SQR1&=0<<20 font="" nbsp="">
    
//設置通道0~3的採樣時間
    ADC1->SMPR2&=0XFFFFF000;//通道0,1,2,3採樣時間清空
    ADC1->SMPR2|=7<<9 font="" nbsp="">
    ADC1->SMPR2|=7<<6 font="" nbsp="">
    ADC1->SMPR2|=7<<3 font="" nbsp="">
    ADC1->SMPR2|=7<<0 font="" nbsp="">
    
/* ADC1定期通道0配置 *************************************/   
 ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_239Cycles5);

/* 啟用DMA請求後,最後轉移(單ADC模式)*/
// ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);

/* 啟用ADC3 的 DMA */
    ADC_DMACmd(ADC1, ENABLE);

    ADC1->CR2|=1<<0 1="" cr2="" font="" nbsp="">

// ADC_DMACmd(ADC1, ENABLE);
    
    ADC1->CR2|=1<<3 1="" cr2="" font="" nbsp="">
    while(ADC1->CR2&1<<3 0="" cr2="" font="" nbsp="" when="">
    //該位元由軟體設置並由硬體清除。在校準寄存器被初始化後該位將被清除。
    
    ADC1->CR2|=1<<2 1="" font="" nbsp="">
    while(ADC1->CR2&1<<2 0="" cr2="" font="" nbsp="" when="">
//該位元由軟體設置以開始校準,並在校準結束時由硬體清除
}

沒有留言: