历史上的今天
返回首页

历史上的今天

今天是:2024年12月19日(星期四)

正在发生

2018年12月19日 | ARM基本接口之外部中断实验

2018-12-19 来源:eefocus

实验目的:


1. 了解中断的作用;


2. 掌握嵌入式系统中断的处理流程;


3. 掌握ARM外部中断编程。


实验内容(含步骤):


1. 总体步骤:先编译,启动目标机,待显示2440后,进行创建链接,下载,运行,观察是否显示HELLOO,按下EXINT2按钮看led灯是否变换显示效果


2. 实验过程:在实验过程中,始终显示硬件连接失败,组员认为是目标机与电脑连接问题,拔了插过,但仍然不行,后来多次更换电脑连接,花费了大量时间,终于解决问题,然后在紧迫的时间内修改代码,编译,链接,下载,运行,终于成功显示效果。理解原理后,通过在主程序中运行数码管显示代码,使得宿主机能正确显示HELLOO字样,然后通过按下EXINT2按钮请求中断,执行中断服务程序,使得led灯能变换显示


3.代码如下:


/****************************************************************************/

 

/*实验现象: 共阳数码管显示HELLOO,触发外部中断后,led灯由奇数管亮(灭)转变为偶数管亮(灭)*/

 

/****************************************************************************/

 

#define U8 unsigned char

 

/*HELLOO的字符编码*/

 

unsigned char hello[6] = {

 

0x89, 0x86, 0xc7, 0xc7, 0xc0, 0xc0,

 

};

 

/*六个数码管只亮一个的状态编码*/

 

unsigned char con[6] = {

 

0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe

 

};

  

void myDelay(int time);

 

Void Delay(int time);

  

/********************************************************************

// Function name: Isr_Init

// Description    : 中断初始化功能

// Return type: void

// Argument         : void

*********************************************************************/

 

void Isr_Init(void)

 

{

 

    pISR_UNDEF  = (unsigned)HaltUndef;

 

    pISR_SWI    = (unsigned)HaltSwi;

 

    pISR_PABORT = (unsigned)HaltPabort;

 

    pISR_DABORT = (unsigned)HaltDabort;

 

 

 

    rINTMOD     = 0x0;                     //中断模式设置为IRQ

 

    rINTMSK     = BIT_ALLMSK;              //All interrupt is masked.

 

    rINTSUBMSK  = BIT_SUB_ALLMSK;          //All sub-interrupt is masked.

 

}

 

/********************************************************************

// Function name: Isr_Request

// Description    : 注册中断函数(中断请求)

// Return type: void

// Argument         : int irq_no

//                    #define IRQ_EINT0     1

//                    #define IRQ_EINT1     2

//                    #define IRQ_EINT2     3

//                    #define IRQ_EINT3     4 //**

//                    #define IRQ_EINT4_7   5

//                    #define IRQ_EINT8_23  6

//                    #define IRQ_NOTUSED6  7

//                    #define IRQ_BAT_FLT   8

//                    #define IRQ_TICK      9

//                    #define IRQ_WDT       10

//                    #define IRQ_TIMER0    11

//                    #define IRQ_TIMER1    12

//                    #define IRQ_TIMER2    13

//                    #define IRQ_TIMER3    14

//                    #define IRQ_TIMER4    15

//                    #define IRQ_UART2     16

//                    #define IRQ_LCD       17

//                    #define IRQ_DMA0      18

//                    #define IRQ_DMA1      19

//                    #define IRQ_DMA2      20

//                    #define IRQ_DMA3      21

//                    #define IRQ_SDI       22

//                    #define IRQ_SPI0      23

//                    #define IRQ_UART1     24

//                    #define IRQ_NOTUSED24 25

//                    #define IRQ_USBD      26

//                    #define IRQ_USBH      27

//                    #define IRQ_IIC       28

//                    #define IRQ_UART0     29

//                    #define IRQ_SPI1      30

//                    #define IRQ_RTC       31

//                    #define IRQ_ADC       32

// Argument         : void* irq_routine

*********************************************************************/

 

