S3C2440 I/O口與按鍵中斷
阿新 • • 發佈:2019-01-12
S3C2440,仍然從最簡單的IO口開始,不過加上IO中斷,用於按鍵控制,
不再使用庫函式,而是直接呼叫暫存器,暫存器對映見我的另外一篇文章
https://blog.csdn.net/pxy198831/article/details/86025258 S3C2440暫存器對映表
/****************************** *檔名:key.c *功能: 按鍵程式 *建立者: 潘星宇 *最後修改:2013.03.26 *備註: * *******************************/ #include "key.h" #include "touch.h" /************************************************** *函式名: get_bit_port_g * *功能: 獲取I/O口G對應位的狀態 * *出口引數:對應位的狀態 * *入口引數:想要獲取狀態的位號 * *備註: * * *************************************************/ int get_bit_port_f (char port_bit) { int temp_data; //臨時變數 temp_data = rGPFDAT; //獲取埠G的資料 temp_data = temp_data >> port_bit; //將需要獲取狀態的位右移至第0位 temp_data &= 0x0001; //將其餘位清零 return (temp_data); } int get_bit_port_g (char port_bit) { int temp_data; //臨時變數 temp_data = rGPGDAT; //獲取埠G的資料 temp_data = temp_data >> port_bit; //將需要獲取狀態的位右移至第0位 temp_data &= 0x0001; //將其餘位清零 return (temp_data); } /************************************************************************** ***** 函式名: EINT0_callback ***** 功能: 外部中斷0回撥函式 ***** 引數: 無 ***** 返回值: 無 ***** 建立者: 潘星宇 ***** 建立時間:2017-4-25 ***** 最後更新: 2017-4-25 ****************************************************************************/ void EINT0_callback(void) __irq { ClearPending(BIT_EINT0); if (get_bit_port_f(0) == 0) { delay(200); if (get_bit_port_f(0) == 0) { if(function_flag == 1) { function_flag = 4; } else { } } } } /************************************************************************** ***** 函式名: EINT1_callback ***** 功能: 外部中斷1回撥函式 ***** 引數: 無 ***** 返回值: 無 ***** 建立者: 潘星宇 ***** 建立時間:2017-4-25 ***** 最後更新: 2017-4-25 ****************************************************************************/ void EINT1_callback(void) __irq { ClearPending(BIT_EINT1); if (get_bit_port_f(1) == 0) { delay(200); if (get_bit_port_f(1) == 0) { if(function_flag == 1) { function_flag = 5; } else { } } } } /************************************************************************** ***** 函式名: EINT2_callback ***** 功能: 外部中斷2回撥函式 ***** 引數: 無 ***** 返回值: 無 ***** 建立者: 潘星宇 ***** 建立時間:2013-1-19 ***** 最後更新: 2013-1-19 ****************************************************************************/ void EINT2_callback(void) __irq { ClearPending(BIT_EINT2); if (get_bit_port_f(2) == 0) { delay(200); if (get_bit_port_f(2) == 0) { if(function_flag == 0) { function_flag = 1; } else if (function_flag == 1) { function_flag = 20; } else if ((function_flag == 3)||(function_flag == 4)||(function_flag == 5)) { function_flag = 1; } else { } } } } /************************************************************************** ***** 函式名: EINT4_7_callback ***** 功能: 外部中斷4回撥函式 ***** 引數: 無 ***** 返回值: 無 ***** 建立者: 潘星宇 ***** 建立時間:2017-4-25 ***** 最後更新: 2017-4-25 ****************************************************************************/ void EINT4_7_callback(void) __irq { ClearPending(BIT_EINT4_7); rEINTPEND=(1<<4); // 清中斷掛起,否則將一直中斷 if (get_bit_port_f(4) == 0) { delay(200); if (get_bit_port_f(4) == 0) { if(function_flag == 1) { function_flag = 3; } else { } } } } void EINT8_23_callback(void) __irq { ClearPending(BIT_EINT8_23); rEINTPEND=(1<<8); // 清中斷掛起,否則將一直中斷 if (get_bit_port_g(0) == 1) { delay(200); if ((get_bit_port_g(0) == 1)&(red_bell_on == 1)) { rGPBDAT &= ~0x1e0; rGPBCON |=0x01; rGPBDAT |= 0x1; } } else if (get_bit_port_g(0) == 0) { delay(200); if (get_bit_port_g(0) == 0) { rGPBDAT |= 0x1e0; rGPBDAT &= 0x1e0; } } // if (get_bit_port_g(14) == 0) // { // delay(200); // if (get_bit_port_g(14) == 0) // { // } // } } /************************************************************************** ***** 函式名: INT_initialize_key ***** 功能: 初始化按鍵中斷 ***** 引數: 無 ***** 返回值: 無 ***** 建立者: 潘星宇 ***** 建立時間:2013-1-15 ***** 最後更新: 2017-4-26 ****************************************************************************/ void INT_initialize_key (void) { //第一步 配置I/O口特殊功能 rGPFCON &= ~((3<<0)|(3<<2)|(3<<4)|(3<<8)); //清零GPF0,1,2,4對應的控制位 rGPFCON |= (2<<0)|(2<<2)|(2<<4)|(2<<8); //設定GPF0,1,2,4為外部中斷模式 rGPFUP |= (1|(1<<1)|(1<<2)|(1<<4)); //禁上拉 rGPGCON &= ~(3<<0); //清零GPG0對應的控制位 rGPGCON |= (2<<0); //設定GPG0為外部中斷模式 rGPGUP |= 1; //禁止上拉 //第二步 配置其中斷觸發方式 rEXTINT0 &= ~((7<<0)|(7<<4)|(7<<8)|(7<<16)); //清零EIT0,1,2,4對應的控制位 rEXTINT0 |= (2<<0)|(2<<4)|(2<<8)|(2<<16); //設定EIT0,1,2,4為下降沿觸發中斷模式 rEXTINT1 &= ~(7<<0); //清零EIT8 rEXTINT1 |= (6<<0); //設定EIT8為雙邊沿觸發中斷模式 // //第三步 清子中斷標誌位,開啟子遮蔽 rEINTPEND |= ((1<<4)|(1<<8)); //清子中斷 rEINTMASK &= ~((1<<4)|(1<<8)); //開啟子遮蔽 //第四步 清總中斷:源掛起和中斷掛起 ClearPending(BIT_EINT0); //清以下5個總中斷和掛起標誌 ClearPending(BIT_EINT1); ClearPending(BIT_EINT2); ClearPending(BIT_EINT4_7); ClearPending(BIT_EINT8_23); //第五步 設定中斷服務函式入口 pISR_EINT0 = (unsigned int)EINT0_callback; pISR_EINT1 = (unsigned int)EINT1_callback; pISR_EINT2 = (unsigned int)EINT2_callback; pISR_EINT4_7 = (unsigned int)EINT4_7_callback; pISR_EINT8_23 = (unsigned int)EINT8_23_callback; //開總中斷 EnableIrq(BIT_EINT0); EnableIrq(BIT_EINT1); EnableIrq(BIT_EINT2); EnableIrq(BIT_EINT4_7); EnableIrq(BIT_EINT8_23); rGPBDAT = 0x5e0; //關LED rGPBCON =0x00115401; //設定GPB5、GPB6、GPB8、GPB10為輸出 rGPBUP =0x7ff; //禁止上拉 }
請注意看程式註釋,尤其是中斷的步驟,很關鍵
標頭檔案如下:
#ifndef KEY_H #define KEY_H #include "2440addr.h" #include "common_functions.h" #include "touch.h" #include "global_value.h" /************************************************************************** ***** 函式名: INT_initialize_key ***** 功能: 初始化按鍵中斷 ***** 引數: 無 ***** 返回值: 無 ***** 建立者: 潘星宇 ***** 建立時間:2013-1-15 ***** 最後更新: 2013-1-19 ****************************************************************************/ extern void INT_initialize_key (void); extern int get_bit_port_g (char port_bit); #endif