21ic问答首页 - MM32F031K6T的ADC转换速率好像达不到1Msps
MM32F031K6T的ADC转换速率好像达不到1Msps
deadphenix2022-02-26
我使用库例程,时钟使用HSI,72MHz,APB2不分频;ADC_PRESCARE设置为12;
设置采样通道2个,通道采样时间在55.5周期以上,符合数据手册。但如果采样时间设置为13.5周期,却达不到111ksps,任何低于55.5周期的设置,都只能达到65ksps左右;或者ADC_PRESCARE设置为11及以下,提高ADC时钟,也都只能达到65ksps左右;请问瓶颈在哪儿?下面是ADC配置和时钟配置
//ADC配置,2个采样通道
void ADCMultiChannelInit(){
GPIO_Config_AIN(GPIOA, GPIO_Pin_1);
GPIO_Config_AIN(GPIOA, GPIO_Pin_3);
ADC_InitTypeDef ADC_InitStructure;
ADC_StructInit(&ADC_InitStructure);
//Initialize PA1 to analog input mode
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //Enable ADC clock
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_PRESCARE = ADC_PCLK2_PRESCARE_12; //ADC prescale factor
ADC_InitStructure.ADC_Mode = ADC_Mode_Continuous_Scan; //Set ADC mode to continuous conversion mode
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //AD data right-justified
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC, ADC_Channel_DisableAll, 0, ADC_SampleTime_13_5Cycles);//Block all channels
ADC_RegularChannelConfig(ADC1, ADCch1, 0, ADC_SampleTime_13_5Cycles);//Enable the channel
ADC_RegularChannelConfig(ADC1, ADCch2, 0, ADC_SampleTime_13_5Cycles);//Enable the channel
#ifdef ADC_USE_DMA
ADC_DMACmd(ADC1, ENABLE); //Enable ADCDMA
#else
ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE); //DMA interrupt initialization
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = ADC_COMP_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
#endif
ADC_Cmd(ADC1, ENABLE); //Enable AD conversion
}
//DMA配置
void ADC_DMAInit(void)
{
DMA_InitTypeDef DMA_InitStructure;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32) & (ADC1->ADDATA); //DMA transfer peripheral address
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADCValue; //DMA transfer memory address
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //DMA transfer direction from peripheral to memory
DMA_InitStructure.DMA_BufferSize = 2; //DMA cache size
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //After receiving the data, the peripheral address is forbidden to move backward
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //After receiving the data, the memory address is shifted backward
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //Define the peripheral data width to 16 bits
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //Define the memory data width to 16 bits
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //Cycle conversion mode
DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA priority is high
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //M2M mode is disabled
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
DMA_Cmd(DMA1_Channel1, ENABLE);
DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE); //DMA interrupt initialization
NVIC_InitStruct.NVIC_IRQChannel = DMA1_Channel1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
ADCTrigFilterflag = 0;
}
//ADCDMA中断处理
u32 measCount;
void DMA1_Channel1_IRQHandler(void)
{
// ADC_SoftwareStartConvCmd(ADC1, DISABLE); //Stop Conversion
DMA_ClearITPendingBit(DMA1_IT_TC1); //Clear interrupt flag
u16 chan = 0;
measCount++;
// ADC_SoftwareStartConvCmd(ADC1, ENABLE);
// ADCflag = 1; //Erected transmission complete flag
}
//72M时钟配置
void SetSysClockTo72_HSI(void)
{
unsigned char temp = 0;
unsigned int temp1 = 0;
RCC->CR |= RCC_CR_HSION;
while (!(RCC->CR & RCC_CR_HSIRDY))
;
RCC->CR |= (1 << 20);
RCC->CR &= ~(1 << 2);
RCC->CFGR = RCC_CFGR_PPRE1_2;
FLASH->ACR = FLASH_ACR_LATENCY_2 | FLASH_ACR_PRFTBE;
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
/* PCLK2 = HCLK PRE2 divide*/
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
/* PCLK1 = HCLK PRE1 divide */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1;
RCC->CFGR &= ~RCC_CFGR_SW;
temp1 = *(u16 *)0x1FFFF7FA;
if ((temp1 & 0xff) == 0xff) {
temp1 &= 0xff00;
} else {
temp1 &= 0xff;
temp1 <<= 8;
}
temp1 |= (RCC->CR & 0xFFFF00ff) | 0xf8;
RCC->CR = temp1;
RCC->CFGR |= RCC_CFGR_SW_HSI;
while (1) {
temp = RCC->CFGR;
temp = temp >> 2;
temp &= RCC_CFGR_SW;
if(temp == RCC_CFGR_SW_HSI)
break;
}
}
设置采样通道2个,通道采样时间在55.5周期以上,符合数据手册。但如果采样时间设置为13.5周期,却达不到111ksps,任何低于55.5周期的设置,都只能达到65ksps左右;或者ADC_PRESCARE设置为11及以下,提高ADC时钟,也都只能达到65ksps左右;请问瓶颈在哪儿?下面是ADC配置和时钟配置
//ADC配置,2个采样通道
void ADCMultiChannelInit(){
GPIO_Config_AIN(GPIOA, GPIO_Pin_1);
GPIO_Config_AIN(GPIOA, GPIO_Pin_3);
ADC_InitTypeDef ADC_InitStructure;
ADC_StructInit(&ADC_InitStructure);
//Initialize PA1 to analog input mode
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //Enable ADC clock
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_PRESCARE = ADC_PCLK2_PRESCARE_12; //ADC prescale factor
ADC_InitStructure.ADC_Mode = ADC_Mode_Continuous_Scan; //Set ADC mode to continuous conversion mode
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //AD data right-justified
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC, ADC_Channel_DisableAll, 0, ADC_SampleTime_13_5Cycles);//Block all channels
ADC_RegularChannelConfig(ADC1, ADCch1, 0, ADC_SampleTime_13_5Cycles);//Enable the channel
ADC_RegularChannelConfig(ADC1, ADCch2, 0, ADC_SampleTime_13_5Cycles);//Enable the channel
#ifdef ADC_USE_DMA
ADC_DMACmd(ADC1, ENABLE); //Enable ADCDMA
#else
ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE); //DMA interrupt initialization
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = ADC_COMP_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
#endif
ADC_Cmd(ADC1, ENABLE); //Enable AD conversion
}
//DMA配置
void ADC_DMAInit(void)
{
DMA_InitTypeDef DMA_InitStructure;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32) & (ADC1->ADDATA); //DMA transfer peripheral address
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADCValue; //DMA transfer memory address
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //DMA transfer direction from peripheral to memory
DMA_InitStructure.DMA_BufferSize = 2; //DMA cache size
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //After receiving the data, the peripheral address is forbidden to move backward
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //After receiving the data, the memory address is shifted backward
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //Define the peripheral data width to 16 bits
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //Define the memory data width to 16 bits
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //Cycle conversion mode
DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA priority is high
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //M2M mode is disabled
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
DMA_Cmd(DMA1_Channel1, ENABLE);
DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE); //DMA interrupt initialization
NVIC_InitStruct.NVIC_IRQChannel = DMA1_Channel1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
ADCTrigFilterflag = 0;
}
//ADCDMA中断处理
u32 measCount;
void DMA1_Channel1_IRQHandler(void)
{
// ADC_SoftwareStartConvCmd(ADC1, DISABLE); //Stop Conversion
DMA_ClearITPendingBit(DMA1_IT_TC1); //Clear interrupt flag
u16 chan = 0;
measCount++;
// ADC_SoftwareStartConvCmd(ADC1, ENABLE);
// ADCflag = 1; //Erected transmission complete flag
}
//72M时钟配置
void SetSysClockTo72_HSI(void)
{
unsigned char temp = 0;
unsigned int temp1 = 0;
RCC->CR |= RCC_CR_HSION;
while (!(RCC->CR & RCC_CR_HSIRDY))
;
RCC->CR |= (1 << 20);
RCC->CR &= ~(1 << 2);
RCC->CFGR = RCC_CFGR_PPRE1_2;
FLASH->ACR = FLASH_ACR_LATENCY_2 | FLASH_ACR_PRFTBE;
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
/* PCLK2 = HCLK PRE2 divide*/
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
/* PCLK1 = HCLK PRE1 divide */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1;
RCC->CFGR &= ~RCC_CFGR_SW;
temp1 = *(u16 *)0x1FFFF7FA;
if ((temp1 & 0xff) == 0xff) {
temp1 &= 0xff00;
} else {
temp1 &= 0xff;
temp1 <<= 8;
}
temp1 |= (RCC->CR & 0xFFFF00ff) | 0xf8;
RCC->CR = temp1;
RCC->CFGR |= RCC_CFGR_SW_HSI;
while (1) {
temp = RCC->CFGR;
temp = temp >> 2;
temp &= RCC_CFGR_SW;
if(temp == RCC_CFGR_SW_HSI)
break;
}
}
赞0
评论
2023-03-12
赞0
评论
2023-03-09
赞0
评论
2023-02-20
赞0
评论
2023-02-19
赞0
评论
2022-04-01
赞0
评论
2022-04-01
赞0
评论
2022-03-16
赞0
评论
2022-03-16
赞0
评论
2022-03-16
您需要登录后才可以回复 登录 | 注册