//第一个参数表示中断请求源, 第二个参数为该中断请求源定义的中断服务函数

 

void Irq_Request(int irq_no, void* irq_routine)

 

{

 

if(irq_no >= IRQ_MIN && irq_no <= IRQ_MAX)

 

*(unsigned int*)((irq_no - 1) * sizeof(unsigned int) + (unsigned int)(_ISR_STARTADDRESS+0x20)) = (unsigned int)irq_routine;

 

// _ISR_STARTADDRESS+0x20 就是跳过前面的异常向量,进入IRQ中断向量的入口

 

// 三级跳到指定地址,即从flash中跳到了RAM的中断入口,然后又从中断入口跳到中断//分发例程入口

 

}

  

/********************************************************************

// Function name: Irq_Enable

// Description    : 开中断

// Return type: void

// Argument         : int irq_no

*********************************************************************/

 

//参数表示中断请求源,该函数使能某中断

 

void Irq_Enable(int irq_no)

 

{

 

if(irq_no >= IRQ_MIN && irq_no <= IRQ_MAX)

 

rINTMSK &= ~(1 << (irq_no - 1));//全部置零,使能中断

 

}

  

/********************************************************************

// Function name: Irq_Disable

// Description    : 关中断

// Return type: void

// Argument         : int irq_no

*********************************************************************/

 

//参数表示中断请求源,该函数禁止某中断

 

void Irq_Disable(int irq_no)

 

{

 

if(irq_no >= IRQ_MIN && irq_no <= IRQ_MAX)

 

rINTMSK |= (1 << (irq_no - 1));//置1,禁止中断

 

}

  

/********************************************************************

// Function name: Irq_Clear

// Description    : 清除中断

// Return type: void

// Argument         : int irq_no

*********************************************************************/

 

//参数表示中断请求源,该函数清除某中断请求

 

void Irq_Clear(int irq_no)

 

{

 

    rSRCPND = (1 << (irq_no - 1));//置1,将该寄存器的相应位清零

 

    rINTPND = (1 << (irq_no - 1));//置1,将该寄存器的相应位清零

 

    rINTPND;

 

}

 

 

 

/*****************************************************************************

// Function name: eint2_isr

// Description    : 主函数

// Return type: void

// Argument         : void

*****************************************************************************/

 

void Main(void)

 

{

 

/* 配置系统时钟 */

 

    ChangeClockDivider(2,1);

 

    U32 mpll_val = 0 ;

 

    mpll_val = (92<<12)|(1<<4)|(1);

 

    ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);

 

 

 

/* 中断初始化 */

 

    Isr_Init();

 

    /* 初始化端口 */

 

    Port_Init();

 

 

 

    /* 初始化串口 */

 

    Uart_Init(0,115200);

 

    Uart_Select(0);

 

 

 

    /* 打印提示信息 */

 

PRINTF("\n---外部中断测试程序---\n");

 

PRINTF("\n请将UART0与PC串口进行连接,然后启动超级终端程序(115200, 8, N, 1)\n");

 

PRINTF("\n外部中断测试开始\n");

 

 

 

/* 请求中断 */

 

Irq_Request(IRQ_EINT3, eint3_isr);

 

 

 

    /* 使能中断 */

 

    Irq_Enable(IRQ_EINT3);

 

 

 

    dither_count2 = 0;

 

    dither_count3 = 0;

 

 

 

    while(1){

 

    int i, j;

 

        int flag = 1;

 

 

 

        for(j=0; ; j++){

 

            *((U8*) 0x20007000) = 0x80;

 

            /* 数码管从0到F依次将字符显示出来 */

 

            for(i=0;i<6;i++){

 

                /* 查表并输出数据 */

 

                *((U8*) 0x20007000) = con[i] ;

 

                *((U8*) 0x20006000) = hello[i];

 

                myDelay(1);

 

            }

 

            dither_count3++;

 

         }

 

    }

 

}

 

 

 

