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

主循环里不断开启关闭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个回答
toofree 回答时间: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吧。
能否帮分析下我的程序卡死的情况?
toofree 回答时间: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造成的。
jy04706985 回答时间:2019-1-31 14:07:08
没遇到过。。。

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版