【2440裸机】中断

发布时间:2023-06-07  

@******************************************************************************

@ File:head.S

@ 功能:初始化,设置中断模式、管理模式的栈,设置好中断处理函数

@******************************************************************************       

   

.extern     main

.text 

.global _start 

_start:

@******************************************************************************       

@ 异常向量,本程序中,除Reset和HandleIRQ外,其它异常都没有使用

@******************************************************************************       

    b   Reset


@ 0x04: 未定义指令中止模式的向量地址

HandleUndef:

    b   HandleUndef 

 

@ 0x08: 管理模式的向量地址,通过SWI指令进入此模式

HandleSWI:

    b   HandleSWI


@ 0x0c: 指令预取终止导致的异常的向量地址

HandlePrefetchAbort:

    b   HandlePrefetchAbort


@ 0x10: 数据访问终止导致的异常的向量地址

HandleDataAbort:

    b   HandleDataAbort


@ 0x14: 保留

HandleNotUsed:

    b   HandleNotUsed


@ 0x18: 中断模式的向量地址

    b   HandleIRQ


@ 0x1c: 快中断模式的向量地址

HandleFIQ:

    b   HandleFIQ


Reset:                  

    ldr sp, =4096           @ 设置栈指针,以下都是C函数,调用前需要设好栈

    bl  disable_watch_dog   @ 关闭WATCHDOG,否则CPU会不断重启

    

    msr cpsr_c, #0xd2       @ 进入中断模式

    ldr sp, =3072           @ 设置中断模式栈指针


    msr cpsr_c, #0xd3       @ 进入管理模式

    ldr sp, =4096           @ 设置管理模式栈指针,

                            @ 其实复位之后,CPU就处于管理模式,

                            @ 前面的“ldr sp, =4096”完成同样的功能,此句可省略


    bl  init_led            @ 初始化LED的GPIO管脚

    bl  init_irq            @ 调用中断初始化函数,在init.c中

    msr cpsr_c, #0x53       @ 设置I-bit=0,开IRQ中断

    

    ldr lr, =halt_loop      @ 设置返回地址

    ldr pc, =main           @ 调用main函数

halt_loop:

    b   halt_loop


HandleIRQ:

    sub lr, lr, #4                  @ 计算返回地址

    stmdb   sp!,    { r0-r12,lr }   @ 保存使用到的寄存器

                                    @ 注意,此时的sp是中断模式的sp

                                    @ 初始值是上面设置的3072

    

    ldr lr, =int_return             @ 设置调用ISR即EINT_Handle函数后的返回地址  

    ldr pc, =EINT_Handle            @ 调用中断服务函数,在interrupt.c中

int_return:

    ldmia   sp!,    { r0-r12,pc }^  @ 中断返回, ^表示将spsr的值复制到cpsr


int.c文件


/*

 * init.c: 进行一些初始化

 */ 


#include "s3c24xx.h"


/*

 * LED1,LED2,LED4对应GPF4、GPF5、GPF6

 */

#define    GPF4_out    (1<#define    GPF5_out    (1<#define    GPF6_out    (1<

#define    GPF4_msk    (3<#define    GPF5_msk    (3<#define    GPF6_msk    (3<

/*

 * S2,S3,S4对应GPF0、GPF2、GPG3

 */

#define GPF0_eint     (0x2<#define GPF2_eint     (0x2<#define GPG3_eint     (0x2<

#define GPF0_msk    (3<#define GPF2_msk    (3<#define GPG3_msk    (3<

/*

 * 关闭WATCHDOG,否则CPU会不断重启

 */

void disable_watch_dog(void)

{

    WTCON = 0;  // 关闭WATCHDOG很简单,往这个寄存器写0即可

}


void init_led(void)

{

    // LED1,LED2,LED4对应的3根引脚设为输出

    GPFCON &= ~(GPF4_msk | GPF5_msk | GPF6_msk);

    GPFCON |= GPF4_out | GPF5_out | GPF6_out;

}


/*

 * 初始化GPIO引脚为外部中断

 * GPIO引脚用作外部中断时,默认为低电平触发、IRQ方式(不用设置INTMOD)

 */ 

void init_irq( )

