设为首页收藏本站

Discuz! Board

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 10173|回复: 12
打印 上一主题 下一主题

STM32F373 SDADC+DMA工作不正常

[复制链接]

2

主题

7

帖子

25

积分

新手上路

Rank: 1

积分
25
跳转到指定楼层
楼主
iken 发表于 2013-12-6 11:07:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我遇到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);

}
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖
回复

使用道具 举报

2

主题

7

帖子

25

积分

新手上路

Rank: 1

积分
25
沙发
 楼主| iken 发表于 2013-12-6 11:07:34 | 只看该作者
如果增加错误中断DMA_IT_TE,发现能进入一次中断,这说明dma配置完、使能后就产生了错误中断:
  /* Enable DMA2 Channel3 Transfer half and Complete interrupt */
  DMA_ITConfig(DMA2_Channel3, DMA_IT_TC | DMA_IT_HT|DMA_IT_TE, ENABLE);
回复 支持 反对

使用道具 举报

243

主题

1706

帖子

6151

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
6151
板凳
admin 发表于 2013-12-6 11:10:23 | 只看该作者
我把我做项目的那个代码晚上上传给你,自己参考下,代码在家里,dma+sdadc
回复 支持 反对

使用道具 举报

243

主题

1706

帖子

6151

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
6151
地板
admin 发表于 2013-12-6 11:15:32 | 只看该作者
这个是基本配置:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复 支持 反对

使用道具 举报

2

主题

7

帖子

25

积分

新手上路

Rank: 1

积分
25
5#
 楼主| iken 发表于 2013-12-6 11:22:23 | 只看该作者
我看看,谢谢。
回复 支持 反对

使用道具 举报

2

主题

7

帖子

25

积分

新手上路

Rank: 1

积分
25
7#
 楼主| iken 发表于 2013-12-6 13:06:14 | 只看该作者
admin 发表于 2013-12-6 11:15
这个是基本配置:

参考了你的配置,还是不行。
回复 支持 反对

使用道具 举报

243

主题

1706

帖子

6151

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
6151
8#
admin 发表于 2013-12-6 13:20:36 | 只看该作者
你所有的中断优先级都设置成一样干什么?
回复 支持 反对

使用道具 举报

2

主题

7

帖子

25

积分

新手上路

Rank: 1

积分
25
9#
 楼主| iken 发表于 2013-12-6 15:46:49 | 只看该作者
DMA可以了。
之前主要是SDADC_CONFIG()中没配置好,资料没读透。
现在不用timer3触发,直接软件触发转换,DMA工作正常了。
谢谢管理员啊!
回复 支持 反对

使用道具 举报

4

主题

15

帖子

79

积分

注册会员

Rank: 2

积分
79
10#
Simple 发表于 2014-6-12 14:14:57 | 只看该作者
是哪里没配制好啊?
回复 支持 反对

使用道具 举报

4

主题

15

帖子

79

积分

注册会员

Rank: 2

积分
79
11#
Simple 发表于 2014-6-12 15:53:30 | 只看该作者
都哪个口可以用作SDADC
回复 支持 反对

使用道具 举报

Archiver|手机版|小黑屋|Comsenz Inc.   

GMT+8, 2024-4-19 11:58 , Processed in 0.386267 second(s), 29 queries .

Powered by Discuz! X3

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表