同一时间,只能有一个IO口映射到中断线,例如,当PA0做了外部中断0时,PB0等就不能作为外部中断0了。

 main.c

#include "exti.h"

int main(void)
{
    delay_init();
    LedInit();
    Exti_Init();

    while(1)
    {

    }
}

led.c

#include"led.h"

void LedInit()
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOA,ENABLE); //使能PD/PA端口时钟
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //推挽输出
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;    //LED1-->PD.2 端口配置
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    //IO口速度为50MHz
    GPIO_Init(GPIOD, &GPIO_InitStructure); //初始化GPIOD.2
    LED1on;

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;    //LED0-->PA.8 端口配置
    GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOD.2
    LED0off;
}

led.h

#ifndef __LED_H
#define __LED_H

#include<stm32f10x.h>

#define LED1on GPIO_ResetBits(GPIOD,GPIO_Pin_2)
#define LED1off GPIO_SetBits(GPIOD,GPIO_Pin_2)
#define LED0on GPIO_ResetBits(GPIOA,GPIO_Pin_8)
#define LED0off GPIO_SetBits(GPIOA,GPIO_Pin_8)

#define LED0 PAout(8)// PA8
#define LED1 PDout(2)// PD2

void LedInit(void);


#endif

key.c

#include"key.h"

//按键初始化函数
void KEY_Init(void) //IO初始化
{
     GPIO_InitTypeDef GPIO_InitStructure;

     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC,ENABLE);//使能PORTA,PORTC时钟

    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_1|GPIO_Pin_13;//KEY0-KEY1
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入
     GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIOC1、13

    //初始化 WK_UP-->GPIOA.0      下拉输入
    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0设置成输入,默认下拉
    GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.0

}

unsigned char KEY_Scan(unsigned char mode)
{
    static u8 key_up=1;//按键按松开标志
    if(mode)key_up=1;  //支持连按
    if(key_up&&(KEY0==0||KEY1==0||WK_UP==1))
    {
        delay_ms(10);//去抖动
        key_up=0;
        if(KEY0==0)return KEY0_PRES;
        else if(KEY1==0)return KEY1_PRES;
        else if(WK_UP==1)return WKUP_PRES;
    }
    else if(KEY0==1&&KEY1==1&&WK_UP==0)
        key_up=1;
     return 0;// 无按键按下
}

key.h

#ifndef __KEY_H
#define __KEY_H

#include"sys.h"
#include"delay.h"

#define KEY0  GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_1)//读取按键0
#define KEY1  GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_13)//读取按键1

#define WK_UP   GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)//读取按键3(WK_UP)

#define KEY0_PRES     1    //KEY0按下
#define KEY1_PRES    2    //KEY1按下

#define WKUP_PRES   4    //KEY_UP按下(即WK_UP/KEY_UP)

void KEY_Init(void);//IO初始化
u8 KEY_Scan(u8 mode);

#endif

exti.c

#include "exti.h"

void Exti_Init()
{
//    GPIO_InitTypeDef GPIO_InitStructure;
    EXTI_InitTypeDef EXTI_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

//    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC,ENABLE);

//    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;
//    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
//    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
//    GPIO_Init(GPIOA,&GPIO_InitStructure);
//
//    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
//    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1|GPIO_Pin_13;
//    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
//    GPIO_Init(GPIOC,&GPIO_InitStructure);
    KEY_Init();

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//使能复用功能时钟

    //key0(PC1)中断线以及中断初始化配置 下降沿触发
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource1);

    EXTI_InitStructure.EXTI_Line=EXTI_Line1;
    EXTI_InitStructure.EXTI_LineCmd=ENABLE;
    EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
    EXTI_Init(&EXTI_InitStructure);

    //key1(PC13)中断线以及中断初始化配置 下降沿触发
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource13);

    EXTI_InitStructure.EXTI_Line=EXTI_Line13;
    EXTI_Init(&EXTI_InitStructure);

    //WK_UP(PA0)中断线以及中断初始化配置 上升沿触发
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);

    EXTI_InitStructure.EXTI_Line=EXTI_Line0;
    EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising;
    EXTI_Init(&EXTI_InitStructure);


    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    //key0(PC1)所在外部中断通道1
    NVIC_InitStructure.NVIC_IRQChannel=EXTI1_IRQn;//stm32f10x.h
    NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;
    NVIC_Init(&NVIC_InitStructure);

    //key1(PC13)所在外部中断通道10~15
    NVIC_InitStructure.NVIC_IRQChannel=EXTI15_10_IRQn;//stm32f10x.h
    NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
    NVIC_Init(&NVIC_InitStructure);

    //WK_UP(PA0)所在外部中断通道0
    NVIC_InitStructure.NVIC_IRQChannel=EXTI0_IRQn;//stm32f10x.h
    NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
    NVIC_Init(&NVIC_InitStructure);

}

void EXTI1_IRQHandler()
{
    delay_ms(10);
    if(KEY0==0)
    {
        LED0=!LED0;
    }
    EXTI_ClearITPendingBit(EXTI_Line1);
}


void EXTI15_10_IRQHandler()
{
    //正点原子加了判断,但可以不用加判断,
//    delay_ms(10);
//    if(KEY1==0)
//    {
        LED1=!LED1;
//    }
    EXTI_ClearITPendingBit(EXTI_Line13);
}

void EXTI0_IRQHandler()
{
    delay_ms(10);
    if(WK_UP==1)
    {
        LED0=!LED0;
        LED1=!LED1;
    }
    EXTI_ClearITPendingBit(EXTI_Line0);
}

exti.h

#ifndef __exti_H
#define __exti_H
#include "delay.h"
#include "key.h"
#include "led.h"

void Exti_Init(void);

#endif