打印

STM32F373 16位SDADC配合DMA无**常工作

[复制链接]
9077|18
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
kinggwi|  楼主 | 2013-7-18 11:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本人最近在使用SDADC和DMA的过程中遇到点问题想请教大家,具体是这样的,16位AD单独使用可以正常工作,但是和DMA结合就无法使用,在调试状态下观察发现只要DMA初始化到DMA_Cmd(DMA2_Channel3, ENABLE);这句时,SDADC就立刻停止了采集转换,而且SDADC所有的数据寄存器在此刻都归零了,就更别说进DMA中断了。。。

void SDADC1_Config()
{
   SDADC_InitTypeDef SDADC_InitStructure;
   SDADC_AINStructTypeDef SDADC_AINStructure;
   GPIO_InitTypeDef GPIO_InitStructure;
          
         
   uint32_t SDADCTimeout = 0;
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_SDADC1, ENABLE);
   
   SDADC_DeInit(SDADC1);  
   /* PWR APB1 interface clock enable */
   RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
   
   /* Enable SDADC analog interface */
   PWR_SDADCAnalogCmd(PWR_SDADCAnalog_1, ENABLE);
   
   /* Set the SDADC divider: The SDADC should run @6MHz */
   /* If Sysclk is 72MHz, SDADC divider should be 12 */
   RCC_SDADCCLKConfig(RCC_SDADCCLK_SYSCLK_Div12);
   /* GPIO Peripheral clock enable */
   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOE, ENABLE);
   /* SDADC channel 3 pin7 configuration: PE7 */
   GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AN;
   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
   GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_7;
   GPIO_Init(GPIOE, &GPIO_InitStructure);
         
         
   /* Select External reference: The reference voltage selection is available
      only in SDADC1 and therefore to select the VREF for SDADC2/SDADC3, SDADC1
      clock must be already enabled */
   SDADC_VREFSelect(SDADC_VREF_Ext);
   /* Insert delay equal to ~5 ms */
//    Delay(2);

   SDADC_Cmd(SDADC1, ENABLE);
   SDADC_InitModeCmd(SDADC1, ENABLE);
   SDADCTimeout = 30;
   /* wait for INITRDY flag to be set */
   while((SDADC_GetFlagStatus(SDADC1, SDADC_FLAG_INITRDY) == RESET) && (--SDADCTimeout != 0));
//    if(SDADCTimeout == 0)
//    {
//      /* INITRDY flag can not set */
//      return 1;
//    }
   
   SDADC_AINStructure.SDADC_InputMode =SDADC_InputMode_SEOffset; //SDADC_InputMode_SEZeroReference;
   SDADC_AINStructure.SDADC_Gain =  SDADC_Gain_1_2;//GAIN is 0.5
   SDADC_AINStructure.SDADC_CommonMode = SDADC_CommonMode_VSSA;
   SDADC_AINStructure.SDADC_Offset = 0;
   SDADC_AINInit(SDADC1, SDADC_Conf_0, &SDADC_AINStructure);
  
   /* Channel3 configuration */
   SDADC_InitStructure.SDADC_Channel = SDADC_Channel_3;
   SDADC_InitStructure.SDADC_ContinuousConvMode = ENABLE;
   SDADC_InitStructure.SDADC_FastConversionMode = DISABLE;
   SDADC_Init(SDADC1, &SDADC_InitStructure);
         
       
         SDADC_ChannelConfig(SDADC1, SDADC_Channel_3, SDADC_Conf_0);
         SDADC_DMAConfig(SDADC1,SDADC_DMATransfer_Regular, ENABLE);
   SDADC_InitModeCmd(SDADC1, DISABLE);
          
   /* configure calibration to be performed on conf0 */
   SDADC_CalibrationSequenceConfig(SDADC1, SDADC_CalibrationSequence_1);
   
   SDADC_StartCalibration(SDADC1);
   /* Set calibration timeout: 5.12 ms at 6 MHz in a single calibration sequence */
   SDADCTimeout = 4*30720 ;
  
   while((SDADC_GetFlagStatus(SDADC1, SDADC_FLAG_EOCAL) == RESET) && (--SDADCTimeout != 0));
//    if(SDADCTimeout == 0)
//    {
//      /* EOCAL flag can not set */
//      return 2;
//    }
//    /* SDADC successfully configured */
//    return 0;


        SDADC_SoftwareStartConv(SDADC1);   
          
}       
         

