• 定时器裸机程序


    硬件平台:JZ2440 

    实现功能:以定时器来控制led闪烁

    start.s           -->  关闭看门狗,设置中断向量表,初始化中断定时器0

    init.c             -->  初始化函数

    interrupt.c    -->  中断服务函数

    main.c         -->  死循环

    s3c2440.h   -->  寄存器映射

    start.s 源码:

    .extern main timer0_interrupt
    .text
    .global _start
    _start:
    
    @ 异常向量表
    @0x00 reset
    b Reset
    
    @0x04 未定义指令异常
    Handle_Undef:
    b Handle_Undef
      
    @0x08 软件中断异常
    Handle_SWI:
    b Handle_SWI
    
    @0x0c 预取指令异常
    Handle_PrefectchAbort:
    b  Handle_PrefectchAbort
    
    @0x10 数据访问异常
    Handle_DateAbort:
    b Handle_DateAbort
    
    @0x14  保留异常
    Handle_NotUsed:
    b Handle_NotUsed
    
    @0x18  外部中断请求异常
    b  Handle_IRQ
    
    @0x1c  快速中断请求异常
    Handle_FIQ:
    b   Handle_FIQ
    
    Reset:                   @复位进入超级用户模式
          ldr sp,=4096
          bl watchdog_init
          bl clock_init
          bl sdram_init
          bl copy_steppingstone_to_sdram
          ldr pc,=on_sdram
    on_sdram:  
          msr cpsr_c,#0xd2   @进入中断模式
          ldr sp,=4096    
    
          msr cpsr_c, #0xdf    @ 进入系统模式
          ldr sp, =0x34000000
          
          bl led_init
          bl timer0_init
          bl interrupt_init  
          msr cpsr_c,#0x5f  @进入系统模式
          
          ldr lr,=main_loop
          ldr pc,=main 
    main_loop:
           b   main_loop 
    
    Handle_IRQ:
          sub lr,lr,#4
          stmdb sp!,{r0-r12,lr}       
                    
          ldr lr,=IRQ_return
          ldr pc,=timer0_interrupt
    IRQ_return:
          ldmia sp!,{r0-r12,pc}^
                 
         

    init.c 源码:

      

    #include"s3c2440.h"
    
    void watchdog_init(void)
    {
        WTCON=0;
    }
    
    void clock_init(void)
    {
        LOCKTIME=0x00ffffff;
        MPLLCON=((0x5c<<12)|(0x01<<4)|(0x02));     //fclk 200MHZ   hclk  100MHZ    pclk  50MHZ
         CLKDIVN=0x03;
        
        __asm__
        (
          "mrc p15,0,r0,c1,c0,0
    "
          "orr r0,r0,#0xc0000000
    "
          "mcr p15,0,r0.c1,c0,0
    "
        );
    }
    
    void sdram_init(void)
    {
        unsigned long *p=(unsigned long *)0x8000000;
        p[0]=0x22011110;
        p[1]=0x00000700;
        p[2]=0x00000700;
        p[3]=0x00000700;
        p[4]=0x00000700;
        p[5]=0x00000700;
        p[6]=0x00000700;
        p[7]=0x00018005;
        p[8]=0x00018005;
        p[9]=0x008c04f4;
        p[10]=0x0000000b1;
        p[11]=0x000000030;
        p[12]=0x000000030;
    }
    
    
    void copy_steppingstone_to_sdram(void)
    {
        unsigned int  *sour=(unsigned int *)0x00000000;
        unsigned int  *dest=(unsigned int *)0x30000000;
        
        while(sour<(unsigned int *)4096)
        {
            *dest=*sour;
            dest++;
            sour++;
        }
    }
    
    void led_init(void)
    {
        GPFCON=(1<<8)|(1<<10)|(1<<12);
    }
    
    
    void timer0_init(void)
    {
        TCFG0=99;
        TCFG1=0x03;
        TCON=11;
        TCNTB0=31250;
        TCMPB0=0;
    }
    
    void interrupt_init(void)
    {
        INTMASK&=(~(1<<10));
    }

    interrupt.c 源码:
     

    #include"s3c2440.h"
    
    
    void timer0_interrupt(void)
    {
        if(INTOFFSET==10)  GPFDAT=~(GPFDAT&(0x7<<4));    
        SRCPND=1<<INTOFFSET;
        INTPND=INTPND;
        
    }

    main.c 源码:

    int main(void)
    {
        while(1);return 0;
    }

    s3c2440.h 源码:

    #ifndef _S3C2440_H_
    #define _S3C2440_H_
    
    //看门狗
    #define WTCON       (*(unsigned long *)0x53000000)
    
    //时钟
    #define LOCKTIME    (*(unsigned long *)0x4c000000)
    #define MPLLCON     (*(unsigned long *)0x4c000004)
    #define UPLLCON     (*(unsigned long *)0x4c000008)
    #define CLKCON      (*(unsigned long *)0x4c00000c)
    #define CLKSLOW     (*(unsigned long *)0x4c000010)
    #define CLKDIVN     (*(unsigned long *)0x4c000014)
    #define CAMDIVN     (*(unsigned long *)0x4c000018)
    
    //sdram
    #define BWSCON      (*(unsigned long *)0x48000000)
    #define BANKCON0    (*(unsigned long *)0x48000004)
    #define BANKCON1    (*(unsigned long *)0x48000008)
    #define BANKCON2    (*(unsigned long *)0x4800000C)
    #define BANKCON3    (*(unsigned long *)0x48000010)
    #define BANKCON4    (*(unsigned long *)0x48000014)
    #define BANKCON5    (*(unsigned long *)0x48000018)
    #define BANKCON6    (*(unsigned long *)0x4800001C)
    #define BANKCON7    (*(unsigned long *)0x48000020)
    #define REFRESH     (*(unsigned long *)0x48000024)
    #define BANKSIZE    (*(unsigned long *)0x48000028)
    #define MRSRB6      (*(unsigned long *)0x4800002C)
    #define MRSRB7      (*(unsigned long *)0x48000030)
    
    //GPIO
    #define GPFCON      (*(unsigned long *)0x56000050)
    #define GPFDAT      (*(unsigned long *)0x56000054)
    
    //TIMER0
    #define TCFG0       (*(unsigned long *)0x51000000)
    #define TCFG1       (*(unsigned long *)0x51000004)
    #define TCON        (*(unsigned long *)0x51000008)
    #define TCNTB0      (*(unsigned long *)0x5100000c)
    #define TCMPB0     (*(unsigned long *)0x51000010)
    #define TCNTO0      (*(unsigned long *)0x51000014)
    
    //INTERRUPT
    #define INTMASK     (*(unsigned long *)0x4a000008)
    #define SRCPND      (*(unsigned long *)0x4a000000)
    #define INTPND      (*(unsigned long *)0x4a000010)
    #define INTOFFSET   (*(unsigned long *)0x4a000014)
    
    #endif

    连接脚本 timer.lds:

    SECTIONS
    {
        . =0x30000000;
        .text                : {*(.text)}
        .rodata  ALIGN(4)    : {*(.rodata)}
        .data    ALIGN(4)    : {*(.data)}
        .bss     ALIGN(4)    : {*(.bss) *(COMMON)}
    }

    Makefile:

    objs:=start.o init.o main.o interrupt.o
    
    timer.bin:$(objs)
        arm-linux-ld -Ttimer.lds -o timer_elf $^
        arm-linux-objcopy -O binary -S timer_elf $@
        arm-linux-objdump -D -m arm timer_elf > timer.dis
        
    %.o:%.c
        arm-linux-gcc  -o $@ -c $<
    %.o:%.s 
        arm-linux-gcc -o $@ -c $<
        
    clean:
        rm -f *.o *.bin *.dis timer_elf
  • 相关阅读:
    linux打包解压包(.tar .gz .tar.gz .zip)
    centos安装fusesshfs通过挂载目录实现数据双向同步
    WSL远程访问Windows下的MySQL方法
    Linux中hugepage的使用方法
    Python科普系列——类与方法(下篇)
    Treevalue(0x02)——函数树化详细解析(上篇)
    Treevalue(0x03)——函数树化详细解析(下篇)
    Python科普系列——类与方法(上篇)
    个人网站迁移之旅:从博客到知识库,从 Hexo 到 Docusaurus
    wpf 动画结束后保留end值,动画结束后会失去绑定,可以在completed事件重新进行绑定
  • 原文地址:https://www.cnblogs.com/zsy12138/p/10408245.html
Copyright © 2020-2023  润新知