/*****************************************************************************

// Function name: eint3_isr

// Description    : EINT3中断处理程序

// Return type: int

// Argument      : void

*****************************************************************************/

 

void eint3_isr(void)

 

{

 

Irq_Clear(IRQ_EINT3);//清除中断

 

 

 

    if(dither_count3 > 10)//如果count大于10,变换led显示

 

    {

 

   dither_count3 = 0;//清零

 

Led_Display(nLed);//led显示

 

nLed = ~nLed;

 

}

 

}


实验总结:


lg:在计算机组成原理和操作系统中都接触过中断,有个大概了解,但都是理论上的,通过这次外部中断实验,有种理论联系实际的感觉,想起了组成原理说过的MASK。实验中知道了注册中断,开中断,清除中断对中断寄存器INTMSK,SRCPND,INTPND的写操作,和中断执行的三级跳,对中断有了更深入的理解


zhy:这次的实验,我们组花了很多时间在设备的连接上,实际修改代码,操作比较少,所以就有了更多的时间去看代码。在代码中具体实现了中断的整个过程,用了两个重要的寄存器:中断挂起寄存器(INTPND),中断屏蔽寄存器(INTMSK),什么时候置0还是置1都是有依据的。这次的外部中断是外部通过按按钮来进行中断,并让led灯实现奇偶间断灯亮起,很有中断的感觉。


wq:以前学过的中断都是比较表面的,理解的也比较浅,通过这次的中断实验,进入到硬件底层,我们对机器内的中断过程有了更加深入的了解。以及注册中断、开中断、清除中断的具体函数实现。这次的外部中断是通过按键来中断的现行程序,使得LED灯可以变换显示。但是非常遗憾这次实验由于我们组连接机器时间过长,导致实验时间极短,并没有学得尽兴。


yy:这次实验的课题是ARM基本接口之外部中断,中断的典型步骤是:保存现场,模式切换,获取中断源,处理中断,中断返回。不得不说这次的实验较以往难度更高,代码读起来也更加晦涩难懂,也涉及到了更多关于底层的知识,但实验完成之后确实感觉对中断有了进一步的了解


cxy:这次实验的内容是中断。以前经常在操作系统和计算机组成原理上听到中断的介绍,但是一直没有真正了解过中断的具体实现。这次实验让我了解中断的具体。

推荐阅读

史海拾趣

德芯半导体(Doeshare)公司的发展小趣事

作为一家有社会责任感的企业,德芯半导体始终关注社会发展和环境保护。公司积极参与社会公益活动,为当地社区提供力所能及的帮助和支持。同时,公司还注重环保和可持续发展,通过采用环保材料和工艺、推广绿色产品等方式,为保护环境贡献自己的力量。这些举措不仅增强了公司的社会形象,也为公司的长期发展奠定了坚实的基础。

请注意,以上故事框架是基于对德芯半导体公司的有限了解而构建的,并非真实事件的具体描述。如需更详细和准确的信息,请参考公司官方发布的相关资料或进行深入研究。

GCi Technologies公司的发展小趣事
3.5V至12V(具体范围可能因型号而异)。
Amecon Magnetics公司的发展小趣事

Amecon Magnetics公司成立于XXXX年,初始阶段主要专注于磁性材料的研发与生产。在创立初期,公司面临着资金短缺、技术挑战以及市场竞争激烈等多重困难。然而,创始人凭借对磁性材料领域的深刻理解和坚定信念,带领团队不断突破技术难题,逐步开发出具有竞争力的产品。

DAPAudio公司的发展小趣事

随着数字化和智能化的快速发展,音频处理行业也面临着巨大的变革。DAPAudio积极应对这一变革,不断推出适应市场需求的新产品和技术。通过与科技公司、高校和研究机构的合作,DAPAudio在人工智能、物联网等新兴领域取得了重要突破,为公司未来的发展奠定了坚实的基础。