void DMA2_Configuration(void)
{
        DMA_InitTypeDef   DMA_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
  /* Enable DMA2 clock */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
  
  /* Config the DMA2 channel 3 */
  DMA_DeInit(DMA2_Channel3);
  
  DMA_InitStructure.DMA_PeripheralBaseAddr  = (uint32_t)&SDADC1->RDATA12R;
  DMA_InitStructure.DMA_MemoryBaseAddr      = (uint32_t)Volt_Buffer;
  DMA_InitStructure.DMA_DIR                 = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize          = N;
  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_Low;
  DMA_InitStructure.DMA_M2M                 = DMA_M2M_Disable;
  DMA_Init(DMA2_Channel3, &DMA_InitStructure);
       
       
        NVIC_InitStructure.NVIC_IRQChannel = DMA2_Channel3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
          
  /* Enable DMA2 Channel3 Transfer half and Complete interrupt */
  DMA_ITConfig(DMA2_Channel3, DMA_IT_TC , ENABLE);
  
           /* Enable DMA2 Channel3 */
  DMA_Cmd(DMA2_Channel3, ENABLE);


}
       

沙发
uet_cache| | 2013-7-18 12:06 | 只看该作者
DMA好像只能与12位的ADC配合使用,SDADC好像不行,你查下编程手册。

使用特权

评论回复
板凳
kinggwi|  楼主 | 2013-7-18 13:06 | 只看该作者
可F373的官方例程里就有16位AD使用DMA啊

使用特权

评论回复
地板
iken| | 2013-12-5 16:46 | 只看该作者
本帖最后由 iken 于 2013-12-5 16:50 编辑

我也遇到SDADC+DMA的问题,没有产生DMA中断,各使能条件都满足,不确定其它配置是否有问题。


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

/**
  * @brief  Main program.
  * @param  None
  * @retval None
  */
int main(void)
{

  RCC_ClocksTypeDef RCC_Clocks;
  __IO float InputVoltageMv = 0;
    uint32_t ChannelIndex;

  /* SysTick end of count event each 1ms */
  RCC_GetClocksFreq(&RCC_Clocks);
  SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000);
        UART_Init();

  /* Configure DMA2 to transfer data from SDADC data register to embedded SRAM */
  DMA2_Config();        
  /* POT_SDADC channel5P (in Single Ended Zero Reference mode) configuration using
     injected conversion with continuous mode enabled */
  SDADC1_Config();


  /* Configure TIM3 as trigger for SDADC conversion */
  TIM13_Config();               
        TIM_Cmd(TIM13, ENABLE);



    /* Infinite loop */
    while (1)
    {

if(aa==1)
{
        aa=0;
      InputVoltageMv = (((InjectedConvData + 32768) * SDADC_VREF) / (SDADC_GAIN * SDADC_RESOL));
      /* write result to LCD */
      sprintf(LCDstr, " RV3 = %2.2f mV  ", InputVoltageMv);
                printf("\n\r Pot (RV3)   = %2.2f mV \n\r",InputVoltageMv);
                        
      LCD_DisplayStringLine(LCD_LINE_5, (uint8_t*)LCDstr);

        DMA_ClearFlag(DMA2_FLAG_GL3);
            }               



    }

}

static void DMA2_Config(void)
{
  DMA_InitTypeDef   DMA_InitStructure;

  /* Enable DMA2 clock */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
  
  /* Config the DMA2 channel 3 */
  DMA_DeInit(DMA2_Channel3);
  
  DMA_InitStructure.DMA_PeripheralBaseAddr  = SDADC1_DR_Address;
  DMA_InitStructure.DMA_MemoryBaseAddr      = (uint32_t)InjectedConvData;
  DMA_InitStructure.DMA_DIR                 = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize          = 2;
  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_M2M                 = DMA_M2M_Disable;
  DMA_Init(DMA2_Channel3, &DMA_InitStructure);
  
  /* Enable DMA2 Channel3 Transfer half and Complete interrupt */
  DMA_ITConfig(DMA2_Channel3, DMA_IT_TC | DMA_IT_HT, ENABLE);
  
  /* Enable DMA2 Channel3 */
  DMA_Cmd(DMA2_Channel3, ENABLE);
}
/**
  * @brief  Configure POT_SDADC channel 5P in Single Ended Zero Reference mode using
  *         injected conversion with continuous mode enabled.
  * @param  None
  * @retval 0: SDADC Configured successfully
  *         1: INITRDY flag is not set, check the SDVDDA and SDVREF
  *         2: EOCAL flag is not set
  */
