stm32f4 ADC采样频率是多少?

2019-07-20 10:23发布

  对于F4ADC配置有几点疑问希望大家帮忙解答一下:  问题1:这个表的意思是否是说明F4在供电电压大于2.4V时其最大时钟是36MHZ?当其时钟在30MHZ时,外部触发采样频率最大为1764KHZ?
 如果上面这个问题是对的话,那么对于库函数的几项操作有点疑问:  这个说明给出了ADC转换时间的计算方式,那么对应的我配置如下:
//ADC时钟为APB2的4分频->84/4=21MHZ(F407ADC在2.4-3.6V供电电压下最大速率36M,稳定速度为30M)
        ADC_CommonInitStructure.ADC_Prescaler=ADC_Prescaler_Div4;
//配置ADC1规则组(得出其单次采样时间为->(3+12)/21≈0.7us)
ADC_RegularChannelConfig(ADC1,ADC_Channel_10,1,ADC_SampleTime_3Cycles);
//两次采样的间隔时间为5个ADC时钟周期(5/21≈0.24us)
        ADC_CommonInitStructure.ADC_TwoSamplingDelay=ADC_TwoSamplingDelay_5Cycles;
问题2:按照如上数据理论值计算其最大采样频率:0.7+0.24≈1us->1MHZ,是否是这样计算的?
问题3:我想用ADC+DMA+TIM触发的方式来做一个简易的示波器,方法就是通过TIM的定时触发ADC采样,将采样值装入DMA缓存中,DMA装满后触发LCD刷新程序。
有一个概念我不是很清楚,比如我一屏采100个点,要能显示400HZ的正弦信号,是不是说我ADC采样速率至少要100*400=40KHZ的速率呢?
补充内容 (2017-5-12 17:49): 更正一个几年前的错误, ADC_CommonInitStructure.ADC_TwoSamplingDelay=ADC_TwoSamplingDelay_5Cycles; 此项配置仅仅用于双重或三重交错模式下才有效,也就是说之前的计算是错误的
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
47条回答
jj123paopao
1楼-- · 2019-07-21 13:16
回复【7楼】KC_CEC:
---------------------------------
谢谢,我发现程序会死在这句:while(ADC1->SR & 1<<1);
这句话作用是等待转换结束,注释掉之后就正常在串口中打印电压值了,用PA1采样板子上的3.3V电压,采样得到的最低电压是3.295166V,最高电压是3.299194V.
请问为什么程序会卡死在那句话?
KC_CEC
2楼-- · 2019-07-21 13:34
 精彩回答 2  元偷偷看……
天使的诺言
3楼-- · 2019-07-21 16:14
楼主你好!(ADC+DMA) 我使用的是单个ADC多通道采集。 在配置的时候,使用了DMA 发送过半中断


这是stm32f4xx_it.c
中断程序
void DMA2_Stream0_IRQHandler(void)
{
//??????·???DMA·?????°?????
   if(DMA_GetFlagStatus(DMA2_Stream0,DMA_FLAG_HTIF0)==SET) 
   {  
     int i;
 printf("ok");
for(i=0;i<256;i++)
{
data= (ADC_ConvertedValue >> 8) & 0xff;
}
printf("%f ",Rx_Buffer*16*3.3*2/4096);
  SPI_FLASH_PageWrite(data, MyWriteAddr, 256);
MyWriteAddr+=256;
// printf("ok");
DMA_ClearFlag(DMA2_Stream0,DMA_FLAG_HTIF0);
}else if(DMA_GetFlagStatus(DMA2_Stream0,DMA_FLAG_TCIF0)==SET) 
    {  
int i;
for(i=256;i<512;i++)
{
data= (ADC_ConvertedValue >> 8) & 0xff;
}
SPI_FLASH_PageWrite(data, MyWriteAddr, 256);
MyWriteAddr+=256;
// printf("yes");
DMA_ClearFlag(DMA2_Stream0,DMA_FLAG_TCIF0);  

if(MyWriteAddr>=0x3fffff)
{
DMA_ITConfig(DMA2_Stream0,DMA_IT_TC | DMA_IT_HT,DISABLE);
GPIO_ResetBits(GPIOB,GPIO_Pin_5);
printf("  -------ADC×????á????????????????------ ");
}
}
贴过来乱码出无关紧要!

这个是ADC配置 用了DMA中断!

#include "adc.h"

#define ADC1_DR_Address    ((uint32_t)0x4001224C)
__IO uint16_t ADC_ConvertedValue[CH_NUM]={0};
//__IO u16 ADC_ConvertedValueLocal;


/*
 * ????????ADC1_GPIO_Config
 * ?è??  ??????ADC1??DMA2???±??????????PC.01
 * ????: ??
 * ????  ????
 * ?÷??  ???????÷??
 */



/* ????????ADC1_Mode_Config
 * ?è??  ??????ADC1???¤×÷??????DMA????
 * ????: ??
 * ????  ????
 * ?÷??  ???????÷??
 */
 
 
 
 /* ????????ADC1_Config
 * ?è??  ??????ADC1???¤×÷??????DMA????
 * ????: ??
 * ????  ????
 * ?÷??  ???????÷??
 */
 static void ADC1_Config(void)
{

GPIO_InitTypeDef GPIO_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;


/* Enable DMA clock */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);

/* Enable GPIOC clock */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);

