你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F030 ADC1 DMA1采集 开启NVIC后目标数据为空,ADC1->DR有数据

[复制链接]
死鹹水魚 提问时间:2017-5-25 15:45 /
本帖最后由 死鹹水魚 于 2017-6-1 09:25 编辑

最近在用STMF030的片子在开发过程中遇到一个奇葩的问题,
打算实现:
       ADC1的轮流采集多个通道,数据通过DMA1_CH1搬运到一片内存区,完成一圈后触发DMA传输完成中断,对采集数据进行处理。

前面的功能已经实现,但是在加入了NVIC中断配置后,发现ADC采集数据为0
       调试下发现DMA写入目标地址的数据组全部为空,而ADC1->DR里面的数据是有变化的,
       并且不为0。DMA内的CPAR1和CMAR1所对应的内存地址没错。NVIC中断也能进入,标志位也正常。
请问下这是什么回事?

以下是ADC、DMA、以及NVIC部分的配置函数。

  1. void ADC_Config(void)
  2. {
  3.         /* ADC Configuration Struct */
  4.         ADC_InitTypeDef ADC_InitStruct;
  5.         GPIO_InitTypeDef GPIO_InitStruct;
  6.         DMA_InitTypeDef DMA_InitStruct;
  7.         NVIC_InitTypeDef NVIC_InitStruct;
  8.         
  9.         /* ADC1 Periph clock Enable  */
  10.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
  11.         
  12.         /* GPIOA Periph clock Enable */
  13.         RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
  14.         
  15.         /* DMA1 Clock enable */
  16.         RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE);
  17.         
  18.         /* ADC RCC CLK */
  19.         RCC_ADCCLKConfig(RCC_ADCCLK_HSI14);        /*ADC 14Mhz Clock*/
  20.         
  21.         /* Configuration PA0:6 as AIN */
  22.         GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2/* PA0:TEM2, PA1:TEM1, PA2:C-PV */\
  23.                                                                                                                 |GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5/* PA3:C-BAT, PA4:V-BOOST, PA5: V-BAT*/\
  24.                                                                                                                 |GPIO_Pin_6/* PA6:V-PV */;
  25.         GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN;
  26.         GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
  27.         
  28.         GPIO_Init(GPIOA, &GPIO_InitStruct);
  29.         
  30.         /* Enable DMA channel1 IRQ Channel */
  31.         NVIC_InitStruct.NVIC_IRQChannel = DMA1_Channel1_IRQn;
  32.         NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
  33.         NVIC_InitStruct.NVIC_IRQChannelPriority = 1;
  34.         
  35.         //NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
  36.         //NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
  37.         NVIC_Init(&NVIC_InitStruct);
  38.         
  39.         /* Initialize ADC Struct */
  40.         ADC_StructInit(&ADC_InitStruct);
  41.         
  42.         /* Configuration ADC */
  43.         ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b;        /* ADC 12bit */
  44.         ADC_InitStruct.ADC_ContinuousConvMode = ENABLE;/* Continuous Convert Mode */
  45.         //ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;
  46.         ADC_InitStruct.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConv_T1_TRGO;/*ADC_ExternalTrigConvEdge_None;*/
  47.         ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConvEdge_Rising;
  48.         ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;
  49.         ADC_InitStruct.ADC_ScanDirection = ADC_ScanDirection_Upward;
  50.         
  51.         ADC_Init(ADC1, &ADC_InitStruct);
  52.         
  53.         /* Convert the ADC1 Channel0 and channe6 with 1.5 Cycles as sampling time */
  54.         ADC_ChannelConfig(ADC1, ADC_Channel_0, ADC_SampleTime_1_5Cycles);
  55.         ADC_ChannelConfig(ADC1, ADC_Channel_1, ADC_SampleTime_1_5Cycles);
  56.         ADC_ChannelConfig(ADC1, ADC_Channel_2, ADC_SampleTime_1_5Cycles);
  57.         ADC_ChannelConfig(ADC1, ADC_Channel_3, ADC_SampleTime_1_5Cycles);
  58.         ADC_ChannelConfig(ADC1, ADC_Channel_4, ADC_SampleTime_1_5Cycles);
  59.         ADC_ChannelConfig(ADC1, ADC_Channel_5, ADC_SampleTime_1_5Cycles);
  60.         ADC_ChannelConfig(ADC1, ADC_Channel_6, ADC_SampleTime_1_5Cycles);
  61.         
  62.         /* Convert the ADC1 inner temp sensor with 1.5 Cycles as Sampling time*/
  63.         /* ADCChannel 16 */
  64.         ADC_ChannelConfig(ADC1, ADC_Channel_TempSensor, ADC_SampleTime_1_5Cycles);
  65.                
  66.         /* Convert the ADC1 Vref*//* ADC_Channel 17 */
  67.         ADC_ChannelConfig(ADC1, ADC_Channel_Vrefint, ADC_SampleTime_1_5Cycles);
  68.         
  69.         /* ADC Calibration *//* Get ADC Calibration Data*/
  70.         ADC_Cal_Data = ADC_GetCalibrationFactor(ADC1);
  71.                
  72.   /* ADC DMA request in circular mode */
  73.   ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular);
  74.         

  75.         /* Enable ADC_DMA */
  76.   ADC_DMACmd(ADC1, ENABLE);  
  77.         
  78.   /* Enable the ADC peripheral */
  79.   ADC_Cmd(ADC1, ENABLE);   
  80.         ADC_TempSensorCmd(ENABLE);        
  81.   ADC_VrefintCmd(ENABLE);
  82.         
  83.   /* Wait the ADRDY flag */
  84.   while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADRDY));
  85.         
  86.         /* ADC Auto Power off */
  87.         ADC_AutoPowerOffCmd(ADC1, ENABLE);
  88.          
  89.         /* DMA1 Configuration */
  90.         DMA_DeInit(ADC_DMA_CH);
  91.         
  92.         DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&(ADC1->DR);        /* DMA Data Source Addr */
  93.         //DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)ConvertDatas;                        /* DMA Data Distance Addr */
  94.         DMA_InitStruct.DMA_MemoryBaseAddr =  (uint32_t)&g_ADCCollectorStruct;
  95.         DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;                                                                        /* DMA Data Transform Dir */
  96.         DMA_InitStruct.DMA_BufferSize = 9;                                                                                                                        /* DMA Data Busser Size */
  97.         DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
  98.   DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;        /* Data Length Half Word 16bit */
  99.   DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  100.   DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;                                                                                /* DMA Mode : Circular Mode */
  101.         //DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;
  102.   DMA_InitStruct.DMA_Priority = DMA_Priority_High;
  103.   DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;

  104. /* DMA Init Configuration */
  105.         DMA_Init(ADC_DMA_CH, &DMA_InitStruct);
  106.         
  107.         DMA_ITConfig(ADC_DMA_CH, DMA_IT_TC, ENABLE);
  108.                
  109.         /* DMA1 Channel1 enable */
  110.   DMA_Cmd(ADC_DMA_CH, ENABLE);
  111.         /* ADC1 regular Software Start Conv */
  112.   ADC_StartOfConversion(ADC1);
  113. }
