打印

关于STM32 ADC用DMA采多通道时数据错位的问题New

[复制链接]
楼主: kingpower2018
手机看帖
扫描二维码
随时随地手机跟帖
61
kingpower2018|  楼主 | 2009-7-13 16:27 | 只看该作者 回帖奖励 |倒序浏览

客户现场是不能RST的

客户现场是不能RST的,你以为客户是你们的实验室,想怎么样搞就怎么样来搞

使用特权

评论回复
62
kingpower2018|  楼主 | 2009-7-13 16:33 | 只看该作者

看来只能与ST国外总部联系

使用特权

评论回复
63
香水城| | 2009-7-13 16:35 | 只看该作者

STM32的数据手册上标明ESD只能承受2000V

你打8000V已经远远超出手册规定的最大允许工作范围。

还有,我请楼主在ADC因为干扰出现问题时,单独对ADC模块进行复位,不知结果如何?

使用特权

评论回复
64
sszxxm| | 2009-7-13 19:41 | 只看该作者

晕,静电枪晃几下就会出现ADC不稳定,还要RESET才行?

建议楼主先把硬件处理好再做软件,身子骨不行的话,再聪明的脑袋也无济于事啊。

使用特权

评论回复
65
511| | 2009-7-14 10:08 | 只看该作者

这么精彩的讨论要留下我的脚印~~~

使用特权

评论回复
66
kingpower2018|  楼主 | 2009-7-14 11:48 | 只看该作者

快回复

使用特权

评论回复
67
freefish| | 2009-7-14 13:13 | 只看该作者

总算说清了一些

出现问题后不恢复,可能的问题是:ADC的精度校准出了异常,通道错位,算法问题等。
建议:出现问题后取出待计算的采样数据加以分析。
不清楚你的算法,也见不到数据,没法判别。注意几点:一是不要使用浮点数据,小数的处理使用Q格式,自己定标。二是不要使用SQRT(),也不要使用牛顿迭代法,有更简便的开方算法。三是不要使用连续AD转换,使用TIM触发,出现问题后也好恢复。
所有的设备出现问题后都允许RST, 我拆解过所见过的所有微机保护装置,国内的有南瑞,北京四方,许继;进口的有ALSTOM,SEL,SEG,西门子,ABB等,这些设备使用的芯片各不相同,南瑞的低压系统为S80296,现在用BF532,高压的是ADI的ADSP2181;ALSTOM的4平台用TMS320VC33,西门子的比较乱,有80196的,也有EX386的,但是共同的一点是:即使有内置看门狗,也一定有一片外置看门狗!
除了硬件保证,软件上也要处理很多东西,比如坏数据处理。曾将有某国内大公司生产的发电机差动保护误动作切除一台60W千瓦大机组,造成电网周波动荡,最终原因是VFC参考电压瞬间波动造成,但录波分析发现此问题完全可以避免,只要在采样中加一条if()即可。在很多书中都提到,可以利用任何时刻,电网中ia+ib+ic-3i0 = 0 这一特点即可判断出坏数据。当然实际应用不能为0,但是可以设定为一定的门槛。

使用特权

评论回复
68
bhsdlmj| | 2009-7-14 13:15 | 只看该作者

快升级 I2C库!!!

kingpower2018  你这个问题还没有解决啊??

得换换思路了 似乎

使用特权

评论回复
69
kingpower2018|  楼主 | 2009-7-15 10:21 | 只看该作者

还有高招吗

使用特权

评论回复
70
511| | 2009-7-15 22:53 | 只看该作者

好贴啊,关注ING

使用特权

评论回复
71
bhsdlmj| | 2009-7-17 07:53 | 只看该作者

估计是没有招数了

最好的招数看来是楼主冷静冷静头脑 自己搞定了!!!

使用特权

评论回复
72
violet520| | 2009-7-17 15:16 | 只看该作者

能把我们的香斑竹难倒,不容易啊

使用特权

评论回复
73
香水城| | 2009-7-17 23:00 | 只看该作者

哈哈,熏香疗法不是万能的

香斑竹也只知芯片内部的事情,外面的世界就知之甚少了。

使用特权

评论回复
74
kingpower2018|  楼主 | 2009-7-21 16:07 | 只看该作者

