使用芯片stm32f103c8t6 ADC采样配置如下: void ADC_Conf(void) { ADC_InitTypeDef ADC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); GPIO_StructInit(&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOA, &GPIO_InitStructure); ADC_DeInit(ADC1); ADC_StructInit(&ADC_InitStructure); ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T4_CC4; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Left; ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_Init(ADC1, &ADC_InitStructure); ADC_RegularChannelConfig(ADC1, ADC_Channel_2,1,ADC_SampleTime_13Cycles5); NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; // AD中断优先级最高 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); ADC_ClearFlag(ADC1, ADC_FLAG_EOC); ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE); ADC_ExternalTrigConvCmd(ADC1, ENABLE); ADC_Cmd(ADC1, ENABLE); } AD中断服务函数如下: void ADC1_2_IRQHandler(void) { if (ADC1->SR & 0x02) { ADC1->SR = ~(uint32_t)0x02; adc.adc_samples[0] = _IQ16toIQ(ADC_GetConversionValue(ADC1)); } } 问题: 从发生中断到进入中断服务函数时间过长(不计算中断执行时间),大概在6us左右。 请问各位大神,有没有办法把这个进入时间缩短到2us左右。 |
我这边程序里面AD采样时钟为12M
RCC_HCLKConfig(RCC_SYSCLK_Div1); // AHB 72M
RCC_PCLK2Config(RCC_HCLK_Div1); // APB2 72M
RCC_PCLK1Config(RCC_HCLK_Div2); // APB1 36M
RCC_ADCCLKConfig(RCC_PCLK2_Div6); // ADC 12M
11.6 Channel-by-channel programmable sample time
ADC samples the input voltage for a number of ADC_CLK cycles which can be modified using
the SMP[2:0] bits in the ADC_SMPR1 and ADC_SMPR2 registers. Each channel can be
sampled with a different sample time.
The total conversion time is calculated as follows:
Tconv = Sampling time + 12.5 cycles
Example:
With an ADCCLK = 14 MHz and a sampling time of 1.5 cycles:
Tconv = 1.5 + 12.5 = 14 cycles = 1 μs
按照11.6计算的话:
Tconv = 13.5 + 12.5 = 26 cycles = 2.17us
这里还有其他什么原因吗?
if (ADC_GetITStatus(ADC1, ADC_IT_EOC) == SET) 占用了较长时间,后面估计要改成汇编了
谢谢各位
if (ADC_GetITStatus(ADC1, ADC_IT_EOC) == SET) //if (ADC1->SR & 0x02)
{
GPIO_SetBits(GPIOB, GPIO_Pin_5);
ADC_ClearITPendingBit(ADC1, ADC_IT_EOC);
}
先确认了是哪儿的问题才想解决方案吧, 除非你有N个中断在ADC中断前发生了, 否则中断的响应时间是不可能是几个us的
所以我觉得是转换时间的问题
评分
查看全部评分
评分
查看全部评分
评分
查看全部评分
评分
查看全部评分
评分
查看全部评分
使用定时器计数并计算的。每次TIM4计数到CCR4的时候触发中断,而进入中断后TIM4的CNT值比CCR4增加了200左右,定时器的时钟为36M。
通过改变NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 不过没有明显效果。
本方案中不能采用DMA,以后该中断函数中还有其他的命令执行。
你的MCU正在执行其他程序,此时中断发生,MCU需要判断此中断以及优先级,然后保护现场进行压栈,然后取中断服务程序地址,还有hclk速率不要分频这会影响存储速度,同样增加时间,你想想从哪里能够省下时间?
评分
查看全部评分
启动ADC转换拉一个IO高 ,进入ADC中断后再拉低,看脉冲宽度。
评分
查看全部评分
to @edmundlee
软件中循环输出GPIO,用逻辑分析仪测试发现大概需要2.45us,和理论计算2.17us有一点差距。
使用中断方式发现从触发到进入中断需要3.48us