复制代码
中断部分函数
  1. extern void ConvertAVGFitter(void);
  2. void         DMA1_Channel1_IRQHandler(void)
  3. {
  4.         if(DMA_GetITStatus(DMA1_IT_TE1))
  5.         {
  6.                 while(1);
  7.         }
  8.         if(DMA_GetITStatus(DMA1_IT_TC1))
  9.   {
  10.                 DMA_ClearFlag(DMA1_FLAG_TC1);
  11.                 DMA_ClearITPendingBit(DMA1_IT_TC1);
  12.                 ConvertAVGFitter();
  13. }
  14. }
复制代码


另,ADC1是利用TIM1的TRGO触发的,请问这有关系吗?
收藏 评论2 发布时间:2017-5-25 15:45

举报

2个回答
死鹹水魚 回答时间:2017-6-1 09:28:40
已解决,原因为堆栈区溢出,经多次试验,整个ADC初始函数中只要加入了NVIC的InitTypedef结构体后,无论 是否配置NVIC都会出现上述现象。把NVIC部分独立成一个函数在主函数调用即可。 话说7天零回复也是厉害。。
感觉030这种低端型的片子看来还是少用库写为妙啊。。
0星空斗罗0 回答时间:2019-3-26 16:06:58
看到老哥的说明,我注册也得给你评论下,非常感谢!!!!我也是同样的问题,谢谢你!!!
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版