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

stm32CubeMX+ADC+DMA的问题

[复制链接]
andrewsss 提问时间:2018-11-1 17:41 /
本帖最后由 andrewsss 于 2018-11-1 17:41 编辑

在使用stm32CubeMx时遇到一个问题,我在用DMA方式获取ADC数据时,设置DMA为Circular模式会被HAL_ADC_Start_DMA阻塞,不懂为什么会这样,后来换了F103芯片也一样,附上配置图:stm32L151C8T6的cube配置图:










360截图20181101171610170.jpg
360截图20181101170832965.jpg
360截图20181101170912812.jpg
收藏 评论18 发布时间:2018-11-1 17:41

举报

18个回答
byronsong 回答时间:2018-11-1 22:31:30
将ADC DMA中断的NVIC使能代码屏蔽即可解决。。。
/**
  * Enable DMA controller clock
  */
static void MX_DMA_Init(void)
{
  /* DMA controller clock enable */
  __HAL_RCC_DMA2_CLK_ENABLE();

  /* DMA interrupt init */
  /* DMA2_Stream0_IRQn interrupt configuration */
  //HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
  //HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);

}

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

andrewsss 回答时间:2018-11-2 19:13:31
Dandjinh 发表于 2018-11-2 17:13
只有1个数据用IT就好了。
DMA的Circle是会一直转换,转换了一半的数据会调用HAL_ADC_ConvHalfCpltCallbac ...

我试过了,缓冲区开大点也不行,程序进入了DMA的中断一直循环,没有进入ADC的中断里
void DMA1_Channel1_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Channel1_IRQn 0 */
        printf("DMA\n");
  /* USER CODE END DMA1_Channel1_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_adc1);
  /* USER CODE BEGIN DMA1_Channel1_IRQn 1 */

  /* USER CODE END DMA1_Channel1_IRQn 1 */
}

void ADC1_2_IRQHandler(void)
{
  /* USER CODE BEGIN ADC1_2_IRQn 0 */
        printf("ADC\n");
  /* USER CODE END ADC1_2_IRQn 0 */
  HAL_ADC_IRQHandler(&hadc1);
  /* USER CODE BEGIN ADC1_2_IRQn 1 */

  /* USER CODE END ADC1_2_IRQn 1 */
}

但是我把DMA的中断程序注释掉,程序还是会中断,我只有把DMA的NVIC的配置也注释掉才不会进入中断,这是为什么
zxk126 回答时间:2018-11-8 17:39:51
andrewsss 发表于 2018-11-3 14:38
今天又实验了几遍,发现使用circular模式时,如果main中阻塞在HAL_ADC_Start_DMA处(程序一直进入DMA1_Chan ...

用中断时你一定要注意中断运行时间和你的中断时间间隔,如果每次中断之间的时间间隔小于一次进入中断运行的时间,那肯定会一直进中断,因为中断还没出来呢,下一次中断就来了,所以会一直进中断,其他程序就执行不了了。
另外,你说的加入打印命令,打印是很耗时间的,你的AD转换周期如果设置太小的话,不够一次打印时间,那肯定会一直反复进中断。打印子程序没用过,不知道是什么方式实现的,如果是中断方式的话,那么他执行打印的时候肯定会等待打印完成,这个时候如果发送中断优先级低于ADC优先级的话,是不会执行发送中断的,也就永远发送不完,也退不出ADC中断。这只是一种猜测,仅供参考。
中断程序一定简单,运行时间短,进去就出来,千万不能加太耗时的等待等语句。

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

wyxy163@126.com 回答时间:2018-11-1 21:12:03
提示: 作者被禁止或删除 内容自动屏蔽
andrewsss 回答时间:2018-11-2 09:46:33
数码小叶 发表于 2018-11-1 21:12
是不是开启DMA中断了,HAL_ADC_Start_DMA的Length参数才是1,而你配置的循环模式,不阻塞才不正常 ...

我的DMA存储变量adcvalue不是数组,所以我设置的1,DMA中断好像使用了DMA就开启了,没法关闭,我的cubemx设置里面是灰色的,无法更改
andrewsss 回答时间:2018-11-2 09:49:36
songshiqun2010 发表于 2018-11-1 22:31
将ADC DMA中断的NVIC使能代码屏蔽即可解决。。。
/**
  * Enable DMA controller clock

非常感谢,我按你的方法试了,是可以的,但是我不明白我又没有写中断处理函数,它执行到哪里去了然后停住了。如果我要用Circular模式的话,应该怎么处理?
电子星辰 回答时间:2018-11-2 10:42:10
Circular模式就是开启一次,DMA会自动循环接收数据,再把函数放在主循环中就不行了,得把函数放在主循环之外

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

Dandjinh 回答时间:2018-11-2 11:48:28
本帖最后由 Dandjinh 于 2018-11-2 12:07 编辑

把ADC的总中断调到比ADC-DMA的中断优先级高试试。
我也是循环加中断,也没问题啊。
况且为啥长度是1啊。长度代表的是数据个数,也就是缓冲区大小。
你设置为1,我猜就是不断进入中断,导致看起来像堵塞一样。


评分

参与人数 1蝴蝶豆 +1 收起 理由
STMCU + 1

查看全部评分

andrewsss 回答时间:2018-11-2 16:30:36
电子星辰 发表于 2018-11-2 10:42
Circular模式就是开启一次,DMA会自动循环接收数据,再把函数放在主循环中就不行了,得把函数放在主循环之 ...

我的直接用circular模式就不行,必须把ADC DMA中断的NVIC使能代码屏蔽掉才行
andrewsss 回答时间:2018-11-2 16:33:00
Dandjinh 发表于 2018-11-2 11:48
把ADC的总中断调到比ADC-DMA的中断优先级高试试。
我也是循环加中断,也没问题啊。
况且为啥长度是1啊。长 ...

调了优先级也不行;我的缓冲区大小就是1,就是一个uint32_t 的变量,所以设的1;我的要把ADC DMA中断的NVIC使能代码屏蔽掉才行
Dandjinh 回答时间:2018-11-2 17:13:01
andrewsss 发表于 2018-11-2 16:33
调了优先级也不行;我的缓冲区大小就是1,就是一个uint32_t 的变量,所以设的1;我的要把ADC DMA中断的NV ...

只有1个数据用IT就好了。
DMA的Circle是会一直转换,转换了一半的数据会调用HAL_ADC_ConvHalfCpltCallback,转换完全部数据会调用HAL_ADC_ConvCpltCallback。然后一直循环。
你可以在HAL_ADC_IRQHandler开头加一句话看看是不是一直进入中断。或者把缓冲区开大点看看是不是没有问题了。
我用的就是CubeMX + ADC + DMA,缓冲区1000,一直没问题。


andrewsss 回答时间:2018-11-2 19:17:03
Dandjinh 发表于 2018-11-2 17:13
只有1个数据用IT就好了。
DMA的Circle是会一直转换,转换了一半的数据会调用HAL_ADC_ConvHalfCpltCallbac ...

对了,我用的cubemx是4.27.0,库是STM32Cube_FW_F1_V1.6.0,
wyxy163@126.com 回答时间:2018-11-2 20:43:13
提示: 作者被禁止或删除 内容自动屏蔽
wyxy163@126.com 回答时间:2018-11-2 20:45:05
提示: 作者被禁止或删除 内容自动屏蔽
12下一页

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版