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

主循环里不断开启关闭ADC的DMA传输功能,上电有几率死机。

[复制链接]
any012 提问时间:2019-1-30 09:51 /
10ST金币
程序写好后发现有一定几率上电后看门狗复位,然后屏蔽看门狗,用定时器控制灯闪烁作为指示,主循环里串口每隔一秒输出一句话;
发现有一定几率主循环里不走,但定时器控制的灯正常闪烁。程序不知道停在哪里了。
然后把主循环里的语句逐句屏蔽掉,最后发现可能是ADC这部分的问题。

ADC这里是这样实现的,只用了STM32的1个ADC引脚,用多路模拟开关来切换外部多个输入信号。
之前ADC的DMA传输就没搞明白,在主循环外开启DMA后,发现读写spi flash异常慢,后来关掉ADC的DMA后正常了。
于是不敢一直开启DMA,而是在主循环里进行ADC读取前开启DMA,读取后再关闭DMA。

请教下大家,问题可能出在哪里?到底程序停在了哪里?

  1. void GetAdcValue(void)
  2. {
  3.     uint8_t i, j;
  4.     ADC_ChannelConfTypeDef sConfig;

  5.     sConfig.Channel = ADC_CHANNEL_8;
  6.     sConfig.Rank = ADC_REGULAR_RANK_1;
  7.     sConfig.SamplingTime = ADC_SAMPLETIME_55CYCLES_5;
  8.     if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  9.         _Error_Handler(__FILE__, __LINE__);
  10.     HAL_ADC_Start_DMA(&hadc1, (uint32_t *)(&adc_Xin_value[0]), 1);

  11.     for(i = 0; i < 8; i++)
  12.     {
  13.         CD4051_XIN(i);
  14.         adcCompletFlag = 0;
  15.         HAL_Delay(1);
  16.         // if (1 == adcCompletFlag)
  17.             adcXinVoltage[i] = adc_Xin_value[0]*2500/4095;
  18.         //HAL_IWDG_Refresh(&hiwdg);
  19.     }

  20.     sConfig.Channel = ADC_CHANNEL_9;
  21.     if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  22.         _Error_Handler(__FILE__, __LINE__);
  23.     for(i = 0; i < 8; i++)
  24.     {
  25.         CD4051_XIN(i);
  26.         adcCompletFlag = 0;
  27.         HAL_Delay(1);
  28.         // if (1 == adcCompletFlag)
  29.             adcXinVoltage[i+8] = adc_Xin_value[0]*2500/4095;
  30.         //HAL_IWDG_Refresh(&hiwdg);
  31.     }
  32.     HAL_ADC_Stop_DMA(&hadc1);
  33. }
复制代码



最佳答案

查看完整内容

开DMA后,主循环是会变慢。 因为DMA和系统总线是复用的,只不过DMA最大能占到二分之一的带宽,至少要给系统留二分之一的带宽。具体DMA带宽分配,是内核仲裁的,外界干涉不了。
收藏 评论9 发布时间:2019-1-30 09:51

举报

9个回答
七哥 回答时间:2019-1-30 09:51:47
any012 发表于 2019-1-30 10:44
我前几天发了另一个贴,咨询ADC中断对主循环的影响。虽然那贴结贴了,但是我仍不太明白。
我在主循环前开启 ...

开DMA后,主循环是会变慢。
因为DMA和系统总线是复用的,只不过DMA最大能占到二分之一的带宽,至少要给系统留二分之一的带宽。具体DMA带宽分配,是内核仲裁的,外界干涉不了。

评分

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

查看全部评分

any012 回答时间:2019-1-30 10:11:43
群里有朋友说开启DMA后不能操作缓存,但没有细说。
是这个原因吗?必须等EOC标志才能读吗?
cxy 回答时间:2019-1-30 10:29:03
wo  de ye shi   gan jue xiang zongxian chongtu
any012 回答时间:2019-1-30 10:44:09
我前几天发了另一个贴,咨询ADC中断对主循环的影响。虽然那贴结贴了,但是我仍不太明白。
我在主循环前开启ADC的DMA功能后,其后的读取spi flash芯片的执行速度,就非常慢了。

所以我现在在主循环里的需要读取adc值时才开启ADC的DMA传输功能,读取完后再关闭。
没想到有几率上电卡死。
any012 回答时间:2019-1-30 10:59:59
toofree 发表于 2019-1-30 10:54
开DMA后,主循环是会变慢。
因为DMA和系统总线是复用的,只不过DMA最大能占到二分之一的带宽,至少要给系 ...

那么,我现在的情况应该适用于在主循环里反复开启观点ADC的DMA吧。
能否帮分析下我的程序卡死的情况?
七哥 回答时间:2019-1-30 11:09:55
any012 发表于 2019-1-30 10:59
那么,我现在的情况应该适用于在主循环里反复开启观点ADC的DMA吧。
能否帮分析下我的程序卡死的情况? ...

慢慢排查吧。
双以往经验来看,你的问题并不是出在你以为会有问题的地方。
你说的主循环里不走,那么程序进没进去主循环呢?如果进了主循环,而不走的话,看看哪块有死循环,而没有超时退出机制;如果都没进主循环,那么在前面排查。
仿真调试,多个LED灯指示程序运行的不同位置,串口打印等,都是调试手段。
any012 回答时间:2019-1-30 11:16:36
进主循环了。
屏蔽掉大部分功能,现在只剩adc部分和串口和定时器了。串口只是用来定时输出信息看主循环有没有死掉,定时器...
定时器没有把定时中断里的所有语句都屏蔽掉,这么说也有可能是定时器中断的问题。不过定时器中断里只是累加一个变量,然后通过这个变量除10、100、1000来得到其它时间基准。主要是定时中断里控制的led灯能正常反转,所以觉得定时器出问题的可能性也不大。
any012 回答时间:2019-1-30 19:23:21
现在改成阻塞方式获取adc值,暂时没出现问题。
我还是怀疑是反复开启关闭dma造成的。
单片机爱好者 回答时间:2019-1-31 14:07:08
没遇到过。。。

所属标签

相似问题

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