上图是STM32F10XX参考手册中的外部中断/事件控制图;通过对上图的阅读,以及查阅参考手册,并没有说明事件和中断不能同时使用。
使用事件前提是改硬件外设支持由事件触发,不然使用不了事件
上图是ADC选择启动规则通道组转换的外部事件,要验证事件和中断可以同时使用,所以要使用110:EXTI11中断线。
void Init(){//中断和事件同时使用
GPIO_InitTypeDef GPIO_init;
EXTI_InitTypeDef EXTI_inti;
NVIC_InitTypeDef NVIC_Initstructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO , ENABLE);
GPIO_init.GPIO_Pin=GPIO_Pin_5;
GPIO_init.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_Init(GPIOE,&GPIO_init);
GPIO_init.GPIO_Pin=GPIO_Pin_4;
GPIO_init.GPIO_Mode=GPIO_Mode_IPU;
GPIO_Init(GPIOE,&GPIO_init);
GPIO_init.GPIO_Pin=GPIO_Pin_11;
GPIO_init.GPIO_Mode=GPIO_Mode_IPU;
GPIO_Init(GPIOE,&GPIO_init);
//选择EXTI的GPIO引脚
GPIO_EXTILineConfig (GPIO_PortSourceGPIOE ,GPIO_PinSource11);
EXTI_inti.EXTI_Line=EXTI_Line11;
EXTI_inti.EXTI_Mode=EXTI_Mode_Interrupt;//中断
EXTI_inti.EXTI_Trigger=EXTI_Trigger_Falling;//下降沿触发
EXTI_inti.EXTI_LineCmd=ENABLE;
EXTI_Init(&EXTI_inti);
EXTI_inti.EXTI_Line=EXTI_Line11;
// EXTI_inti.EXTI_Mode=EXTI_Mode_Event;//事件
EXTI->EMR |=(1<<11);//需要单独操作事件屏蔽寄存器
EXTI_inti.EXTI_Trigger=EXTI_Trigger_Rising;//上升沿触发
EXTI_inti.EXTI_LineCmd=ENABLE;
EXTI_Init(&EXTI_inti);
#ifdef VECT_TAB_RAM
/* Set the Vector Table base location at 0x20000000 */
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); //分配中断向量表
#else /* VECT_TAB_FLASH */
/* Set the Vector Table base location at 0x08000000 */
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endif
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //配置抢占优先级和响应优先级
NVIC_Initstructure.NVIC_IRQChannel =EXTI15_10_IRQn;//指定EXTI的通道
NVIC_Initstructure.NVIC_IRQChannelPreemptionPriority =0;//指定为抢占优先级
NVIC_Initstructure.NVIC_IRQChannelSubPriority =0; //指定为响应优先级
NVIC_Initstructure.NVIC_IRQChannelCmd =ENABLE ;//指定通道状态
NVIC_Init(&NVIC_Initstructure );
}
在将事件和中断同时配置时,一个用 标准库定义模式时,另一个要用操作寄存器来开启中断或者事件屏蔽寄存器。不然只能使用一个,我只验证了在我这个项目中。
void ADC_init(){
ADC_InitTypeDef ADC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 , ENABLE ); //使能GPIOA,ADC1通道时钟
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
// rRCC_CFGR |=2<<14;//配置为6分频,adc为12MHZ
// ADC_RegularChannelConfig(ADC1,ADC_Channel_16,1,ADC_SampleTime_239Cycles5);//采样率
ADC_DeInit(ADC1);
ADC_InitStructure.ADC_ContinuousConvMode= DISABLE;//ENABLE连续转换模式,DISABLE独立
ADC_InitStructure.ADC_DataAlign= ADC_DataAlign_Right; //ADC数据右对齐
// ADC_InitStructure.ADC_ExternalTrigConv= ADC_ExternalTrigConv_None;//由软件启动
ADC_InitStructure.ADC_ExternalTrigConv= ADC_ExternalTrigConv_Ext_IT11_TIM8_TRGO;//由外部中断11事件启动
ADC_InitStructure.ADC_Mode= ADC_Mode_Independent;//独立模式
ADC_InitStructure.ADC_NbrOfChannel= 1;
ADC_InitStructure.ADC_ScanConvMode= DISABLE;//单通道
ADC_Init(ADC1, &ADC_InitStructure);
ADC_TempSensorVrefintCmd(ENABLE); //开启内部温度传感器
ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1
delay_us(5);//上电延迟一段时间再次上电
ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1
ADC_ResetCalibration(ADC1);//复位校准
while(ADC_GetResetCalibrationStatus(ADC1));//等待复位校准
ADC_StartCalibration(ADC1);//开始校准
while(ADC_GetCalibrationStatus(ADC1));//等待校准完成
// ADC_SoftwareStartConvCmd(ADC1,ENABLE);//开始转换
}
ADC触发方式要改成外部事件触发。
我使用的开发板是正点原子的STM32F103ZET6的开发板