ARM实验5 —— 按键中断实验
key_int按键中断实验
实验内容:
通过开发板上的按键中断控制led灯进行跑马灯并打印信息。
通过简单事例说明猎户座4412处理器的GIC中断处理的应用,设置key2按键连接的引脚为中断模式,当识别按键被按下时进入相应的中断处理函数
实验目的:
熟悉开发环境的使用
掌握猎户座4412处理器的中断过程及编程。
实验平台:
fs4412开发板,eclipse,secureCRT。
实验步骤:
对外设进行使能:
1.查看key2在开发板的位置:
2.查看UART_RING在核心板的位置:
3.查看GPX1在芯片手册的位置:
4.查看GPX1的中断源:
5.设置TXT_INT41[1]为下降沿触发。
6.使能TXT_INT41[1]
实验代码
1 #include "exynos_4412.h" 2 typedef enum 3 { 4 false, 5 true 6 }bool; 7 void do_irq() 8 { 9 // 获取中断号 10 unsigned int irq_num = CPU0.ICCIAR & 0x3ff; 11 switch(irq_num) 12 { 13 case 57: 14 printf("This interrupt id is %d\n", irq_num); 15 16 17 18 led_isOn(true); 19 mydelay_ms(1000); 20 led_isOn(false); 21 //mydelay_ms(1000); 22 23 24 25 EXT_INT41_PEND = 0x1 << 1; // 清pend(置1清0) 26 ICDICPR.ICDICPR1 = 0x1 << 25; // 清中断使能位 27 break; 28 case 58: 29 printf("58This interrupt id is %d\n", irq_num); 30 break; 31 default: 32 printf("Interrupt is not exist!\n"); 33 break; 34 } 35 36 // 把处理器中处理完的中断号返回给gic 37 // 告诉gic该中断处理结束,可以送入下一个pending进入 38 CPU0.ICCEOIR = (CPU0.ICCEOIR & ~(0x3ff)) | irq_num; 39 } 40 41 void peripheral_init() 42 { 43 GPX1.CON = 0xf << 4; // 配置GPIO为外部中断 44 EXT_INT41_CON = 0x2 << 4; // 下降沿触发中断 45 EXT_INT41_MASK = 0x0; // 使能相应外设 46 } 47 48 void gic_init() 49 { 50 ICDDCR = 0x1; // 使能中断到分配器 51 ICDISER.ICDISER1 = 0x1 << 25; // 使能按键中断号 52 CPU0.ICCICR = 0x1; // 把中断从cpu接口送入处理器 53 // 屏蔽中断优先级,255表示所有中断都允许通过 54 CPU0.ICCPMR = 0xff; 55 ICDIPTR.ICDIPTR14 = 0x1 << 8; // 选择cpu接口 56 } 57 58 void mydelay_ms(int ms) 59 { 60 int i, j; 61 while(ms--) 62 { 63 for (i = 0; i < 5; i++) 64 for (j = 0; j < 500; j++); 65 } 66 } 67 68 void len_init(){ 69 GPX1.CON = (GPX1.CON& (~0xf)) | 0x1; 70 GPF3.CON = GPF3.CON | (0x1<<16); 71 GPF3.CON = GPF3.CON | (0x1<<20); 72 GPX2.CON = GPX2.CON & (~(0xf<<28)) | (0x1<<28); 73 } 74 void led_isOn(bool bFlag) 75 { 76 if(bFlag == false) 77 GPX2.DAT &= ~(0x1<<7); // led is off 78 else 79 GPX2.DAT |= 0x1<<7; // LED is on 80 81 mydelay_ms(1000); 82 83 if(bFlag == false) 84 GPX1.DAT &= ~0x1; // led is off 85 else 86 GPX1.DAT |= 0x1; // LED is on 87 88 mydelay_ms(1000); 89 if(bFlag == false) 90 GPF3.DAT &= ~(0x1<<4); // led is off 91 else 92 GPF3.DAT |= 0x1<<4; // LED is on 93 mydelay_ms(1000); 94 95 if(bFlag == false) 96 GPF3.DAT &= ~(0x1<<5); // led is off 97 else 98 GPF3.DAT |= 0x1<<5; // LED is on 99 100 } 101 int main() 102 { 103 peripheral_init(); 104 gic_init(); 105 106 len_init(); 107 108 109 int i = 0; 110 while(1) 111 { 112 printf("i = %d\n", i++); 113 mydelay_ms(800); 114 } 115 116 return 0; 117 }
实验结果;
拓展:根据key2 的代码写一个key3 的代码。
查看k3在开发板的位置:
查看SIM_DET 在核心板的位置;
查看GPX1_2在芯片手册的位置;
中断源:
代码:
1 /* 2 * main.c 3 * 4 * Created on: 2018-9-24 5 * Author: Administrator 6 */ 7 8 #include"exynos_4412.h" 9 typedef enum 10 { 11 false, 12 true 13 }bool; 14 15 void do_irq() 16 { 17 // 获取中断号 18 unsigned int irq_num = CPU0.ICCIAR & 0x3ff; 19 switch(irq_num) 20 { 21 22 case 58: 23 printf("58This interrupt id is %d\n", irq_num); 24 led_isOn(true); 25 mydelay_ms(1000); 26 led_isOn(false); 27 //mydelay_ms(1000); 28 29 EXT_INT41_PEND = 0x1 << 2; // 清pend(置1清0) 30 ICDICPR.ICDICPR1 = 0x1 << 26; // 清中断使能位 31 32 break; 33 default: 34 printf("Interrupt is not exist!\n"); 35 break; 36 } 37 38 // 把处理器中处理完的中断号返回给gic 39 // 告诉gic该中断处理结束,可以送入下一个pending进入 40 CPU0.ICCEOIR = (CPU0.ICCEOIR & ~(0x3ff)) | irq_num; 41 } 42 43 44 void peripheral_init() 45 { 46 GPX1.CON = 0xf << 8; // 配置GPIO为外部中断 47 EXT_INT41_CON = 0x2 << 8; // 下降沿触发中断 48 EXT_INT41_MASK = 0x0; // 使能相应外设 49 } 50 51 void gic_init() 52 { 53 ICDDCR = 0x1; // 使能中断到分配器 54 ICDISER.ICDISER1 = 0x1 << 26; // 使能按键中断号 55 CPU0.ICCICR = 0x1; // 把中断从cpu接口送入处理器 56 // 屏蔽中断优先级,255表示所有中断都允许通过 57 CPU0.ICCPMR = 0xff; 58 ICDIPTR.ICDIPTR14 = 0x1 << 16; // 选择cpu接口 59 } 60 61 void len_init(){ 62 GPX1.CON = (GPX1.CON& (~0xf)) | 0x1; 63 GPF3.CON = GPF3.CON | (0x1<<16); 64 GPF3.CON = GPF3.CON | (0x1<<20); 65 GPX2.CON = GPX2.CON & (~(0xf<<28)) | (0x1<<28); 66 } 67 void led_isOn(bool bFlag) 68 { 69 if(bFlag == false) 70 GPX2.DAT &= ~(0x1<<7); // led is off 71 else 72 GPX2.DAT |= 0x1<<7; // LED is on 73 74 mydelay_ms(1000); 75 76 if(bFlag == false) 77 GPX1.DAT &= ~0x1; // led is off 78 else 79 GPX1.DAT |= 0x1; // LED is on 80 81 mydelay_ms(1000); 82 if(bFlag == false) 83 GPF3.DAT &= ~(0x1<<4); // led is off 84 else 85 GPF3.DAT |= 0x1<<4; // LED is on 86 mydelay_ms(1000); 87 88 if(bFlag == false) 89 GPF3.DAT &= ~(0x1<<5); // led is off 90 else 91 GPF3.DAT |= 0x1<<5; // LED is on 92 93 } 94 95 void mydelay_ms(int ms) 96 { 97 int i, j; 98 while(ms--) 99 { 100 for (i = 0; i < 5; i++) 101 for (j = 0; j < 500; j++); 102 } 103 } 104 105 106 int main(){ 107 peripheral_init(); 108 gic_init(); 109 len_init(); 110 int i = 0; 111 while(1) 112 { 113 printf("i = %d\n", i++); 114 mydelay_ms(800); 115 } 116 117 return 0; 118 }
拓展二,由原先的中断使用CPU0,改为使用cpu1;
代码
1 #include "exynos_4412.h" 2 typedef enum 3 { 4 false, 5 true 6 }bool; 7 void do_irq() 8 { 9 // 获取中断号 10 unsigned int irq_num = CPU0.ICCIAR & 0x3ff; 11 switch(irq_num) 12 { 13 case 57: 14 printf("This interrupt id is %d\n", irq_num); 15 16 17 18 led_isOn(true); 19 mydelay_ms(1000); 20 led_isOn(false); 21 //mydelay_ms(1000); 22 23 24 25 EXT_INT41_PEND = 0x1 << 1; // 清pend(置1清0) 26 ICDICPR.ICDICPR1 = 0x1 << 25; // 清中断使能位 27 break; 28 case 58: 29 printf("58This interrupt id is %d\n", irq_num); 30 break; 31 default: 32 printf("Interrupt is not exist!\n"); 33 break; 34 } 35 36 // 把处理器中处理完的中断号返回给gic 37 // 告诉gic该中断处理结束,可以送入下一个pending进入 38 CPU0.ICCEOIR = (CPU0.ICCEOIR & ~(0x3ff)) | irq_num; 39 } 40 41 void peripheral_init() 42 { 43 GPX1.CON = 0xf << 4; // 配置GPIO为外部中断 44 EXT_INT41_CON = 0x2 << 4; // 下降沿触发中断 45 EXT_INT41_MASK = 0x0; // 使能相应外设 46 } 47 48 void gic_init() 49 { 50 ICDDCR = 0x1; // 使能中断到分配器 51 ICDISER.ICDISER1 = 0x1 << 25; // 使能按键中断号 52 CPU1.ICCICR = 0x1; // 把中断从cpu接口送入处理器 53 // 屏蔽中断优先级,255表示所有中断都允许通过 54 CPU1.ICCPMR = 0xff; 55 ICDIPTR.ICDIPTR14 = 0x1 << 8; // 选择cpu接口 56 } 57 58 void mydelay_ms(int ms) 59 { 60 int i, j; 61 while(ms--) 62 { 63 for (i = 0; i < 5; i++) 64 for (j = 0; j < 500; j++); 65 } 66 } 67 68 void len_init(){ 69 GPX1.CON = (GPX1.CON& (~0xf)) | 0x1; 70 GPF3.CON = GPF3.CON | (0x1<<16); 71 GPF3.CON = GPF3.CON | (0x1<<20); 72 GPX2.CON = GPX2.CON & (~(0xf<<28)) | (0x1<<28); 73 } 74 void led_isOn(bool bFlag) 75 { 76 if(bFlag == false) 77 GPX2.DAT &= ~(0x1<<7); // led is off 78 else 79 GPX2.DAT |= 0x1<<7; // LED is on 80 81 mydelay_ms(1000); 82 83 if(bFlag == false) 84 GPX1.DAT &= ~0x1; // led is off 85 else 86 GPX1.DAT |= 0x1; // LED is on 87 88 mydelay_ms(1000); 89 if(bFlag == false) 90 GPF3.DAT &= ~(0x1<<4); // led is off 91 else 92 GPF3.DAT |= 0x1<<4; // LED is on 93 mydelay_ms(1000); 94 95 if(bFlag == false) 96 GPF3.DAT &= ~(0x1<<5); // led is off 97 else 98 GPF3.DAT |= 0x1<<5; // LED is on 99 100 } 101 int main() 102 { 103 peripheral_init(); 104 gic_init(); 105 106 len_init(); 107 108 109 int i = 0; 110 while(1) 111 { 112 printf("i = %d\n", i++); 113 mydelay_ms(800); 114 } 115 116 return 0; 117 }
结果