zoukankan      html  css  js  c++  java
  • 通过按键玩中断

    中断源产生信号->中断控制器->cpu处理中断

    2440:非向量方式,中断总服务程序入口---保护环境---判断中断源---调用对应该中断源的终端服务程序---恢复环境

    6410/210:向量方式,当中断产生,CPU直接跳转到用户设置好的中断处理程序处---保护环境---设备的中断处理---恢复环境

    interrupt.c

    #define INTMSK        (volatile unsigned long*)0x4a000008
    #define INTOFFSET    (volatile unsigned long*)0x4a000014
    #define SRCPND        (volatile unsigned long*)0x4a000000
    #define INTPND        (volatile unsigned long*)0x4a000010
    
    #define EINTMSK        (volatile unsigned long*)0x560000a4
    #define EINTPND        (volatile unsigned long*)0x560000a8
    
    void init_irq()
    {
        //设置这个寄存器一定要在INMSK寄存器之前设置
        *(EINTMSK) &= (~(1<<8)) & (~(1<<11)) & (~(1<<13)) & (~(1<<14)) & (~(1<<15)) & (~(1<<19));
        
        *(INTMSK) &= (~(1<<5));
        //打开中断
        __asm__(
            "mrs r0, cpsr
    "
            "bic r0, r0, #0x80
    "
            "msr cpsr_c, r0
    "
            :
            :
        );
    }
    
    
    void handle_int()
    {
        //判断产生中断的中断源
        unsigned long value = *(EINTPND) & ((1<<8)|(1<<11)|(1<<13)|(1<<14)|(1<<15)|(1<<19));
        //根据中断源,执行不同的中断处理
        switch(value)
        {
            case (1<<8):        //K1
                led_on();
            break;
            
            case (1<<11):        //K2
                led_on();
            break;
            
            case (1<<13):        //K3
                led_on();
            break;
            
            case (1<<14):        //K4
                led_off();
            break;
            
            case (1<<15):        //K5
                led_off();
            break;
            
            case (1<<19):        //K6
                led_off();
            break;
            
            default:
            break;
        }
        //中断清除
        *(EINTPND) = value;
    
        *(SRCPND) = (1<<5);
        *(INTPND) = (1<<5);
        
    }

    mmu.c

    #define MMU_FULL_ACCESS    (3<<10)
    #define MMU_DOMAIN    (0<<5)
    #define MMU_SPECIAL    (1<<4)
    #define MMU_CACHEENABLE (1<<3)
    #define MMU_BUFFERABLE  (1<<2)
    #define MMU_SECTION     (2<<0)
    
    #define SECDESC        (MMU_SECTION|MMU_SPECIAL|MMU_SPECIAL|MMU_FULL_ACCESS)
    #define SECDESC_WB    (MMU_SECTION|MMU_SPECIAL|MMU_SPECIAL|MMU_FULL_ACCESS|MMU_CACHEENABLE|MMU_BUFFERABLE)
    
    void creat_page_table()
    {
        unsigned long *ttb = (unsigned long *)0x30000000;
        unsigned long vaddr,paddr;
        
        vaddr = 0xA0000000;
        paddr = 0x56000000;
        
        *(ttb + (vaddr >> 20)) = ((paddr & 0xfff00000)|SECDESC);
        
        vaddr = 0x30000000;
        paddr = 0x30000000;
        
        while(vaddr += 0x34000000)
        {
            *(ttb + (vaddr >> 20)) = ((paddr & 0xfff00000)|SECDESC);
            vaddr += 0x10000;
            paddr += 0x10000;
        }
    }
    
    void mmu_enable()
    {
        __asm__(
        
        //设置TTB
        "ldr r0, =0x3000000
    "
        "mcr p15,0,r0,c2,c0,0
    "
        //不进行权限检查
        "mvn r0,#0
    "
        "mcr p15,0,r0,c3,c0,0
    "
        //使能mmu
        "mrc p15,0,r0,c1,c0,0
    "
        "orr r0,r0,#0x0001
    "
        "mcr p15,0,r0,c0,c1,0
    "
        :
        :
        );
        
    }
    
    void mmu_init()
    {
        creat_page_table();
        mmu_enable();
    }

    button.c

    #define GPGCON    (volatile unsigned long*)0x56000060
    
    #define GPG0_MSK    (3<<(0*2))
    #define GPG3_MSK    (3<<(3*2))
    #define GPG5_MSK    (3<<(5*2))
    #define GPG6_MSK    (3<<(6*2))
    #define GPG7_MSK    (3<<(7*2))
    #define GPG11_MSK    (3<<(11*2))
    
    #define GPG0_INT    (0x2<<(0*2))
    #define GPG3_INT    (0x2<<(3*2))
    #define GPG5_INT    (0x2<<(5*2))
    #define GPG6_INT    (0x2<<(6*2))
    #define GPG7_INT    (0x2<<(7*2))
    #define GPG11_INT    (0x2<<(11*2))
    
    void button_init()
    {
        *(GPGCON) &= ~(GPG0_MSK | GPG3_MSK | GPG5_MSK | GPG6_MSK | GPG7_MSK |GPG11_MSK);
        *(GPGCON) |= (GPG0_INT | GPG3_INT | GPG5_INT | GPG6_INT | GPG7_INT | GPG11_INT);
    }    

    start.S

    .text
    .global _start
    _start:
        b reset
        ldr pc, _undefined_instruction
        ldr pc, _software_interrupt
        ldr pc, _prefetch_abort
        ldr pc, _data_abort
        ldr pc, _not_used
        ldr pc, _irq
        ldr pc, _fiq
    
        
    _undefined_instruction: .word undefined_instruction
    _software_interrupt:.word software_interrupt
    _prefetch_abort:.word prefetch_abort
    _data_abort:.word data_abort
    _not_used:.word not_used
    _irq:.word irq
    _fiq:.word reset
    
    undefined_instruction:
        nop
        
    software_interrupt:
        nop
    
    prefetch_abort:
        nop
        
    data_abort:
        nop
        
    not_used:
        nop
        
    irq:
        @保存环境
        sub lr, lr, #4
        stmfd sp!, {r0-r12,lr}
        bl handle_int
        ldmfd sp!, {r0-r12,pc}
        
    fiq:
        nop
    
    reset:
        bl set_svc
        bl disable_watchdog    
        bl disable_interrupt
        bl disable_mmu
        bl clock_init
        bl sdram_init
        bl copy_to_ram    
        bl stack_init    
        bl clean_bss
    @    bl light_led
        ldr pc, =gboot_main
            
    set_svc:
        mrs r0, cpsr
        bic r0, r0, #0x1f
        orr r0, r0, #0xd3
        msr cpsr, r0
        mov pc, lr
    
    #define pwTCON 0x53000000
    disable_watchdog:
        ldr r0, =pwTCON
        mov r1, #0x0
        str r1, [r0]
        mov pc, lr
    
    disable_interrupt:
        mvn r1, #0x0
        ldr r0, =0x4a000008
        str r1,[r0]
        mov pc, lr    
    
    disable_mmu:
        mcr p15,0,r0,c7,c7,0
        mrc p15,0,r0,c1,c0,0
        bic r0,r0,#0x00000007
        mcr p15,0,r0,c1,c0,0
        mov pc, lr
    
    #define CLKDIVN 0x4c000014
    #define MPLLCON 0x4c000004 
    #define MPLL_405MHZ ((127<<12)|(2<<4)|(1<<0))
    clock_init:
        ldr r0, =CLKDIVN
        mov r1, #0x5
        str r1, [r0]
        
        mrc p15,0,r0,c1,c0,0
        orr r0,r0,#0xc0000000
        mcr p15,0,r0,c1,c0,0
            
        ldr r0, =MPLLCON
        ldr r1, =MPLL_405MHZ
        str r1, [r0]
    
        mov pc, lr
    
    #define mem_contrl 0x48000000    
    sdram_init:
        ldr r0, =mem_contrl
        add r3, r0, #4*13
        adrl r1, mem_data
        
    0:
        ldr r2, [r1], #4
        str r2, [r0], #4
        cmp r0, r3
        bne 0b    
        mov pc, lr    
        
    copy_to_ram:
        ldr r0, =0x0
        ldr r1, =0x30008000
        add r3, r0, #1024*4
    
    copy_loop:
        ldr r2, [r0], #4
        str r2, [r1], #4
        cmp r0, r3
        bne copy_loop    
        mov pc, lr    
        
    stack_init:
        msr cpsr_c, #0xd2
        ldr sp, =0x33000000  @初始化R13_irq
        msr cpsr_c, #0xd3
        ldr sp, =0x34000000  @初始化R13_svc
        mov pc, lr    
        
    clean_bss:
        ldr r0, =bss_start
        ldr r1, =bss_end
        cmp r0, r1
        moveq pc, lr
        
    clean_loop:
        mov r2, #0
        str r2, [r0], #4
        cmp r0, r1    
        bne clean_loop
        mov pc, lr
    
    mem_data:
        .long 0x22000000
        .long 0x00000700
        .long 0x00000700
        .long 0x00000700
        .long 0x00000700
        .long 0x00000700
        .long 0x00000700
        .long 0x00018001
        .long 0x00018001
        .long 0x008c04f5
        .long 0x000000b1
        .long 0x00000030
        .long 0x00000030        
    
    #define GPBCON 0x56000010
    #define GPBDAT 0x56000014
    light_led:
        ldr r0, =GPBCON
        mov r1, #0x400
        str r1,[r0]
        
        ldr r0, =GPBDAT
        mov r1, #0x0
        str r1, [r0]
        mov pc, lr    
        
  • 相关阅读:
    mac 安装ROS2
    193 最长有效括号
    个人笔记
    个人笔记
    个人笔记-大佬主页
    笔记-吴恩达老师机器学习及深度学习
    个人笔记
    转载-资源链接
    枚举类型
    333333333333333333333333
  • 原文地址:https://www.cnblogs.com/sanshijvshi/p/8395132.html
Copyright © 2011-2022 走看看