逻辑就是
- RCC开启要用的外设的时钟(GPIO和APIC)
- GPIO初始化,配置好GPIO,开漏输出
配置APIC(中断引脚选择):GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14);
此函数在GPIO里面,是来确定AFIO要哪条线和使用哪个GPIO的
配置EXTI:这也是用结构体去初始化
1.void EXTI_DeInit(void);
调用这个函数,就可以把EXTI的配置都清除,恢复成上电时默认的状态。
2.void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
调用这个函数,就可以根据这个结构体里的参数来配置EXTI外设,来初始化EXIT,使用方法和GPIO类似。
3.EXTI_Line,是选择配置的中断线,由于我们使用的是PB14,所以需要用到EXTI14中断线,共有20根中断线可以选择
4.EXTI_Mode,外部中断线的模式,有中断响应和事件响应两种,这里我们要让CPU执行中断,因此选择中断响应EXTI_Mode_Interrupt。
5.EXTI_Trigger,中断触发方式选择,有四种,分别是上升沿、下降沿、双边沿,因为之前的GPIO口是选的上拉模式,即没信号影响的时候那个口是高电平,那有信号来的就对应的是电平从高到低,即下降沿,因此我们这里选择下降沿触发EXTI_Trigger_Falling。
------------------------------------------------------------------------------------------------------------------------
2.void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line);
这个函数是用软件来触发外部中断的,调用这个函数,参数给一个指定的中断线,就能软件触发一次这个外部中断。
3.FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);
可以获取指定的标志位是否被置1了。
这个函数是用软件来触发外部中断的,调用这个函数,参数给一个指定的中断线,就能软件触发一次这个外部中断。
调用这个函数,可以把参数传递的结构体变量EXTI_InitStruct,赋一个默认值,
4.void EXTI_ClearFlag(uint32_t EXTI_Line);
可以对置1的标志位进行清除。
如果想在主程序查看和清除标志位,就用上面两个函数。
对于有些比较紧急的标志位,在置标志位后,会触发中断,在中断函数中,如果想查看标志位和清除标志位,那就用下面两个函数。
5.ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
获取中断标志位是否被置1。
6.void EXTI_ClearITPendingBit(uint32_t EXTI_Line);
清除中断挂起标志位。
其中Mode和Trigger都要搜索才能找到,在启动文件里面有其注释
NVIC(和内核相接,嵌套中断向量控制器):也是结构体去初始化
其中:IRQ(Interrupt Request)
1.选EXTI通道
2.开启通道
3.分配响应优先级和抢占优先级的程度
----------------------------------------------------------------------------------------------------------------------------
配置完毕之后
需要
用GetIT看看是否在EXTI通道14的寄存器被挂起(查看注释可知,如果挂起则输出SET,否则输出RESET),用if判断后再count++
记得在使用Get查看之后,要清除Clear这个位
——————————————————————————————————————
最后在主函数读取count即可
---———————————————————————————————————————————
代码如下:
#include "stm32f10x.h" // Device header
uint16_t CountSensor_Count;
void CountSensor_Init(void)
{//先用RCC开启AFIO和GPIOB的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
//初始化GPIOB
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
//初始化AFIO
//EXTI引脚选择配置,说明是在GPIOB上且是通道14
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14);
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_Line14; //要配置的中断线
EXTI_InitStructure.EXTI_LineCmd = ENABLE; //指定选择中断线的新状态
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //外部中断线的模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //选择下降沿触发,本来
EXTI_Init(&EXTI_InitStructure );
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; //选择指定通道
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //开启指定通道
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //给响应优先级分配优先级程度
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //给抢占优先级分配优先级程度
NVIC_Init(&NVIC_InitStructure);
}
uint16_t CountSensor_Get(void)
{
return CountSensor_Count;
}
void EXTI15_10_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line14)==SET)
{
CountSensor_Count++;
EXTI_ClearITPendingBit(EXTI_Line14);
}
}