新手上路
- 积分
- 31
- 金钱
- 31
- 注册时间
- 2018-2-10
- 在线时间
- 10 小时
|
1金钱
本帖最后由 qiaoqiao001 于 2018-2-10 23:01 编辑
主频设置为56M
ADC设置为4分频14M
采样周期设置为ADC_SampleTime_1Cycles5,手册说是1us
不管是中断方式还是在主循环查询中断标志,清除标志后只能执行1条指令就又再次中断
1us的时间只能执行几个指令?
如果按官方的算法,平均每指令周期=1000000000ns/(56000000*1.25)=14.28ns
1us大约能执行70条执行
慢了10倍。。。。。
两种方式的代码贴出来,各位大神给看看验证一下,是我配置错误还是就这么慢
PC15接了个LED灯
注释掉:ADC_ConversionValue = (uint16_t)ADC1->DR;灯就灭了
不注释灯是亮的
中断方式:
[mw_shl_code=c,true]#include "stm32f10x.h"
uint16_t ADC_ConversionValue=0;
uint16_t ADC_num=0;
void ADC1_init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
/*配置ADC时钟,为PCLK2的4分频,即56/4=14MHz,ADC1在APB2上为56M*/
RCC_ADCCLKConfig(RCC_PCLK2_Div4);
/* Enable ADC1 and GPIOC clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE);
//中断优先级NVIC设置
NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn; //ADC1_2中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级0级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器
/* Configure PC.01 as analog input */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOC, &GPIO_InitStructure);// PC1,输入时不用设置速率
/* ADC1 configuration */
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//独立ADC模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE;//禁止扫描模式,扫描模式用于多通道采集
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//开启连续转换模式,即不停地进行ADC转换
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//不使用外部触发转换
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//采集数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1;//要转换的通道数目1
ADC_Init(ADC1, &ADC_InitStructure);
/*配置ADC1的通道11为1.5个采样周期共14个周期1.17us,序列为1 */
ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_1Cycles5);
//ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_7Cycles5);
//ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_13Cycles5);
//ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_28Cycles5);
//ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_41Cycles5);
//ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_239Cycles5);
/* Enable EOC interrupt */
ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/*复位校准寄存器 */
ADC_ResetCalibration(ADC1);
/*等待校准寄存器复位完成 */
while(ADC_GetResetCalibrationStatus(ADC1));
/* ADC校准 */
ADC_StartCalibration(ADC1);
/* 等待校准完成*/
while(ADC_GetCalibrationStatus(ADC1));
/* 由于没有采用外部触发,所以使用软件触发ADC转换 */
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
int main(void)
{
GPIO_InitTypeDef GPIO_Initstructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
GPIO_Initstructure.GPIO_Pin=GPIO_Pin_15;//PC15
GPIO_Initstructure.GPIO_Mode=GPIO_Mode_Out_PP; //普通推挽输出
GPIO_Initstructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIO_Initstructure);//最后初始化
GPIOC->BRR = GPIO_Pin_15;
ADC1_init();
while (1)
{
ADC_num++;
ADC_num--;
}
}
//ADC1_2中断服务程序
void ADC1_2_IRQHandler(void)
{
if(ADC1->SR & ADC_FLAG_EOC) //检查ADC1EOC中断发生与否
{
ADC1->SR = ~(uint32_t)ADC_FLAG_EOC; //操作寄存器清除ADC1EOC中断标志
ADC_ConversionValue = (uint16_t)ADC1->DR;
if(ADC1->SR & ADC_FLAG_EOC)
{
GPIOC->BSRR = GPIO_Pin_15;
}
else
{
GPIOC->BRR = GPIO_Pin_15;
}
}
}[/mw_shl_code]
主循环查询方式:
[mw_shl_code=c,true]#include "stm32f10x.h"
uint16_t ADC_ConversionValue=0;
void ADC1_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
/*配置ADC时钟,为PCLK2的4分频,即56/4=14MHz,ADC1在APB2上为56M*/
RCC_ADCCLKConfig(RCC_PCLK2_Div4);
/* Enable ADC1 and GPIOC clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE);
/* Configure PC.01 as analog input */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOC, &GPIO_InitStructure);// PC1,输入时不用设置速率
/* ADC1 configuration */
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//独立ADC模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE;//禁止扫描模式,扫描模式用于多通道采集
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//开启连续转换模式,即不停地进行ADC转换
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//不使用外部触发转换
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//采集数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1;//要转换的通道数目1
ADC_Init(ADC1, &ADC_InitStructure);
/*配置ADC1的通道11为1.5个采样周期共14个周期1.17us,序列为1 */
ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_1Cycles5);
//ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_7Cycles5);
//ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_13Cycles5);
//ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_28Cycles5);
//ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_41Cycles5);
//ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_239Cycles5);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/*复位校准寄存器 */
ADC_ResetCalibration(ADC1);
/*等待校准寄存器复位完成 */
while(ADC_GetResetCalibrationStatus(ADC1));
/* ADC校准 */
ADC_StartCalibration(ADC1);
/* 等待校准完成*/
while(ADC_GetCalibrationStatus(ADC1));
/* 由于没有采用外部触发,所以使用软件触发ADC转换 */
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
int main(void)
{
GPIO_InitTypeDef GPIO_Initstructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
GPIO_Initstructure.GPIO_Pin=GPIO_Pin_15;//PC15
GPIO_Initstructure.GPIO_Mode=GPIO_Mode_Out_PP; //普通推挽输出
GPIO_Initstructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIO_Initstructure);//最后初始化
GPIOC->BRR = GPIO_Pin_15;
ADC1_init();
while (1)
{
if(ADC1->SR & ADC_FLAG_EOC) //检查ADC1EOC中断发生与否
{
ADC1->SR = ~(uint32_t)ADC_FLAG_EOC; //操作寄存器清除ADC1EOC中断标志
ADC_ConversionValue = (uint16_t)ADC1->DR;
if(ADC1->SR & ADC_FLAG_EOC)
{
GPIOC->BSRR = GPIO_Pin_15;
}
else
{
GPIOC->BRR = GPIO_Pin_15;
}
}
}
}
[/mw_shl_code]
|
最佳答案
查看完整内容[请看2#楼]
CPU执行中断时需要时间的,入栈,出栈,以及其他处理,都需要时间!
STM32的中断性能,不超过500Khz,也就是当你的中断速度达到2us一次的时候,基本上CPU就不要干其他什么事情了(不管你中断函数多精简),所以你的验证方法,是不可取的。
官方说的1.25DMIPS/MHz,是通过测试一些算法来实现的,而不是测试中断服务速度。
|