打印

STM32多路采集ADC+DMA

[复制链接]
2398|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
我使用是的STM32F103ZET6,同时使用ADC1的16个通道,ADC3的5个通道,都使用DMA来传输,问题:比如ADC1_CH0通道上的值保存到了Buffer[1],其他数据往后移,ADC1_CH15的数据出现在Buffer[0]上,更不可失意的的是,有是ADC1_CH0通道的值出现在Buffer[2]上,其他的往后移,ADC1_CH14,ADC1_CH15则出现在Buffer[0],Buffer[1]上。请大家是否有朋友也碰到过。
评分
参与人数 1威望 +1 收起 理由
logokfu + 1 我在107上还没有遇到这个问题
沙发
airwill| | 2013-6-3 22:32 | 只看该作者
这个 ADC DMA 错位的问题, 我早在两年多前就发现和提出来了.
至今未能解决.
所以现在 1O3 上都避免使用 ADC 的 DMA .

使用特权

评论回复
板凳
hxb20122012|  楼主 | 2013-6-4 21:48 | 只看该作者
不知道版主的问题和我的是否一样,我的问题已经解决了。
总结:(1)一定要配置好ADC之后,才使能DMA
(2)ADC首先要进行默认初始化。
但现在又有新的问题,我在ADC3_CH4通道输入12MHz的正弦波之后,会干扰到ADC1_CH0,ADC1_CH15通道。求解!!!!!!!

使用特权

评论回复
地板
pinghpu| | 2013-6-5 10:46 | 只看该作者
使用ADC多通道DMA时确实存在错位的问题,等待高手的解答。

使用特权

评论回复
5
logokfu| | 2013-6-5 11:45 | 只看该作者
本帖最后由 **kfu 于 2013-6-5 11:53 编辑
hxb20122012 发表于 2013-6-4 21:48
不知道版主的问题和我的是否一样,我的问题已经解决了。
总结:(1)一定要配置好ADC之后,才使能DMA
(2) ...

什么叫  “一定要配置好ADC之后,才使能DMA”。可否上具体代码看看。

我是参考按照如下的官方的demo code做的,没有发现错位现象。我用F107
/**
*  Main program
* @param None
* @retval None
*/
int main(void)
{
/*!< At this stage the microcontroller clock setting is already configured,
this is done through SystemInit() function which is called from startup
file (startup_stm32f10x_xx.s) before to branch to application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32f10x.c file
*/

/* System clocks configuration ---------------------------------------------*/
RCC_Configuration();

/* GPIO configuration ------------------------------------------------------*/
GPIO_Configuration();

/* DMA1 channel1 configuration ----------------------------------------------*/
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADCConvertedValue;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 1;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
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(DMA1_Channel1, &DMA_InitStructure);

/* Enable DMA1 channel1 */
DMA_Cmd(DMA1_Channel1, ENABLE);

/* ADC1 configuration ------------------------------------------------------*/
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 = 1;
ADC_Init(ADC1, &ADC_InitStructure);

/* ADC1 regular channel14 configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_55Cycles5);

/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);

/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);

/* Enable ADC1 reset calibration register */
ADC_ResetCalibration(ADC1);
/* Check the end of ADC1 reset calibration register */
while(ADC_GetResetCalibrationStatus(ADC1));

/* Start ADC1 calibration */
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while(ADC_GetCalibrationStatus(ADC1));

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

while (1)
{
}
}

这个是我的完整的一个工程,调试通过,没有发现错位现象。

说明:  ADC1,8通道ADC采集,采用DMA1通道1传送数据,然后通过串口1 输出到超级终端
采用systick产生1ms时基,每隔100ms输出一次数据。


八通道ADC1_DMA_Printf.rar (1.69 MB)


使用特权

评论回复
6
hxb20122012|  楼主 | 2013-6-5 16:38 | 只看该作者
官方例子是没有问题的!只是自己写着就会出问题,按着自己的思路,没有按照官方的来。

使用特权

评论回复
7
hawksabre| | 2013-6-5 19:00 | 只看该作者
不错   谢谢楼主的  共享资料   不错哦

使用特权

评论回复
8
拿起书本| | 2013-6-5 21:49 | 只看该作者
先收藏了这个重量级的资料,能提供一些实际工程案例最好了。

使用特权

评论回复
9
wago2008| | 2013-6-7 10:06 | 只看该作者
有没试过1us adc采样?就会发生错位,第一个数就不对了,用的自带的时钟14mhz。是太快了么,如果换时间长点就正常

使用特权

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

本版积分规则

74

主题

564

帖子

1

粉丝