static uint32_t SDADC1_Config(void)
{
  SDADC_AINStructTypeDef SDADC_AINStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
  uint32_t SDADCTimeout = 0;

  /* POT_SDADC APB2 interface clock enable */
  RCC_APB2PeriphClockCmd(POT_SDADC_CLK, ENABLE);
  
  /* PWR APB1 interface clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
  /* Enable POT_SDADC analog interface */
  PWR_SDADCAnalogCmd(POT_SDADC_PWR, ENABLE);

  /* Set the SDADC divider: The SDADC should run @6MHz */
  /* If Sysclk is 72MHz, SDADC divider should be 12 */
  RCC_SDADCCLKConfig(RCC_SDADCCLK_SYSCLK_Div48);

  /* POT_GPIO_CLK Peripheral clock enable */
  RCC_AHBPeriphClockCmd(POT_GPIO_CLK, ENABLE);

  /* POT_SDADC channel 5P (PB1) */
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_InitStructure.GPIO_Pin = POT_GPIO_PIN;
  GPIO_Init(POT_GPIO_PORT, &GPIO_InitStructure);

  /* Select External reference: The reference voltage selection is available
     only in SDADC1 and therefore to select the VREF for SDADC2/SDADC3, SDADC1
     clock must be already enabled */
  SDADC_VREFSelect(POT_SDADC_VREF);

  /* Insert delay equal to ~5 ms */
  Delay(5);
  
  /* Enable POT_SDADC */
  SDADC_Cmd(POT_SDADC, ENABLE);

  /* Enter initialization mode */
  SDADC_InitModeCmd(POT_SDADC, ENABLE);
  SDADCTimeout = SDADC_INIT_TIMEOUT;
  /* wait for INITRDY flag to be set */
  while((SDADC_GetFlagStatus(POT_SDADC, SDADC_FLAG_INITRDY) == RESET) && (--SDADCTimeout != 0));

  if(SDADCTimeout == 0)
  {
    /* INITRDY flag can not set */
    return 1;
  }

  /* Analog Input configuration conf0: use single ended zero reference */
  SDADC_AINStructure.SDADC_InputMode = SDADC_InputMode_SEZeroReference;
  SDADC_AINStructure.SDADC_Gain = POT_SDADC_GAIN;
  SDADC_AINStructure.SDADC_CommonMode = SDADC_CommonMode_VSSA;
  SDADC_AINStructure.SDADC_Offset = 0;
  SDADC_AINInit(POT_SDADC, SDADC_Conf_0, &SDADC_AINStructure);

  /* Enable DMA transfer for injected conversions */
  SDADC_DMAConfig(POT_SDADC, SDADC_DMATransfer_Injected,ENABLE);

  /* select POT_SDADC channel 5 to use conf0 */
  SDADC_ChannelConfig(POT_SDADC, POT_SDADC_CHANNEL, SDADC_Conf_0);
//SDADC_ChannelSelect(POT_SDADC, POT_SDADC_CHANNEL);
//SDADC_ContinuousModeCmd(POT_SDADC, ENABLE);
  /* select channel 5 */
  SDADC_InjectedChannelSelect(POT_SDADC, POT_SDADC_CHANNEL);
  /* Enable continuous mode */
//  SDADC_InjectedContinuousModeCmd(POT_SDADC, ENABLE);

  /* Select an external trigger */
  SDADC_ExternalTrigInjectedConvConfig(POT_SDADC, SDADC_ExternalTrigInjecConv_T13_CC1);
  /* Select rising edge */
  SDADC_ExternalTrigInjectedConvEdgeConfig(POT_SDADC, SDADC_ExternalTrigInjecConvEdge_Rising);
  

  /* Exit initialization mode */
  SDADC_InitModeCmd(POT_SDADC, DISABLE);
  /* configure calibration to be performed on conf0 */
  SDADC_CalibrationSequenceConfig(POT_SDADC, SDADC_CalibrationSequence_1);
  /* start POT_SDADC Calibration */
  SDADC_StartCalibration(POT_SDADC);
  /* Set calibration timeout: 5.12 ms at 6 MHz in a single calibration sequence */
  SDADCTimeout = SDADC_CAL_TIMEOUT;
  /* wait for POT_SDADC Calibration process to end */
  while((SDADC_GetFlagStatus(POT_SDADC, SDADC_FLAG_EOCAL) == RESET) && (--SDADCTimeout != 0));
  
  if(SDADCTimeout == 0)
  {
    /* EOCAL flag can not set */
    return 2;
  }

  /* Enable end of injected conversion interrupt */
//  SDADC_ITConfig(POT_SDADC, SDADC_IT_JEOC, ENABLE);
  /* Start a software start conversion */
//  SDADC_SoftwareStartInjectedConv(POT_SDADC);
//  SDADC_SoftwareStartConv(POT_SDADC);

  NVIC_InitStructure.NVIC_IRQChannel = DMA2_Channel3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);


  return 0;
}

