OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6345|回复: 3

【请教】stm32 ADC+DMA信号采集采样频率的问题。

[复制链接]

24

主题

91

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
377
金钱
377
注册时间
2013-6-19
在线时间
53 小时
发表于 2014-7-15 12:49:39 | 显示全部楼层 |阅读模式
5金钱
rt,通过 stm32内部ADC采集2路信号,每路信号采集100个点。采用扫描模式。DMA搬运。
我配置了RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //分频因子6时钟为72M/6=12MHz
ADC_RegularChannelConfig(ADC1,ADC_Channel_10,1,ADC_SampleTime_13Cycles5);    //通道10采集顺序为1
则ADC转换完成所用的时间为(12.5+13.5)*(1/12M)
则ADC采样的频率应为12/26MHz=0.46MHz
而我实测ADC从开始 DMA到DMA完成用时大概1ms。则采样频率为200K左右。那不合理啊。而且我改变ADC通道的采样周期加到239.5个周期采样频率还是200K左右。
不知道是什么情况。
程序源码如下 :
[mw_shl_code=c,true]void RCC1_Configuration(void) { ErrorStatus HSEStartUpStatus; RCC_DeInit(); //RCC 系统复位 RCC_HSEConfig(RCC_HSE_ON); //开启HSE HSEStartUpStatus = RCC_WaitForHSEStartUp(); //等待HSE准备好 if(HSEStartUpStatus == SUCCESS) { FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //Enable Prefetch Buffer FLASH_SetLatency(FLASH_Latency_2); //Set 2 Latency cycles RCC_HCLKConfig(RCC_SYSCLK_Div1); //AHB clock = SYSCLK RCC_PCLK2Config(RCC_HCLK_Div1); //APB2 clock = HCLK RCC_PCLK1Config(RCC_HCLK_Div2); //APB1 clock = HCLK/2 RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_6); //PLLCLK = 12MHz * 6 = 72 MHz RCC_PLLCmd(ENABLE); //Enable PLL while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); //Wait till PLL is ready RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //Select PLL as system clock source while(RCC_GetSYSCLKSource() != 0x08); //Wait till PLL is used as system clock source /*使能各个外设时钟*/ } } /** * @brief void ADC1_Configuration(void) * @note ADC1初始化配置 * @param None * @retval None * @deprecated */ void ADC1_Configuration(void) { ADC_InitTypeDef ADC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE); //使能ADC时钟 ADC_DeInit(ADC1); //将外设 ADC1 的全部寄存器重设为缺省值 /* ADC1 configuration ------------------------------------------------------*/ ADC_InitStructure.ADC_Mode=ADC_Mode_Independent; //独立ADC模式 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=ADC_CONVERT_CHANNEL; //要转换的通道数目 ADC_Init(ADC1,&ADC_InitStructure); /* ADC1 regular channel11 configuration */ //设置指定ADC的规则组通道,设置它们的转化顺序和采样时间 RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC分频因子6 72M/6=12M //配置ADC1的通道14为13.5个采样周期 ADC_RegularChannelConfig(ADC1,ADC_Channel_10,1,ADC_SampleTime_13Cycles5); //通道10采集顺序为1 ADC_RegularChannelConfig(ADC1,ADC_Channel_11,2,ADC_SampleTime_13Cycles5); //ADC_RegularChannelConfig(ADC1,ADC_Channel_16,3,ADC_SampleTime_13Cycles5); //内部温度传感器采集 //ADC_RegularChannelConfig(ADC1,ADC_Channel_17,4,ADC_SampleTime_13Cycles5); //内部基准电压采集 /*开启ADC的DMA支持*/ ADC_DMACmd(ADC1,ENABLE); /* Enable ADC1 */ ADC_Cmd(ADC1,ENABLE); /* Enable ADC1 reset calibaration register */ ADC_ResetCalibration(ADC1); //复位校准寄存器 /* Check the end of ADC1 reset calibration register */ while (ADC_GetResetCalibrationStatus(ADC1)); //等待校准寄存器复位完成 /* Start ADC1 calibaration */ ADC_StartCalibration(ADC1); //ADC校准 /* Check the end of ADC1 calibration */ while (ADC_GetCalibrationStatus(ADC1)); //等待校准完成 // /*打开ADC转换*/ //ADC_SoftwareStartConvCmd(ADC1,ENABLE); //使能软件外部触发ADC转换 } /** * @brief void ADC1_DMA_Configuration(void) * @note ADC1的DMA通道配置 * @param None * @retval None * @deprecated */ void ADC1_DMA_Configuration(vu16 **ADC_VALUE_ADDR) //void ADC1_DMA_Configuration(pADC_ADDR ADC_VALUE_ADDR) { DMA_InitTypeDef DMA_InitStructure; //printf("ADC_VALUE_ADDR:%d\n",(uint32_t)ADC_VALUE_ADDR) ; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE); /* DMA1 channel1 configuration ----------------------------------------------*/ DMA_DeInit(DMA1_Channel1); //DMA通道1寄存器设为缺省值 DMA_InitStructure.DMA_PeripheralBaseAddr=(u32)&ADC1->DR; //设置DMA外设基地址 DMA_InitStructure.DMA_MemoryBaseAddr=(uint32_t)ADC_VALUE_ADDR; //设置DMA内存地址 DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC; //设置外设为数据源 DMA_InitStructure.DMA_BufferSize=ADC_CONVERT_TIMES*ADC_CONVERT_CHANNEL; //DMA通道的DMA缓存大小 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通道具有高优先级 DMA_InitStructure.DMA_M2M=DMA_M2M_Disable; //DMA通道没有设置为内存到内存传输 DMA_Init(DMA1_Channel1,&DMA_InitStructure); /* Enable DMA1 channel1 */ /*启动DMA*/ //DMA_Cmd(DMA1_Channel1,ENABLE); //使能DMA通道1 } [/mw_shl_code]
这里DMA搬运起始地址是数据缓冲队列中相应二维数组的起始地址。

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

24

主题

91

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
377
金钱
377
注册时间
2013-6-19
在线时间
53 小时
 楼主| 发表于 2014-7-15 18:01:00 | 显示全部楼层
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-7-15 23:13:46 | 显示全部楼层
仿真看看寄存器配置对不对吧?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

24

主题

91

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
377
金钱
377
注册时间
2013-6-19
在线时间
53 小时
 楼主| 发表于 2014-7-16 21:56:08 | 显示全部楼层
回复【3楼】正点原子:
---------------------------------
好的,谢谢原子大哥
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-7-5 07:34

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表