{

    // S2,S3对应的2根引脚设为中断引脚 EINT0,ENT2

    GPFCON &= ~(GPF0_msk | GPF2_msk);

    GPFCON |= GPF0_eint | GPF2_eint;


    // S4对应的引脚设为中断引脚EINT11

    GPGCON &= ~GPG3_msk;

    GPGCON |= GPG3_eint;

    

    // 对于EINT11,需要在EINTMASK寄存器中使能它

    EINTMASK &= ~(1<<11);

        

    /*


     * 设定优先级:

     * ARB_SEL0 = 00b, ARB_MODE0 = 0: REQ1 > REQ3,即EINT0 > EINT2

     * 仲裁器1、6无需设置

     * 最终:

     * EINT0 > EINT2 > EINT11即K2 > K3 > K4

     */

    PRIORITY = (PRIORITY & ((~0x01) | (0x3<<7))) | (0x0 << 7) ;


    // EINT0、EINT2、EINT8_23使能

    INTMSK   &= (~(1<<0)) & (~(1<<2)) & (~(1<<5));

}


interrupt.c


#include "s3c24xx.h"


void EINT_Handle()

{

    unsigned long oft = INTOFFSET;

    unsigned long val;

    

    switch( oft )

    {

        // S2被按下

        case 0: 

        {   

            GPFDAT |= (0x7<<4);   // 所有LED熄灭

            GPFDAT &= ~(1<<4);      // LED1点亮

            break;

        }

        

        // S3被按下

        case 2:

        {   

            GPFDAT |= (0x7<<4);   // 所有LED熄灭

            GPFDAT &= ~(1<<5);      // LED2点亮

            break;

        }


        // K4被按下

        case 5:

        {   

            GPFDAT |= (0x7<<4);   // 所有LED熄灭

            GPFDAT &= ~(1<<6);      // LED4点亮                

            break;

        }


        default:

            break;

    }


    //清中断

    if( oft == 5 ) 

        EINTPEND = (1<<11);   // EINT8_23合用IRQ5

    SRCPND = 1<    INTPND = 1<}


头文件


/* WOTCH DOG register */

#define     WTCON           (*(volatile unsigned long *)0x53000000)


/* SDRAM regisers */

#define     MEM_CTL_BASE    0x48000000

#define     SDRAM_BASE      0x30000000


/* NAND Flash registers */

#define NFCONF              (*(volatile unsigned int  *)0x4e000000)

#define NFCMD               (*(volatile unsigned char *)0x4e000004)

#define NFADDR              (*(volatile unsigned char *)0x4e000008)

#define NFDATA              (*(volatile unsigned char *)0x4e00000c)

#define NFSTAT              (*(volatile unsigned char *)0x4e000010)


/*GPIO registers*/

#define GPBCON              (*(volatile unsigned long *)0x56000010)

#define GPBDAT              (*(volatile unsigned long *)0x56000014)


#define GPFCON              (*(volatile unsigned long *)0x56000050)

#define GPFDAT              (*(volatile unsigned long *)0x56000054)

#define GPFUP               (*(volatile unsigned long *)0x56000058)


#define GPGCON              (*(volatile unsigned long *)0x56000060)

#define GPGDAT              (*(volatile unsigned long *)0x56000064)

#define GPGUP               (*(volatile unsigned long *)0x56000068)


#define GPHCON              (*(volatile unsigned long *)0x56000070)

#define GPHDAT              (*(volatile unsigned long *)0x56000074)

#define GPHUP               (*(volatile unsigned long *)0x56000078)


/*UART registers*/

#define ULCON0              (*(volatile unsigned long *)0x50000000)

#define UCON0               (*(volatile unsigned long *)0x50000004)

#define UFCON0              (*(volatile unsigned long *)0x50000008)

#define UMCON0              (*(volatile unsigned long *)0x5000000c)

#define UTRSTAT0            (*(volatile unsigned long *)0x50000010)

#define UTXH0               (*(volatile unsigned char *)0x50000020)

#define URXH0               (*(volatile unsigned char *)0x50000024)

#define UBRDIV0             (*(volatile unsigned long *)0x50000028)



/*interrupt registes*/

#define SRCPND              (*(volatile unsigned long *)0x4A000000)

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>