/**
  * @brief  Configure timer TIM3: It is used as trigger for SDADC conversion
  * @param  None
  * @retval None
  */
static void TIM13_Config(void)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  TIM_OCInitTypeDef        TIM_OCInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;

  /* Enable the TIM3 Interrupt for capture compare event */
  NVIC_InitStructure.NVIC_IRQChannel = TIM13_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
        
  /* Enable TIM13 clock */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM13, ENABLE);
  
  /* TIM3 Configuration */
  TIM_DeInit(TIM13);

  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
  /* Time base configuration */
  TIM_TimeBaseStructure.TIM_Period = 900000;
  TIM_TimeBaseStructure.TIM_Prescaler = 0;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIM13, &TIM_TimeBaseStructure);
  
  /* PWM Mode configuration: Channel1 */
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = 4500 ;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  TIM_OC1Init(TIM13, &TIM_OCInitStructure);

}

中断程序:
void DMA2_Channel3_IRQHandler(void)
{
printf("\n\r Pot (RV3)   = gsdfasfasdf mV 11\n\r");
        aa=1;
  /* Clear DMA2 flag */
  DMA_ClearFlag(DMA2_FLAG_GL3);

}
  

使用特权

评论回复
5
iken| | 2013-12-6 15:49 | 只看该作者
已经验证通过了:SDADC+DMA可以正常工作。

使用特权

评论回复
6
iken| | 2013-12-6 16:48 | 只看该作者
to:kinggwi,
你的SDADC1_Config()相关配置不全,请参考我代码,见附件。

main_ok.rar

4.19 KB

使用特权

评论回复
7
kinggwi|  楼主 | 2013-12-17 13:59 | 只看该作者
灰常感谢!

使用特权

评论回复
8
ZRJ8951| | 2013-12-18 09:16 | 只看该作者
收藏!!!!

使用特权

评论回复
9
fengshang1122| | 2014-1-10 19:52 | 只看该作者
iken 发表于 2013-12-6 15:49
已经验证通过了:SDADC+DMA可以正常工作。

能说说怎么改动的吗

使用特权

评论回复
10
stzm| | 2014-7-23 16:50 | 只看该作者
非常感谢,正在学习STM32

使用特权

评论回复
11
mthgh| | 2015-5-22 11:31 | 只看该作者
mark一下

使用特权

评论回复
12
gurong60| | 2016-9-22 16:22 | 只看该作者
mark

使用特权

评论回复
13
491844473| | 2016-9-28 16:58 | 只看该作者
iken 发表于 2013-12-6 16:48
to:kinggwi,
你的SDADC1_Config()相关配置不全,请参考我代码,见附件。

附件解压缩密码是多少?能告诉我吗?

使用特权

评论回复
14
诸葛豆包| | 2016-10-10 14:50 | 只看该作者
iken 发表于 2013-12-6 16:48
to:kinggwi,
你的SDADC1_Config()相关配置不全,请参考我代码,见附件。

三克油,

使用特权

评论回复
15
tutuxx000| | 2016-10-12 11:33 | 只看该作者
iken 发表于 2013-12-6 16:48
to:kinggwi,
你的SDADC1_Config()相关配置不全,请参考我代码,见附件。

多谢分享!
人民会记得你的!

使用特权

评论回复
16
tiger8098| | 2017-6-2 11:36 | 只看该作者
正在学习,多谢

使用特权

评论回复
17
~LHC~| | 2019-4-26 16:59 | 只看该作者
居然在这里找到SDADC,学习了,谢谢分享

使用特权

评论回复
18
仰望星期五| | 2020-11-16 17:35 | 只看该作者
怎么设置多通道采集,我在这里遇到问题了。

使用特权

评论回复
19
仰望星期五| | 2020-11-16 18:09 | 只看该作者
三组SDADC,配合DMA采集,每一组用一个通道,三个通道可以正常采集,再多加通道就会出现问题,求助。。。。。。。。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

3

帖子

1

粉丝