嵌入式实验报告5.docx
《嵌入式实验报告5.docx》由会员分享,可在线阅读,更多相关《嵌入式实验报告5.docx(11页珍藏版)》请在冰豆网上搜索。
嵌入式实验报告5
CVT6410按键中断实验
一、实验目的
1.熟悉RVDS2.2开发环境。
2.掌握S3C6410内部相关寄存器的操作方法,最终实现对外部设备的控制。
3.熟悉在ARM裸机环境下的C语言编程。
4.熟悉S3C6410按键中断的原理以及编程。
二、实验内容
建立RVDS开发环境。
利用按键中断实现对开发板上发光二极管LED的跑马灯控制。
三、实验设备
1.硬件:
CVT6410教学实验箱、PC机;
2.软件:
PC机操作系统Windows98(2000、XP)+RVDS开发环境。
3.JLINK仿真器。
四、基础知识
中断的基本概念:
CPU与外设之间传输数据的控制方式通常有三种:
查询方式、中断方式和DMA方式。
查询方式的优点是硬件开销小,使用起来比较简单。
但在此方式下,CPU要不断地查询外设的状态,当外设未准备好时,CPU就只能循环等待,不能执行其它程序,这样就浪费了CPU的大量时间,降低了CPU的利用率。
为了解决这个矛盾,通常采用中断传送方式:
即当CPU进行主程序操作时,外设的数据已存入输入端口的数据寄存器;或端口的数据输出寄存器已空,由外设通过接口电路向CPU发出中断请求信号,CPU在满足一定的条件下,暂停执行当前正在执行的主程序,转入执行相应能够进行输入/输出操作的子程序,待输入/输出操作执行完毕之后CPU再返回并继续执行原来被中断的主程序。
这样CPU就避免了把大量时间耗费在等待、查询状态信号的操作上,使其工作效率得以大大地提高。
能够向CPU发出中断请求的设备或事件称为中断源。
系统引入中断机制后,CPU与外设(甚至多个外设)处于“并行”工作状态,便于实现信息的实时处理和系统的故障处理。
中断方式的原理示意图如下所示。
图5-7中断处理示意图
1)中断响应
中断源向CPU发出中断请求,若优先级别最高,CPU在满足一定的条件下,可以中断当前程序的运行,保护好被中断的主程序的断点及现场信息。
然后,根据中断源提供的信息,找到中断服务子程序的入口地址,转去执行新的程序段,这就是中断响应。
CPU响应中断是有条件的,如内部允许中断、中断未被屏蔽、当前指令执行完等。
2)中断服务子程序
CPU响应中断以后,就会中止当前的程序,转去执行一个中断服务子程序,以完成为相应设备的服务。
中断服务子程序的一般结构如下图所示。
图5-8中断服务子程序处理流程
▼保护现场(由一系列的压栈指令完成)。
目的是为了保护那些与主程序中有冲突的寄存器,(如R0,R1,R2等),如果中断服务子程序中所使用的寄存器与主程序中所使用的寄存器等没有冲突的话,这一步骤可以省略。
▼中断处理,中断处理程序在检查到相应的中断源后,调用对应的中断处理程序完成。
▼恢复现场并返回(由一系列的出栈指令完成)。
是与保护现场对应的,但要注意数据恢复的次序,以免混乱。
由于中断服务子程序需要打断主程序的执行,因此其处理应该及时完成,较长时间的延时将导致系统性能严重下降。
实验相应寄存器
端口配置寄存器
实验电路
按键驱动电路参见“3.3CVT6410的按键实验”的实验电路
实验程序
Main.c:
#include"..\inc\6410addr.h"
#include"..\inc\typdef.h"
#include"..\inc\int.h"
#include"..\inc\ExtInt.h"
voidmain(void)
{
GPIO_Init();
Init_SystemInt();
ExtIntConfigure();
INTC_SetVectAddr(NUM_EINT0,IntKey1ISR);
INTC_SetVectAddr(NUM_EINT1,IntKey2ISR);
rEINT0MASK&=(~(0x3f));//取消中断屏蔽
INTC_Enable(NUM_EINT0);
INTC_Enable(NUM_EINT1);
Uart_Printf("\n主程序正在运行,等待中断中...");
while
(1)
{}
}
/*****************************************************/
//程序名:
ExtInt.c
//功能:
外部中断测试
/*****************************************************/
#include"..\inc\6410addr.h"
#include"..\inc\typdef.h"
#include"..\inc\int.h"
#include"..\inc\ExtInt.h"
/*****************************************************/
//程序名:
GPIO_Init()
//功能:
初始化GPIO
//参数:
无
//返回值:
无
/*****************************************************/
voidGPIO_Init(void)
{
//GPIOPortM
//Bit[15:
12][11:
8][7:
4][3:
0]
//CONFIG0001000100010001
//FunctionOutputOutputOutputOutput
rGPMCON=(rGPMCON&~(0xffffffU))|0x1111;//将前面GPM0~GPM3设置成为输出
rGPMPUD=(rGPMPUD&~(0xFFFFU));//上下拉禁止
rGPMDAT=0x3f;//初始化LED灯为熄灭的状态
return;
}
/*****************************************************/
//函数名:
LED_Display
//功能:
LED循环显示
//参数:
无
//返回值:
无
/*****************************************************/
voidLED_Display(void)
{
rGPMDAT=0x3e;
Us_Delay(10000);
Us_Delay(10000);
Us_Delay(10000);
rGPMDAT=0x3d;
Us_Delay(10000);
Us_Delay(10000);
Us_Delay(10000);
rGPMDAT=0x3b;
Us_Delay(10000);
Us_Delay(10000);
Us_Delay(10000);
rGPMDAT=0x37;
Us_Delay(10000);
Us_Delay(10000);
Us_Delay(10000);
rGPMDAT=0x30;
Us_Delay(10000);
Us_Delay(10000);
Us_Delay(10000);
rGPMDAT=0x3f;
Us_Delay(10000);
Us_Delay(10000);
Us_Delay(10000);
return;
}
/*****************************************************/
//程序名:
ExtIntConfigure
//功能:
配置外部中断相关寄存器
//参数:
无
//返回值:
无
/*****************************************************/
voidExtIntConfigure(void)
{
rGPNCON&=(~(0xfff));
rGPNCON|=0xaaa;//配置GPM0~GPM4为外部中断输入模式
rEINT0CON0&=(~((7<<8)|(7<<4)|(7<<0)));//将外部中断组0[5:
1]配置为低电平触发
rEINT0CON0|=((2<<8)|(2<<4)|(2<<0));
rEINT0FLTCON0=0x0000000;
rEINT0FLTCON0|=((1<<23)|(0<<22)|(1<<15)|(0<<14)|(1<<7)|(0<<6));
//将外部中断组0[5:
1]硬件滤波使能为电平滤波方式
rEINT0MASK|=0x3f;//禁止中断
rEINT0PEND=0xffffffff;//清除中断挂起寄存器
return;
}
/*****************************************************/
//程序名:
ClearPending
//功能:
清除中断挂起标志
//参数:
中断挂起位
//返回值:
无
/*****************************************************/
voidClearPending(U8bit)
{
rEINT0PEND|=bit;
return;
}
/*****************************************************/
//程序名IntKey1ISR
//功能:
中断服务程序1
//参数:
无
//返回值:
无
/*****************************************************/
void__irqIntKey1ISR(void)
{
U32temp;
temp=rEINT0PEND;
if(temp&(1<<0))
{
Uart_Printf("\nUP被按下,点亮LED1");
rGPMDAT=0x3e;
ClearPending(BIT_INT0);
}
if(temp&(1<<1))
{
Uart_Printf("\nDown被按下,点亮LED2");
rGPMDAT=0x3d;
ClearPending(BIT_INT1);
}
if(temp&(1<<2))
{
Uart_Printf("\nLeft被按下,点亮LED3");
rGPMDAT=0x3b;
ClearPending(BIT_INT2);
}
if(temp&(1<<3))
{
Uart_Printf("\Right被按下,点亮LED4");
rGPMDAT=0x37;
ClearPending(BIT_INT3);
}
INTC_ClearVectAddr();
return;
}
/*****************************************************/
//程序名IntKey2ISR
//功能:
中断服务程序2
//参数:
无
//返回值:
无
/*****************************************************/
void__irqIntKey2ISR(void)
{
U32temp;
temp=rEINT0PEND;
if(temp&(1<<4))
{
Uart_Printf("\nMenu被按下,LED全部点亮");
rGPMDAT=0x30;
ClearPending(BIT_INT4);
}
if(temp&(1<<5))
{
Uart_Printf("\nBack被按下,LED循环点亮");
LED_Display();
ClearPending(BIT_INT5);
}
INTC_ClearVectAddr();
return;
}
五、实验步骤
1.准备好实验环境,将JLINK连接好。
给开发板上电,使Bootloader停在菜单处。
2.打开软件‘CodeWarriorforRVDS’,新建工程‘ExtInt.mcp’,并添加两个程序文件‘main.c’和‘ExtInt.c’等文件。
3.对工程文件进行相应设置
4.编译该工程,成功后将生成映像文件‘ExtInt.axf’。
打开AXD,装载映像文件‘ExtInt.axf’。
5.运行程序,观察结果。
六、实验结果
按下对应的按钮,灯对应显示,超级终端中对应打印信息。
7、总结
通过该实验实习,了解单片机的键盘模块,熟悉和掌握了嵌入式开发系统环境及其调试方式,进一步熟悉汇编编程和C语言编程;和理解了课本中的程序代码。