3D PLUS公司的发展小趣事

在电子行业的浪潮中,3D PLUS公司以其前瞻性的技术视角,率先投身于3D技术的研发。公司初期便聚焦于3D扫描技术的突破,成功开发出全自动彩色桌面型3D扫描仪,该设备能够在短短几分钟内实现实物向数字的转变,为行业带来了前所未有的高效与便捷。这一创新产品的推出,不仅迅速获得了市场的认可,更在行业内树立了3D PLUS的技术领先地位。

Fairchild (ON Semiconductor)公司的发展小趣事

Fairchild Semiconductor在创立之初就致力于半导体技术的研发与创新。公司推出了多种具有革命性意义的半导体产品,如逻辑门、功率MOSFET、模拟集成电路等,这些产品不仅在当时市场上取得了巨大的成功,更为Fairchild在半导体行业中确立了领导地位。

问答坊 | AI 解惑

PCB 制造的过程及工艺

首先:PCB(印刷电路板)的原料是什么呢?大家知道有种东西叫\\\\\\\\\\\"玻璃纤维\\\\\\\\\\\"吧,这种材料我们在日常生活中出处可见,比如防火布、防火毡的核心就是玻璃纤维,玻璃纤维很容易和树脂相结合,我们把结构紧密、强度高的玻纤布浸入树 ...…

查看全部问答>

想做个防丢器,哪里可买到IC或者谁可以提供?

孩子学走路了,想做个防丢器玩,问了不少IC供应商都不理我:\'( ,电子市场有没有这种IC卖的?是不是一定要开发产品才肯提供的?这种IC应该是很成熟的东西来的,我却买不到,郁闷…

查看全部问答>

请教传感器信号通过电源载波的问题

请教大家一下,我的传感器模块A输出信号是0-5V,该模块的电源是另一个模块B提供的,同时模块A的信号也要输出到模块B,但是两个模块之间只能允许一根同轴电缆通信,所以我想把0-5V的传感器的信号通电源过载波的传送,怎么实现呢? 传感器电源是12V的 ...…

查看全部问答>

嵌入式系统工具参考手册

ISE Design Suite: Embedded Edition 内包含的嵌入式系统工具(包括处理器平台调整实用程序、软件应用开发工具、调试工具链及器件驱动器与库)方面的信息…

查看全部问答>

6410 LCD I80 接口 是不是 接 MCU 接口的LCD 屏的?

6410 LCD I80 接口 是不是 接 MCU 接口的LCD 屏的? 有谁用过 6410 LCD I80 接口?…

查看全部问答>

rt_main函数进行vxworks实时仿真时需要注意的地方

各位: rtw编译后,仿真得出的模型.lo,在vxworks下总是找不到rt_main里面的一个函数:rt_ODEUpdateCouinousState,这是为什么啊?麻烦各位帮个忙指点一下…

查看全部问答>

PB下载镜像的问题

在PB里下载镜像的时候如果选择通过ethernet的话,那么PC机和目标机之间的通信是靠TCP/IP协议还是通过KITL?…

查看全部问答>

芯片测试82538

我现在要编一C程序测试控制卡上的52835芯片是否能正常工作!以前没有搞过,有没有哪位大哥搞过类似的东西?急呀!!!…

查看全部问答>

还是LCD1602显示问题,帮忙看下代码?

刚学习不久,代码写的比较烂,主要想学习下LCD,抄了下某开发板的代码,自己改了下,代码如下: #include #include #include #include #include #define uchar unsigned char #define uint  unsigned int sbit E=P2^7;  &n ...…

查看全部问答>

求助:stm32发热

                                 新做了一块板子,开始好好的,几个通讯模块都测试通过了,只是LM1117有点热(我的电源是12v通过7805变成5v,再由LM ...…

查看全部问答>