历史上的今天
返回首页

历史上的今天

今天是:2024年10月12日(星期六)

正在发生

2018年10月12日 | Tiny210裸机之按键中断

2018-10-12 来源:eefocus

start.S源码:

.global _start

_start:

    ldr sp, =0xD0030000  // 初始化栈,因为后面要调用C函数 

    bl clock_init                // 初始化时钟 

    bl ddr_init                   // 初始化内存 

    bl nand_init                // 初始化NAND 

    ldr r0, =0x36000000   // 要拷贝到DDR中的位置 

    ldr r1, =0x0                 // 从NAND的0地址开始拷贝 

    ldr r2, =bss_start         // BSS段的开始地址 

    sub r2,r2,r0                  // 要拷贝的大小 

    bl nand_read              // 拷贝数据 

clean_bss:

    ldr r0, =bss_start

    ldr r1, =bss_end

    mov r3, #0

    cmp r0, r1

    ldreq pc, =on_ddr

clean_loop:

    str r3, [r0], #4

    cmp r0, r1    

    bne clean_loop        

    ldr pc, =on_ddr

on_ddr:

    mrs  r0, cpsr

    bic    r0,r0,#0x1f  // 清M4~M0 

    orr    r0,r0,#0x12

    msr    cpsr,r0        // 进入irq 

    ldr sp, =0x3e000000    // 初始化普通中断模式的栈,指向内存 

    bl irq_init

    mrs  r0, cpsr

    bic    r0,r0,#0x9f  // 开总的中断开关,清M4~M0 

    orr    r0,r0,#0x10

    msr    cpsr,r0      // 进入user mode 

    ldr sp, =0x3f000000    // 初始化用户模式的栈,指向内存 

    ldr pc, =main

halt:

    b halt    

.global key_IRQ

key_IRQ:

    sub lr, lr, #4                   // 1.计算返回地址 

    stmdb sp!, {r0-r12, lr}  // 2.保护现场 

    // 3. 处理异常 

    bl do_irq

    

    // 4. 恢复现场 

    ldmia sp!, {r0-r12, pc}^  // ^表示把spsr恢复到cpsr 

===================================================================

irq.c源码:

#include "lib.h"

#define GPH2CON        (*(volatile unsigned int *)0xE0200C40)

#define GPH2DAT        (*(volatile unsigned int *)0xE0200C44)

#define GPH3CON        (*(volatile unsigned int *)0xE0200C60)

#define GPH3DAT        (*(volatile unsigned int *)0xE0200C64)

#define EXT_INT_2_CON        (*(volatile unsigned int *)0xE0200E08)

#define EXT_INT_3_CON        (*(volatile unsigned int *)0xE0200E0C)

#define EXT_INT_2_MASK        (*(volatile unsigned int *)0xE0200F08)

#define EXT_INT_3_MASK        (*(volatile unsigned int *)0xE0200F0C)

#define VIC0INTSELECT        (*(volatile unsigned int *)0xF200000C)

#define VIC0INTENABLE        (*(volatile unsigned int *)0xF2000010)

#define VIC0VECTADDR16        (*(volatile unsigned int *)0xF2000140)

#define VIC0ADDRESS          (*(volatile unsigned int *)0xF2000F00)

#define EXT_INT_2_PEND        (*(volatile unsigned int *)0xE0200F48)

#define EXT_INT_3_PEND        (*(volatile unsigned int *)0xE0200F4c)

int i = 0;

void do_irq(void)

{

    // 清中断 

    EXT_INT_2_PEND |= 1<<3;

    EXT_INT_3_PEND |= 1<<0;

    // 清中断向量 

    VIC0ADDRESS = 0;

    if(!(GPH2DAT & (1<<3)))

    {

        wy_printf("counter(k4) : %d \n",i++);

    }

    if(!(GPH3DAT & (1<<0)))

    {

        wy_printf("counter(K5) : %d \n",i--);

    }

}

extern void key_IRQ(void);

void irq_init(void)

{

    // 设置GPH2_3(K4),GPH3_0(K5)用于中断 

    GPH2CON |= 0xf<<12;

    GPH3CON |= 0xf<<0;

    // 设置触发方式为下降沿触发 

    EXT_INT_2_CON |= 0x2<<12;

    EXT_INT_3_CON |= 0x2<<0;

    // 使能中断(GPIO里面的) 

    EXT_INT_2_MASK &= ~(1<<3);

    EXT_INT_3_MASK &= ~(1<<0);

    // 设置为IRQ中断 

    VIC0INTSELECT &= ~(1<<16);

    // 使能中断(中断控制器里面的) 

    VIC0INTENABLE |= 1<<16;

    // 设置中断向量 

    VIC0VECTADDR16 = (int)key_IRQ;

}

