Chinaunix首页 | 论坛 | 博客
  • 博客访问: 260287
  • 博文数量: 49
  • 博客积分: 1400
  • 博客等级: 上尉
  • 技术积分: 540
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-08 10:33
文章分类

全部博文(49)

文章存档

2010年(2)

2009年(30)

2008年(17)

我的朋友

分类:

2009-01-05 14:13:03

实现功能:GPF0和GPF1接的两个按键,GPB0和GPB1接两个LED,用中断方式按GPF0时,GPB0亮,按GPF1时,GPB1亮。
实验程序:
.extern  main
.text
.global _start
_start:
 b reset
HandleUndef:
 b HandleUndef @未定义指令终止模式
HandleSWI:
 b HandleSWI @管理模式地址
HandlePrefetchAbort:
 b HandlePrefetchAbort @指令预取终止模式
HandleDateAbort:
 b HandleDateAbort  @数据访问终止模式
HandleNotUsed:
 b HandleNotUsed  @保留
 b HandleIRQ  @IRQ中断模式
HandleFIQ:
 b HandleFIQ
reset:
 ldr sp,=1024*4  @复位模式的堆栈
 bl watch_dog  @关闭看门狗   
 msr cpsr_c,#0xd2  @进入中断模式
 ldr sp,=1024*3  @中断模式的栈地址
 msr cpsr_c,#0xdf  @系统模式
 ldr sp,=1024*4
 bl led_init  @led初始化
 bl Interupt_init  @中断初始化函数
 msr cpsr_c,#0x5f  @开启中断
 ldr lr,=loop  @此两句调用也可用bl main语句
 ldr pc,=main
loop:
 b loop
HandleIRQ:
 sub lr,lr,#4  @计算返回地址
 stmdb sp!,{r0-r12,lr}  @保存使用到的寄存器
 ldr lr,=int_return
 ldr pc,=Inter_Handle @调用中断处理函数
int_return:
 ldmia sp!,{r0-r12,pc}^ @中断返回 
 
初始化程序:
#include "s3c2410.h"
#define  GPB0_out (1<<(0*2))
#define  GPB1_out (1<<(1*2))
#define   GPF0_eint (2<<(0*2))
#define   GPF1_eint (2<<(1*2))
//#define  GPF0_disup (1)
//#define GPF1_disup (1<<1)
#define  eint0  (~1)
#define  eint1  (~(1<<1))
#define  ARB_mode0 (~1)
#define  ARB_mode6 (~(1<<6))
void watch_dog()
{
    WTCON  = 0;
}
void led_init()
{
   GPBCON  |=  (GPB0_out | GPB1_out);
   GPFCON  |=  (GPF0_eint | GPF1_eint);
  // GPFUP   |=  (GPF0_disup | GPF1_disup);
}
void Interupt_init()
{
  //EXTINT0 |= (3<<0)|(3<<3);
  INTMSK &= (eint0 & eint1);
 
  PRIORITY = (PRIORITY & ((~0x01) | (0x3<<7)))  ;
  //RIORITY &= (ARB_mode0 & ARB_mode6);
 
}
 
中断服务程序:
#include "s3c2410.h"
void Inter_Handle()
{
    unsigned long key_down;
    key_down = INTOFFSET;
    switch(key_down)
    {
        case 0:
              {
                GPBDAT |= 0x03;   //此语句重要,若没有它,将会出现全亮
                GPBDAT &= (~1);
                break;
              }
        case 1:
              {
                GPBDAT |= 0x03;
                GPBDAT &= (~(1<<1));
                break;
              }
        default:
         break;
    }
    SRCPND = (1<    INTPND = (1<   
}
主函数:
int main()
{
    while(1);
    return 0;
}
 
试验中遇到的问题:
主要是arm汇编指令 B 和 BL指令,用B指令调用时,直接跳转到给定的地址,而不保存R14, BL指令与B指令不同的是保存R14,所以在这个实验中,最开始用的是B指令,怎么调也没有调出来,郁闷坏了。之后用BL指令,一烧写就好使了。还有就是其中这条语句: GPBDATA |= 0x03,这条语句也很重要。若没有这条语句,
经过一两次,就变成全亮了。低两位全为0了。
阅读(1423) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

奥特曼不打怪2018-06-25 11:18:15

这个裸机怎么用?有没有具体步骤?