1.原理图 2.代码 #include <windows.h> #include <types.h> #include <ceddk.h> #include <memory.h> #include <nkintr.h> #include <pegdpar.h> #include <ddkreg.h> #include <Winuser.h> #include "matrixkey.h" #include "Oal_timer.h" #include "at91_pio.h" // Controller includes #include "at91sam9263_gpio.h" #include "AT91SAM9263_oal_intr.h" #include "atmel_oal_ioctl.h" static HANDLE m_hMute; static BYTE Virtualkey0=VK_NUMPAD0; static HANDLE m_hevInterrupt0; static HANDLE gintThread0; static DWORD g_dwSysIntrToIrq0 = SYSINTR_UNDEFINED; static BYTE Virtualkey1=VK_NUMPAD0; static HANDLE m_hevInterrupt1; static HANDLE gintThread1; static DWORD g_dwSysIntrToIrq1 = SYSINTR_UNDEFINED; static BYTE Virtualkey2=VK_NUMPAD0; static HANDLE m_hevInterrupt2; static HANDLE gintThread2; static DWORD g_dwSysIntrToIrq2 = SYSINTR_UNDEFINED; static BYTE Virtualkey3=VK_NUMPAD0; static HANDLE m_hevInterrupt3; static HANDLE gintThread3; static DWORD g_dwSysIntrToIrq3 = SYSINTR_UNDEFINED; static BYTE Virtualkey4=VK_NUMPAD0; static HANDLE m_hevInterrupt4; static HANDLE gintThread4; static DWORD g_dwSysIntrToIrq4 = SYSINTR_UNDEFINED; static BYTE Virtualkey5=VK_NUMPAD0; static HANDLE m_hevInterrupt5; static HANDLE gintThread5; static DWORD g_dwSysIntrToIrq5 = SYSINTR_UNDEFINED; static BYTE int9keyup=0; static void loopn(UINT32 wCount) { volatile unsigned int i, k,j=0; for (k=0; k<wCount; k++) for(i=0;i < 100; i++) { j++; } //400n } static DWORD KeyPadLock() { DWORD dwStatus; dwStatus = WaitForSingleObject(m_hMute, INFINITE); if(dwStatus == WAIT_OBJECT_0) { dwStatus = ERROR_SUCCESS; } else { dwStatus = GetLastError(); } return dwStatus; } static DWORD KeyPadUnLock() { DWORD dwStatus = ERROR_SUCCESS; BOOL fOk; fOk = ReleaseMutex(m_hMute); if(!fOk) { dwStatus = GetLastError(); } return dwStatus; } // 中断脚输入为低则返回TRUE,否则返回FALSE static BOOL IsIntPortLow(unsigned IrqNumber) { int result; result=pio_get_value(IrqNumber); if(result) return FALSE; else return TRUE; } // 中断脚输入是否稳定,稳定则返回TRUE,否则返回FALSE static BOOL IsIntPortStable(unsigned IrqNumber) { int i; int pre,now; KeyPadLock(); pre=pio_get_value(IrqNumber); for(i=0;i<3;i++) { Sleep(3); now=pio_get_value(IrqNumber); if(pre!=now) { KeyPadUnLock(); return FALSE; } } KeyPadUnLock(); return TRUE; } //所有输出管脚输出高电平 void alloutpinhigh(void) { pio_set_value(AT91C_PIN_PB(22), 1); pio_set_value(AT91C_PIN_PB(23), 1); pio_set_value(AT91C_PIN_PB(24), 1); pio_set_value(AT91C_PIN_PB(25), 1); pio_set_value(AT91C_PIN_PB(26), 1); pio_set_value(AT91C_PIN_PB(27), 1); } //所有输出管脚输出低电平 void alloutpinlow(void) { pio_set_value(AT91C_PIN_PB(22), 0); pio_set_value(AT91C_PIN_PB(23), 0); pio_set_value(AT91C_PIN_PB(24), 0); pio_set_value(AT91C_PIN_PB(25), 0); pio_set_value(AT91C_PIN_PB(26), 0); pio_set_value(AT91C_PIN_PB(27), 0); } #define ENTRY_POWEROFF 0x2 #define ENTRY_NULL 0x0 #define poweroff_counter 1300 #define wait_cnt 100 INT WINAPI Int0_Thread(void) { DWORD result; BYTE i; static int count=0; while(1) { result=WaitForSingleObject(m_hevInterrupt0, INFINITE); switch(result) { case WAIT_OBJECT_0: const struct pio_desc hw_pio[] = { {"INT0", AT91C_PIN_PB(6), 0, PIO_PULLUP, PIO_INPUT}, NULL, }; pio_setup(hw_pio, sizeof(hw_pio)/sizeof(struct pio_desc)); // 消除按键抖动 if(!IsIntPortStable(AT91C_PIN_PB(6))) { InterruptDone(g_dwSysIntrToIrq0); break; } // 中断输入是高电平,说明按键弹起 if(pio_get_value(AT91C_PIN_PB(6))) { keybd_event(Virtualkey0,0, KEYEVENTF_EXTENDEDKEY|KEYEVENTF_KEYUP, 0); RETAILMSG(1,(TEXT("Virtualkey0=%d up/r/n"),Virtualkey0)); } // 否则,轮询输出低电平, else { // 输出管脚全部输出高 alloutpinhigh(); for(i=0;i<6;i++) { pio_set_value(AT91C_PIN_PB(22)+i, 0); Sleep(3); while(!pio_get_value(AT91C_PIN_PB(6)) ) {