==================================================================

main.c源码:

#include "command.h"

#include "clock.h"

#include "led.h"

#include "uart.h"

#include "lib.h"

#include "nand.h"

#define    CFG_PROMPT        "WY_BOOT # "    // Monitor Command Prompt    

#define    CFG_CBSIZE        256        // Console I/O Buffer Size    

char *argv[10];

int readline (const char *const prompt)

{

    char console_buffer[CFG_CBSIZE];        // console I/O buffer    

    char *buf = console_buffer;

    int argc = 0;

    int state = 0;

    //puts(prompt);

    wy_printf("%s",prompt);

    gets(console_buffer);

    

    while (*buf)

    {

        if (*buf != ' ' && state == 0)

        {

            argv[argc++] = buf;

            state = 1;

        }

        

        if (*buf == ' ' && state == 1)

        {

            *buf = '\0';

            state = 0;

        }

        

        buf++;    

    }

    

    return argc;

}

void message(void)

{

    wy_printf("\nThis bootloader support some command to test peripheral:\n");

    wy_printf("Such as: LCD, IIS, BUZZER \n");

    wy_printf("Try 'help' to learn them \n\n");    

}

int main(void)

{

    char buf[6];

    int argc = 0;

    int i = 0;

    led_init(); // 设置对应管脚为输出 

    uart_init(); // 初始化UART0 

    nand_read_id(buf);

    wy_printf("\n**********************************************************\n");

    wy_printf("                     wy_bootloader\n");

    wy_printf("                     vars: %d \n",2012);

    wy_printf("                     nand id:");

    putchar_hex(buf[0]);

    putchar_hex(buf[1]);

    putchar_hex(buf[2]);

    putchar_hex(buf[3]);

    putchar_hex(buf[4]);

    wy_printf("\n**********************************************************\n");

    while (1)

    {

        argc = readline (CFG_PROMPT);

        if(argc == 0 && i ==0)

        {

            message();

            i=1;

        }

        run_command(argc, argv);

    }

    return 0;

}

==================================================================

Makefile文件:

uart.bin:start.s main.c uart.c clock.c led.c lib.c command.c nand.c mem_setup.S irq.c

    arm-linux-gcc -nostdlib -c start.s -o start.o

    arm-linux-gcc -nostdlib -c main.c -o main.o

    arm-linux-gcc -nostdlib -c uart.c -o uart.o

    arm-linux-gcc -nostdlib -c lib.c -o lib.o

    arm-linux-gcc -nostdlib -c clock.c -o clock.o    

    arm-linux-gcc -nostdlib -c led.c -o led.o    

    arm-linux-gcc -nostdlib -c command.c -o command.o    

    arm-linux-gcc -nostdlib -c nand.c -o nand.o    

    arm-linux-gcc -nostdlib -c irq.c -o irq.o    

    arm-linux-gcc -nostdlib -c mem_setup.S -o mem_setup.o    

    arm-linux-ld -T bootloader.lds start.o main.o uart.o lib.o clock.o led.o command.o nand.o mem_setup.o irq.o -o uart_elf

    arm-linux-objcopy -O binary -S uart_elf uart.bin

clean:

    rm -rf *.o *.bin uart_elf *.dis

    

===================================================================

bootloader.lds链接文件:

SECTIONS {

    . = 0x36000010;

    .text : {

        * (.text)

    }

    . = ALIGN(4);

    .rodata : {

        * (.rodata)

    }

    

    . = ALIGN(4);

    .data : {

        * (.data)

    }

    . = ALIGN(4);

    bss_start = .;

    .bss  : { *(.bss)  *(COMMON) }

    bss_end = .;

}


推荐阅读

史海拾趣

Engineered Components Co公司的发展小趣事

为了确保产品质量和客户满意度,ECC建立了完善的质量管理体系。他们从原材料采购到生产、检测、包装等各个环节都制定了严格的质量标准。ECC还引入了先进的质量检测设备和方法,确保每一件产品都符合高标准的质量要求。此外,ECC还定期对员工进行质量培训,提高员工的质量意识和操作技能。这些措施使得ECC的产品在市场上赢得了良好的口碑和信誉。

Fischer Elektronik公司的发展小趣事

Fischer Elektronik公司成立于1969年,是德国在高性能散热器和半导体制冷领域的领先制造商。成立之初,公司专注于研发和生产电子元器件的关键部件,如散热器和连接器,以满足当时快速增长的电子行业对高效散热解决方案的需求。凭借其精湛的工艺和严格的质量控制,Fischer Elektronik迅速在市场中站稳脚跟,并开始在仪器仪表、通讯/网络、交通/汽车和工业/自动化等领域展露头角。

