typedef struct
{
GPIO_TypeDef* GPIOX;
uint16_t GPIO_Pin;
} KGPT[2][6]; //6*4
KGPT KPIN= {
{{GPIOA,GPIO_Pin_0},{GPIOA,GPIO_Pin_1}, {GPIOA,GPIO_Pin_2},{GPIOA,GPIO_Pin_3},{GPIOA,GPIO_Pin_4},{GPIOA,GPIO_Pin_5}}, //行
{{GPIOA,GPIO_Pin_6},{GPIOA,GPIO_Pin_7}, {GPIOB,GPIO_Pin_0},{GPIOB,GPIO_Pin_1}} //列
};
u8 i=0;
GPIO_InitTypeDef GPIO_InitStructure;
void KEYPAD_INIT (void) { //按鍵中斷初始化
NVIC_InitTypeDef NVIC_InitStruct; //定義結構體變數
EXTI_InitTypeDef EXTI_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE); //啟動GPIO時鐘 (需要與復用時鐘一同啟動)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //配置埠中斷需要啟用復用時鐘
for(i=0; i<6; i++)
{
GPIO_InitStructure.GPIO_Pin = KPIN[0][i].GPIO_Pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽輸出
GPIO_Init(KPIN[0][i].GPIOX, &GPIO_InitStructure);//初始化row
GPIO_SetBits(KPIN[0][i].GPIOX,KPIN[0][i].GPIO_Pin);//行設定為高電平
}
for(i=0; i<4; i++)
{
GPIO_InitStructure.GPIO_Pin = KPIN[1][i].GPIO_Pin;//PC5
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPU; //GPIO_Mode_Out_PP ; //設定成推挽輸出
GPIO_Init(KPIN[1][i].GPIOX, &GPIO_InitStructure);//初始化col
GPIO_ResetBits(KPIN[1][i].GPIOX,KPIN[1][i].GPIO_Pin);//列設定為低電平
}
//第1個中斷
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource6); //定義 GPIO 中斷
EXTI_InitStruct.EXTI_Line=EXTI_Line6; //定義中斷線
EXTI_InitStruct.EXTI_LineCmd=ENABLE; //中斷使能
EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt; //中斷模式為 中斷
EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Rising; //上升沿觸發
EXTI_Init(& EXTI_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel=EXTI9_5_IRQn; //中斷線
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE; //使能中斷
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2; //搶占優先級 2
NVIC_InitStruct.NVIC_IRQChannelSubPriority=2; //子優先級 2
NVIC_Init(& NVIC_InitStruct);
//第2個中斷
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource7); //定義 GPIO 中斷
EXTI_InitStruct.EXTI_Line=EXTI_Line7; //定義中斷線
EXTI_InitStruct.EXTI_LineCmd=ENABLE; //中斷使能
EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt; //中斷模式為 中斷
EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Rising; //上升沿觸發
EXTI_Init(& EXTI_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel=EXTI9_5_IRQn; //中斷線
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE; //使能中斷
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2; //搶占優先級 2
NVIC_InitStruct.NVIC_IRQChannelSubPriority=2; //子優先級 2
NVIC_Init(& NVIC_InitStruct);
//第3個中斷
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0); //定義 GPIO 中斷
EXTI_InitStruct.EXTI_Line=EXTI_Line0; //定義中斷線
EXTI_InitStruct.EXTI_LineCmd=ENABLE; //中斷使能
EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt; //中斷模式為 中斷
EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Rising; //上升沿觸發
EXTI_Init(& EXTI_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel=EXTI0_IRQn; //中斷線
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE; //使能中斷
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2; //搶占優先級 2
NVIC_InitStruct.NVIC_IRQChannelSubPriority=2; //子優先級 2
NVIC_Init(& NVIC_InitStruct);
//第4個中斷
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1); //定義 GPIO 中斷
EXTI_InitStruct.EXTI_Line=EXTI_Line1; //定義中斷線
EXTI_InitStruct.EXTI_LineCmd=ENABLE; //中斷使 能
EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt; //中斷模式為 中斷
EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Rising; //上升沿觸發
EXTI_Init(& EXTI_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel=EXTI1_IRQn; //中斷線
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE; //使能中斷
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2; //搶占優先級 2
NVIC_InitStruct.NVIC_IRQChannelSubPriority=2; //子優先級 2
NVIC_Init(& NVIC_InitStruct);
EXTI_ClearITPendingBit(EXTI_Line0);
EXTI_ClearITPendingBit(EXTI_Line1);
EXTI_ClearITPendingBit(EXTI_Line6);
EXTI_ClearITPendingBit(EXTI_Line17);
}
void EXTI0_IRQHandler(void) {
if(EXTI_GetITStatus(EXTI_Line0)!=RESET) { //判斷某個線上的中斷是否發生
for(i = 0; i<6; i++) {
GPIO_ResetBits(KPIN[1][i].GPIOX,KPIN[1][i].GPIO_Pin);
if(!(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)))
delay_us(20);//消抖延時
if(!(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)))
number=(i*4+1);//回傳的資料 為1-16 對應4x4鍵盤的16個鍵
}
EXTI_ClearITPendingBit(EXTI_Line0); //清除 LINE 上的中斷標志位
}
}
程式運行后 按下一個按鍵 中斷中回圈6次 每次都能獲得number值 ,大神 問題出在哪里?
uj5u.com熱心網友回復:
delay時間通常是ms級別(5ms),20us的delay太少。還有,盡量不要在中斷中識別按鍵,除非按鍵有去抖動處理,否則效率低,而且容易多識別。uj5u.com熱心網友回復:
不要用IO中斷去捕捉按鍵的變化,很多干擾信號會影響你判斷的。簡單的方法:開個20ms的定時器,定時檢測按鍵的狀態。
uj5u.com熱心網友回復:
定時和濾波https://mp.csdn.net/postedit/91462991
uj5u.com熱心網友回復:
不好意思,上面地址寫錯了,應該是https://blog.csdn.net/hhhh63/article/details/91462991
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/95705.html
標籤:單片機/工控
上一篇:串口資料傳輸過快時,接收資料出現“卡頓”情況,有遇到過類似情況麻煩給下建議
下一篇:1
