1、STM32 EXTI的每一個GPIO口都可以配置成EXTI中斷線,但是配置時需要進行“一一配置”:
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource6);
EXTI_InitStructure.EXTI_Line = EXTI_IMR_MR6;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource7);
EXTI_InitStructure.EXTI_Line = EXTI_IMR_MR7;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
如果上述配置變成:
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource6|GPIO_PinSource7);
EXTI_InitStructure.EXTI_Line = EXTI_IMR_MR6|EXTI_IMR_MR7;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
中斷則無法進入。原因暫不知。
2、定義EXTI中斷後,爲了避免類似按鍵的“抖動”,可以在中斷檢測後加入電平檢測,當設置成上升沿&下降沿觸發時就可以判斷出是哪一個觸發,而且通過延時可以有效的避免“抖動”。如下:
if (PC_HDMI1_PLUT_IN()==1)
{
DelayXms(100);
if (PC_HDMI1_PLUT_IN()==1)
{
PC_HDMI_VGA_PREVIOUS_SUB_CMD = PC_HDMI_VGA_IN_SUB_CMD;
PC_HDMI_VGA_IN_SUB_CMD = 0x01;
SEND_STATE = 0X01;
}
}
else if (PC_HDMI1_PLUT_IN()==0)
{
DelayXms(100);
if (PC_HDMI1_PLUT_IN()==0)
{
PC_HDMI_VGA_IN_SUB_CMD = PC_HDMI_VGA_PREVIOUS_SUB_CMD;
SEND_STATE = 0X01;
}
}
函數PC_HDMI1_PLUT_IN()的功能爲讀取中斷線引腳電平,通過電平檢測,可以判斷上升沿還是下降沿。
3、如果定義了EXTI中斷後,又定義了一個優先級更高的中斷。那麼該中斷務必要編寫中斷服務程序,否則,高優先級的中斷無法退出,其餘中斷功能無法正常使用。
規則:如果定義了某一箇中斷,但是沒有使用該中斷的話,最好將其關閉,否則會產生不可預知的問題。
以上規則需要注意的是,假如使用串口中斷,僅僅關閉中斷即可,若是需要調用USART1_SendByte()函數,則USART1的使能需要置爲ENABLE,否則也會發生不可預知的問題。
4、小型按鍵的兩端 不一定 並聯電容(10uF);但是大型的按鍵/開關兩端 一定 要並聯10UF電容;
5、參考代碼:
#define KEY4_Status GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_6)
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStructure);
EXTI_ClearITPendingBit(EXTI_Line6);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource6);
key_exti.EXTI_Line=EXTI_Line6;
key_exti.EXTI_Mode=EXTI_Mode_Interrupt;
key_exti.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
key_exti.EXTI_LineCmd= ENABLE;
EXTI_Init(&key_exti);
key_nvic.NVIC_IRQChannel = EXTI9_5_IRQChannel;
key_nvic.NVIC_IRQChannelPreemptionPriority =1;
key_nvic.NVIC_IRQChannelSubPriority =1;
key_nvic.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&key_nvic);
void EXTI9_5_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line6)!=RESET)
{
delay_ms(20);
if(KEY4_Status == 1)
{
delay_ms(10);
while(!KEY4_Status);
KEY_Staus=0x04;
}
if(KEY4_Status == 0)
{
delay_ms(10);
while(KEY4_Status);
KEY_Staus=0x03;
}
EXTI_ClearITPendingBit(EXTI_Line6);
}
}