主循环里不断开启关闭ADC的DMA传输功能,上电有几率死机。
程序写好后发现有一定几率上电后看门狗复位,然后屏蔽看门狗,用定时器控制灯闪烁作为指示,主循环里串口每隔一秒输出一句话;发现有一定几率主循环里不走,但定时器控制的灯正常闪烁。程序不知道停在哪里了。
然后把主循环里的语句逐句屏蔽掉,最后发现可能是ADC这部分的问题。
ADC这里是这样实现的,只用了STM32的1个ADC引脚,用多路模拟开关来切换外部多个输入信号。
之前ADC的DMA传输就没搞明白,在主循环外开启DMA后,发现读写spi flash异常慢,后来关掉ADC的DMA后正常了。
于是不敢一直开启DMA,而是在主循环里进行ADC读取前开启DMA,读取后再关闭DMA。
请教下大家,问题可能出在哪里?到底程序停在了哪里?
void GetAdcValue(void)
{
uint8_t i, j;
ADC_ChannelConfTypeDef sConfig;
sConfig.Channel = ADC_CHANNEL_8;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_55CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
_Error_Handler(__FILE__, __LINE__);
HAL_ADC_Start_DMA(&hadc1, (uint32_t *)(&adc_Xin_value), 1);
for(i = 0; i < 8; i++)
{
CD4051_XIN(i);
adcCompletFlag = 0;
HAL_Delay(1);
// if (1 == adcCompletFlag)
adcXinVoltage = adc_Xin_value*2500/4095;
//HAL_IWDG_Refresh(&hiwdg);
}
sConfig.Channel = ADC_CHANNEL_9;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
_Error_Handler(__FILE__, __LINE__);
for(i = 0; i < 8; i++)
{
CD4051_XIN(i);
adcCompletFlag = 0;
HAL_Delay(1);
// if (1 == adcCompletFlag)
adcXinVoltage = adc_Xin_value*2500/4095;
//HAL_IWDG_Refresh(&hiwdg);
}
HAL_ADC_Stop_DMA(&hadc1);
}
any012 发表于 2019-1-30 10:44
我前几天发了另一个贴,咨询ADC中断对主循环的影响。虽然那贴结贴了,但是我仍不太明白。
我在主循环前开启 ...
开DMA后,主循环是会变慢。
因为DMA和系统总线是复用的,只不过DMA最大能占到二分之一的带宽,至少要给系统留二分之一的带宽。具体DMA带宽分配,是内核仲裁的,外界干涉不了。 群里有朋友说开启DMA后不能操作缓存,但没有细说。
是这个原因吗?必须等EOC标志才能读吗? wode ye shi gan jue xiang zongxian chongtu 我前几天发了另一个贴,咨询ADC中断对主循环的影响。虽然那贴结贴了,但是我仍不太明白。
我在主循环前开启ADC的DMA功能后,其后的读取spi flash芯片的执行速度,就非常慢了。
所以我现在在主循环里的需要读取adc值时才开启ADC的DMA传输功能,读取完后再关闭。
没想到有几率上电卡死。 toofree 发表于 2019-1-30 10:54
开DMA后,主循环是会变慢。
因为DMA和系统总线是复用的,只不过DMA最大能占到二分之一的带宽,至少要给系 ...
那么,我现在的情况应该适用于在主循环里反复开启观点ADC的DMA吧。
能否帮分析下我的程序卡死的情况? any012 发表于 2019-1-30 10:59
那么,我现在的情况应该适用于在主循环里反复开启观点ADC的DMA吧。
能否帮分析下我的程序卡死的情况? ...
慢慢排查吧。
双以往经验来看,你的问题并不是出在你以为会有问题的地方。
你说的主循环里不走,那么程序进没进去主循环呢?如果进了主循环,而不走的话,看看哪块有死循环,而没有超时退出机制;如果都没进主循环,那么在前面排查。
仿真调试,多个LED灯指示程序运行的不同位置,串口打印等,都是调试手段。 进主循环了。
屏蔽掉大部分功能,现在只剩adc部分和串口和定时器了。串口只是用来定时输出信息看主循环有没有死掉,定时器...
定时器没有把定时中断里的所有语句都屏蔽掉,这么说也有可能是定时器中断的问题。不过定时器中断里只是累加一个变量,然后通过这个变量除10、100、1000来得到其它时间基准。主要是定时中断里控制的led灯能正常反转,所以觉得定时器出问题的可能性也不大。 现在改成阻塞方式获取adc值,暂时没出现问题。
我还是怀疑是反复开启关闭dma造成的。 没遇到过。。。
页:
[1]