ddm hopt + schuler GmbH & Co KG公司的发展小趣事

进入21世纪后,ddm hopt + schuler公司紧跟数字化浪潮,积极推动数字化转型和智能制造。公司引入先进的物联网、大数据和人工智能技术,对生产线进行智能化改造和升级。通过实时数据监控和分析,公司能够更准确地预测市场需求、优化生产计划、提高生产效率。同时,智能制造也为企业带来了更高的灵活性和更低的成本。

广州奥松公司的发展小趣事

为了满足市场对于芯片的日益增长的需求,奥松电子决定启动建设8英寸MEMS特色芯片IDM产业基地。这一项目的实施,不仅提升了公司的产能规模,也进一步巩固了公司在电子行业中的地位。通过引进先进的生产设备和技术,奥松电子成功打造了一个集研发、生产、销售于一体的产业基地,为公司的长远发展奠定了坚实的基础。

动运科技(DONGWOON)公司的发展小趣事

在全球化的大背景下,企业之间的合作与共赢成为了一种趋势。动运科技积极寻求与全球知名企业的战略合作,共同推动电子行业的发展。例如,公司与香港希荻微的合作就是一个典型的例子。通过独占许可的方式,希荻微获得了动运科技在中国大陆及港澳台地区生产、销售与自动对焦及光学防抖技术相关的产品的权利,并有权使用授权技术进行技术改进及新产品研发。这一合作不仅为双方带来了互利共赢的机会,也为整个电子行业的发展注入了新的活力。

FORMOSA公司的发展小趣事

随着物联网和智能家居概念的普及,一家名为“FORMOSA智能科技”的公司专注于研发和生产智能家居硬件产品。该公司推出的智能音箱、智能门锁、智能照明等系列产品,凭借其出色的性能、便捷的操作和良好的用户体验,在市场上迅速获得了消费者的青睐。FORMOSA智能科技还积极与各大智能家居平台进行合作,实现了产品的互联互通和智能化管理。通过不断的技术创新和市场拓展,该公司成功推动了智能家居产品的普及和应用。

问答坊 | AI 解惑

使DC/DC变换器限流特性线性化的热敏电阻器网络

核心器件: MAX1714 最近推出的各种集成式降压   DC/DC变换器均已采取对外接低侧MOSFET同步整流器的电压降采样的方法,无需高侧电流检测电阻器。这种拓扑节省了检测电阻器的成本和印制电路板的空间,也适当提高了电路效率。但是,MOS ...…

查看全部问答>

电子系统设计基本知识

本文有模拟电路、数字电路、单片机电路、ARM硬件、ARM编程等基础知识,里面还有电阻、电容、半导体二级管三极管等元器件的介绍,还有电源电路、电路设计、通信系统等。欢迎想学电子基础知识的人下载。…

查看全部问答>

我的超声波带原理图与PCB

本帖最后由 paulhyde 于 2014-9-15 03:46 编辑 我的超声波带原理图与PCB  …

查看全部问答>

大家A有整体方案了没有

本帖最后由 paulhyde 于 2014-9-15 09:04 编辑 大家A有整体方案了没有  …

查看全部问答>

单片机实现液晶显示的开发方案

我们的产品希望用液晶屏显示,不知各位高人有什么比较好的实现方法吗?(接口可以是232或者485)…

查看全部问答>

三星S3C241O的中断问题

我最近在学华恒ARM9,用的是三星S3C2410当做到中断这个问题的时候,遇到了问题,还请各位大虾帮忙 问题如下: 1、不管我把中断置一还是置零都没看到区别,和芯片资料有出入,为什么会这样 2、我把中断待决寄存器和源待决寄存器的值读出来,发现 ...…

查看全部问答>

请问哪里有无线协议的详细文档下载?

刚学GPRS开发,想找些无线通讯协议看看,google了一下,没找到,所以想请教一下,哪里有这一类的完整文档下载,谢谢!…

查看全部问答>

超新手弱弱问题----关于定时器的问题

这几天在看书,发现里面说到定时器a和定时器b,我想问一下,定时器是不是属于单片机里面一个硬件呢?应该不是在msp430芯片里面的吧???…

查看全部问答>

求助。。。。

用iar for msp430怎么下载程序到430里? 求具体过程,最好能有×××××× 还有就是怎么看程序是否在下载?单片机是否在运行? 本人初学,只有一点51的基础,还请各位多多指教…

查看全部问答>

液晶屏初始化时花屏了,求助!

液晶屏初始化时花屏了!(LCD12864带字库的)LCD12864 带字库的。在我对液晶屏初始化时,设置到“进入设定点”这一步,用api函数SSIDataPut(SSI_BASE, data) 发送命令字0x06,就花屏了!这是为什么? …

查看全部问答>