/* Enable ADC1 clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);


/* DMA channel0 configuration */
DMA_DeInit(DMA2_Stream0);
DMA_InitStructure.DMA_Channel = DMA_Channel_0;  
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;  //ADC???·
DMA_InitStructure.DMA_Memory0BaseAddr = (u32)&ADC_ConvertedValue;//???????·
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = CH_NUM;
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_FIFOMode = DMA_FIFOMode_Disable;         
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
//DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA2_Stream0, &DMA_InitStructure);
//DMA_ITConfig(DMA2_Stream0,DMA_IT_TC,ENABLE);
DMA_Cmd(DMA2_Stream0, ENABLE);


/* Configure C.01  as analog input */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOC, &GPIO_InitStructure); // C0,PC1,PC2,?????±?????è??????



  /* ADC1 configuration */
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;//ADC?±??21MHz
  ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
  ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
  ADC_CommonInit(&ADC_CommonInitStructure);


ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//????ADC????
ADC_InitStructure.ADC_ScanConvMode = ENABLE;   //?????¨?è???????¨?è?????????à?¨??????
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //????????×?????????????????????ADC×???
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//????????????·?×???
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Left;  //????????×ó????
ADC_InitStructure.ADC_NbrOfConversion = 4;   //??×??????¨??????4
ADC_Init(ADC1, &ADC_InitStructure);

 
/*????ADC1???¨??10,11,12??3?????ù???????ò????1,2,3,4 */ 
ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_3Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 2, ADC_SampleTime_3Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 3, ADC_SampleTime_3Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 4, ADC_SampleTime_3Cycles);

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

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

/*??????×??????÷ */   
/*ADC_ResetCalibration(ADC1);*/
/*??????×??????÷?????ê?? */
/*while(ADC_GetResetCalibrationStatus(ADC1));*/

/* ADC??×? */
/*ADC_StartCalibration(ADC1);*/
/* ??????×??ê??*/
/*while(ADC_GetCalibrationStatus(ADC1));*/


}

void NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
  
/* Configure one bit for preemption priority */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  
/* ????P[A|B|C|D|E]0???????? */
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

}

/*
 * ????????ADC1_Init
 * ?è??  ????
 * ????  ????
 * ????  ????
 * ?÷??  ???????÷??
 */

 void ADC_start(void)
 {
 /* ??????????????????·????ù???????í????·?ADC×??? */ 
ADC_SoftwareStartConv(ADC1);
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);

/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* Enable DMA channel0 */
DMA_Cmd(DMA2_Stream0, ENABLE);
DMA_ITConfig(DMA2_Stream0,DMA_IT_TC | DMA_IT_HT,ENABLE);
 }
void ADC1_Init(void)
{
ADC1_Config();
NVIC_Config();
}


求解为什么我的DMA中断进不去,还是我的ADC没有工作,本人做的是一个数据采集,其他led exti usart 均已调试成功!
跪求大神指点。
KC_CEC
4楼-- · 2019-07-21 19:56
回复【10楼】天使的诺言:
---------------------------------
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; 
可能是你没有使能DMA转换吧。

库函数里面可以读取很多标志位的,通过串口打印各个标志位就知道自己哪一步搞错了哦。
aelan
5楼-- · 2019-07-21 19:59
 精彩回答 2  元偷偷看……
球球~电子
6楼-- · 2019-07-21 23:43
你好,我也想做一个简易示波器,双ADC+DMA我已经调通不过用的是F1
我想问一下楼主是怎么把数据在LCD上还原成正弦曲线的。。。

一周热门 更多>