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]
实验代码
#include "exynos_4412.h"
typedef enum
{
false,
true
}bool;
void do_irq()
{
// 获取中断号
unsigned int irq_num = CPU0.ICCIAR & 0x3ff;
switch(irq_num)
{
case :
printf("This interrupt id is %d\n", irq_num); led_isOn(true);
mydelay_ms();
led_isOn(false);
//mydelay_ms(1000); EXT_INT41_PEND = 0x1 << ; // 清pend(置1清0)
ICDICPR.ICDICPR1 = 0x1 << ; // 清中断使能位
break;
case :
printf("58This interrupt id is %d\n", irq_num);
break;
default:
printf("Interrupt is not exist!\n");
break;
} // 把处理器中处理完的中断号返回给gic
// 告诉gic该中断处理结束,可以送入下一个pending进入
CPU0.ICCEOIR = (CPU0.ICCEOIR & ~(0x3ff)) | irq_num;
} void peripheral_init()
{
GPX1.CON = 0xf << ; // 配置GPIO为外部中断
EXT_INT41_CON = 0x2 << ; // 下降沿触发中断
EXT_INT41_MASK = 0x0; // 使能相应外设
} void gic_init()
{
ICDDCR = 0x1; // 使能中断到分配器
ICDISER.ICDISER1 = 0x1 << ; // 使能按键中断号
CPU0.ICCICR = 0x1; // 把中断从cpu接口送入处理器
// 屏蔽中断优先级,255表示所有中断都允许通过
CPU0.ICCPMR = 0xff;
ICDIPTR.ICDIPTR14 = 0x1 << ; // 选择cpu接口
} void mydelay_ms(int ms)
{
int i, j;
while(ms--)
{
for (i = ; i < ; i++)
for (j = ; j < ; j++);
}
} void len_init(){
GPX1.CON = (GPX1.CON& (~0xf)) | 0x1;
GPF3.CON = GPF3.CON | (0x1<<);
GPF3.CON = GPF3.CON | (0x1<<);
GPX2.CON = GPX2.CON & (~(0xf<<)) | (0x1<<);
}
void led_isOn(bool bFlag)
{
if(bFlag == false)
GPX2.DAT &= ~(0x1<<); // led is off
else
GPX2.DAT |= 0x1<<; // LED is on mydelay_ms(); if(bFlag == false)
GPX1.DAT &= ~0x1; // led is off
else
GPX1.DAT |= 0x1; // LED is on mydelay_ms();
if(bFlag == false)
GPF3.DAT &= ~(0x1<<); // led is off
else
GPF3.DAT |= 0x1<<; // LED is on
mydelay_ms(); if(bFlag == false)
GPF3.DAT &= ~(0x1<<); // led is off
else
GPF3.DAT |= 0x1<<; // LED is on }
int main()
{
peripheral_init();
gic_init(); len_init(); int i = ;
while()
{
printf("i = %d\n", i++);
mydelay_ms();
} return ;
}
实验结果;
拓展:根据key2 的代码写一个key3 的代码。
查看k3在开发板的位置:
查看SIM_DET 在核心板的位置;
查看GPX1_2在芯片手册的位置;
中断源:
代码:
/*
* main.c
*
* Created on: 2018-9-24
* Author: Administrator
*/ #include"exynos_4412.h"
typedef enum
{
false,
true
}bool; void do_irq()
{
// 获取中断号
unsigned int irq_num = CPU0.ICCIAR & 0x3ff;
switch(irq_num)
{ case :
printf("58This interrupt id is %d\n", irq_num);
led_isOn(true);
mydelay_ms();
led_isOn(false);
//mydelay_ms(1000); EXT_INT41_PEND = 0x1 << ; // 清pend(置1清0)
ICDICPR.ICDICPR1 = 0x1 << ; // 清中断使能位 break;
default:
printf("Interrupt is not exist!\n");
break;
} // 把处理器中处理完的中断号返回给gic
// 告诉gic该中断处理结束,可以送入下一个pending进入
CPU0.ICCEOIR = (CPU0.ICCEOIR & ~(0x3ff)) | irq_num;
} void peripheral_init()
{
GPX1.CON = 0xf << ; // 配置GPIO为外部中断
EXT_INT41_CON = 0x2 << ; // 下降沿触发中断
EXT_INT41_MASK = 0x0; // 使能相应外设
} void gic_init()
{
ICDDCR = 0x1; // 使能中断到分配器
ICDISER.ICDISER1 = 0x1 << ; // 使能按键中断号
CPU0.ICCICR = 0x1; // 把中断从cpu接口送入处理器
// 屏蔽中断优先级,255表示所有中断都允许通过
CPU0.ICCPMR = 0xff;
ICDIPTR.ICDIPTR14 = 0x1 << ; // 选择cpu接口
} void len_init(){
GPX1.CON = (GPX1.CON& (~0xf)) | 0x1;
GPF3.CON = GPF3.CON | (0x1<<);
GPF3.CON = GPF3.CON | (0x1<<);
GPX2.CON = GPX2.CON & (~(0xf<<)) | (0x1<<);
}
void led_isOn(bool bFlag)
{
if(bFlag == false)
GPX2.DAT &= ~(0x1<<); // led is off
else
GPX2.DAT |= 0x1<<; // LED is on mydelay_ms(); if(bFlag == false)
GPX1.DAT &= ~0x1; // led is off
else
GPX1.DAT |= 0x1; // LED is on mydelay_ms();
if(bFlag == false)
GPF3.DAT &= ~(0x1<<); // led is off
else
GPF3.DAT |= 0x1<<; // LED is on
mydelay_ms(); if(bFlag == false)
GPF3.DAT &= ~(0x1<<); // led is off
else
GPF3.DAT |= 0x1<<; // LED is on } void mydelay_ms(int ms)
{
int i, j;
while(ms--)
{
for (i = ; i < ; i++)
for (j = ; j < ; j++);
}
} int main(){
peripheral_init();
gic_init();
len_init();
int i = ;
while()
{
printf("i = %d\n", i++);
mydelay_ms();
} return ;
}
拓展二,由原先的中断使用CPU0,改为使用cpu1;
代码
#include "exynos_4412.h"
typedef enum
{
false,
true
}bool;
void do_irq()
{
// 获取中断号
unsigned int irq_num = CPU0.ICCIAR & 0x3ff;
switch(irq_num)
{
case :
printf("This interrupt id is %d\n", irq_num); led_isOn(true);
mydelay_ms();
led_isOn(false);
//mydelay_ms(1000); EXT_INT41_PEND = 0x1 << ; // 清pend(置1清0)
ICDICPR.ICDICPR1 = 0x1 << ; // 清中断使能位
break;
case :
printf("58This interrupt id is %d\n", irq_num);
break;
default:
printf("Interrupt is not exist!\n");
break;
} // 把处理器中处理完的中断号返回给gic
// 告诉gic该中断处理结束,可以送入下一个pending进入
CPU0.ICCEOIR = (CPU0.ICCEOIR & ~(0x3ff)) | irq_num;
} void peripheral_init()
{
GPX1.CON = 0xf << ; // 配置GPIO为外部中断
EXT_INT41_CON = 0x2 << ; // 下降沿触发中断
EXT_INT41_MASK = 0x0; // 使能相应外设
} void gic_init()
{
ICDDCR = 0x1; // 使能中断到分配器
ICDISER.ICDISER1 = 0x1 << ; // 使能按键中断号
CPU1.ICCICR = 0x1; // 把中断从cpu接口送入处理器
// 屏蔽中断优先级,255表示所有中断都允许通过
CPU1.ICCPMR = 0xff;
ICDIPTR.ICDIPTR14 = 0x1 << ; // 选择cpu接口
} void mydelay_ms(int ms)
{
int i, j;
while(ms--)
{
for (i = ; i < ; i++)
for (j = ; j < ; j++);
}
} void len_init(){
GPX1.CON = (GPX1.CON& (~0xf)) | 0x1;
GPF3.CON = GPF3.CON | (0x1<<);
GPF3.CON = GPF3.CON | (0x1<<);
GPX2.CON = GPX2.CON & (~(0xf<<)) | (0x1<<);
}
void led_isOn(bool bFlag)
{
if(bFlag == false)
GPX2.DAT &= ~(0x1<<); // led is off
else
GPX2.DAT |= 0x1<<; // LED is on mydelay_ms(); if(bFlag == false)
GPX1.DAT &= ~0x1; // led is off
else
GPX1.DAT |= 0x1; // LED is on mydelay_ms();
if(bFlag == false)
GPF3.DAT &= ~(0x1<<); // led is off
else
GPF3.DAT |= 0x1<<; // LED is on
mydelay_ms(); if(bFlag == false)
GPF3.DAT &= ~(0x1<<); // led is off
else
GPF3.DAT |= 0x1<<; // LED is on }
int main()
{
peripheral_init();
gic_init(); len_init(); int i = ;
while()
{
printf("i = %d\n", i++);
mydelay_ms();
} return ;
}
结果