回复?

使用特权

评论回复
75
bhsdlmj| | 2009-7-21 16:44 | 只看该作者

huifu !~!!

使用特权

评论回复
76
kingpower2018|  楼主 | 2009-9-8 14:01 | 只看该作者
回复

使用特权

评论回复
77
kingpower2018|  楼主 | 2009-9-8 14:02 | 只看该作者
问题一直没解决呀

使用特权

评论回复
78
zhaozhifang| | 2009-9-9 16:42 | 只看该作者

排除法解决问题,找到干扰源是正道

楼主,一团乱麻想要解开,用手拍打是不行的。这是我工作的警句。我来帮你理理思路。如你所言,板子在实验室不出问题,在现场出问题。而且能够确认,一个大的电机启动与一个故障有直接关联性。然后,你认为芯片有问题,然后你反复要求st公司的人解决。显然你的工作思路不清楚。
1、假设芯片确有稳定性问题,st公司的技术支持就能解决了么?
2、你反复要求st公司的人解决的只能是请他们帮你看看你是否正确使用了芯片。而深入的了解和掌握芯片不正是你的工作么?别人都是辅助你的。
3、如你所言,既然在实验室没问题,你能否在现场创造一个小环境屏蔽一切干扰?然后再观察板子的运行情况。
4、假设板子有保护情况下正常工作,你可以逐一的解除相关保护,直到某种干扰引入造成故障。
5、然后对症下药,解决问题,兴师问罪,看看大刀砍到谁的头上。你现在这个状态,若当了皇帝,肯定是昏君。
总结,要找到干扰作用到了“哪”。

使用特权

评论回复
79
kingpower2018|  楼主 | 2009-10-14 16:59 | 只看该作者
我也想呀,可是客户现场不是你的实验田,不准你随便搞的

使用特权

评论回复
80
xiaoshuang| | 2009-10-15 09:57 | 只看该作者
我的ad也同样出过错位问题,但是后来我还是用软件的办法解决了。我说说我的情况的思路,看看是否对楼主有帮助。
开始,我使用的是16路规则通道的ad循环多次扫描,使用dma传送到一个256的字节的数组,然后我就没有管它了,有时间就去那数组中取出来计算平均值。在短时间内也是无事。但是机器一多,有的就发生过错位了,也用仿真器抓到过。初始化程序如下:
uint16  ADC_ConvertedValue[256];//ad转换结果存入的数组
void init_ad(void)
{
ADC_InitTypeDef ADC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;

/* Enable peripheral clocks --------------------------------------------------*/
  /* Enable DMA clock */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA, ENABLE);

  /* Enable ADC1 and GPIOC clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE);

/*初始化DMA*/
    DMA_DeInit(DMA_Channel1);
  DMA_InitStructure.DMA_PeripheralBaseAddr =0x4001244c;
  DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_ConvertedValue;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = 256;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA_Channel1, &DMA_InitStructure);
  
  /* Enable DMA channel1 */
  DMA_Cmd(DMA_Channel1, ENABLE);
  
/*初始化AD*/
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_InitStructure.ADC_ScanConvMode = ENABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfChannel = 16;
  ADC_Init(ADC1, &ADC_InitStructure);


  ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_1Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_1Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_1Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_1Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 5, ADC_SampleTime_1Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 6, ADC_SampleTime_1Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 7, ADC_SampleTime_1Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 8, ADC_SampleTime_1Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 9, ADC_SampleTime_1Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 10, ADC_SampleTime_1Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 11, ADC_SampleTime_55Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 12, ADC_SampleTime_55Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 13, ADC_SampleTime_55Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 14, ADC_SampleTime_55Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 15, ADC_SampleTime_1Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 16, ADC_SampleTime_1Cycles5);


  ADC_DMACmd(ADC1, ENABLE);
  

  ADC_Cmd(ADC1, ENABLE);
  

  ADC_ResetCalibration(ADC1);

  while(ADC_GetResetCalibrationStatus(ADC1));


  ADC_StartCalibration(ADC1);

  while(ADC_GetCalibrationStatus(ADC1));
     
  /* Start ADC1 Software Conversion */
  ADC_SoftwareStartConvCmd(ADC1, ENABLE);  
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则