打印

关于6410的定时器中断,高手,版主进来救命啊!

[复制链接]
3336|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
跑6410的裸机已经几天了,现在被中断这只拦路虎给截下来了,主要是没有搞懂启动码的问题,现在我贴上我的源程序,希望大家来帮帮忙呐。。。。不甚感激,各位大神们,你们的一句话就能拯救一个中国好青年啊。。这是我的main.c
#define rGPMCON (*(volatile unsigned *)0x7F008820)
#define rGPMDAT (*(volatile unsigned *)0x7f008824)
#define rGPMPUD (*(volatile unsigned *)0x7f008828)

#define rGPFCON (*(volatile unsigned *)(0x7F0080A0))
#define rGPFDAT (*(volatile unsigned *)(0x7F0080A4))
#define rGPFPUD (*(volatile unsigned *)(0x7F0080A8))

#define rGPNCON (*(volatile unsigned *)(0x7F008830))
#define rGPNDAT (*(volatile unsigned *)(0x7F008834))
#define rGPNPUD (*(volatile unsigned *)(0x7F008838))

#define PCLK 66000000  //for S3C6410 66MHZ
#define HCLK 133000000 //for S3C6410 133MHZ
#define rTCFG0 (*(volatile unsigned *)(0x7F006000))
#define rTCFG1 (*(volatile unsigned *)(0x7F006004))
#define rTCON (*(volatile unsigned *)(0x7F006008))
#define rTCNTB0 (*(volatile unsigned *)(0x7F00600C))
#define rTCMPB0 (*(volatile unsigned *)(0x7F006010))
#define rTCNTO0 (*(volatile unsigned *)(0x7F006014))
#define rTCNTB1 (*(volatile unsigned *)(0x7F006018))
#define rTCMPB1 (*(volatile unsigned *)(0x7F00601c))
#define rTCNTO1 (*(volatile unsigned *)(0x7F006020))
#define rTCNTB2 (*(volatile unsigned *)(0x7F006024))
#define rTCNTO2 (*(volatile unsigned *)(0x7F00602c))
#define rTCNTB3 (*(volatile unsigned *)(0x7F006030))
#define rTCNTO3 (*(volatile unsigned *)(0x7F006038))
#define rTCNTB4 (*(volatile unsigned *)(0x7F00603c))
#define rTCNTO4 (*(volatile unsigned *)(0x7F006040))
#define rTINT_CSTAT (*(volatile unsigned *)(0x7F006044))

#define rVIC0INTENABLE (*(volatile unsigned *)(0x71200010))
#define rVIC1INTENABLE (*(volatile unsigned *)(0x71300010))

#define rVIC0VECTADDR  ((volatile unsigned *)(0x71200100))

void IRQ_Exception(void);

void GPIO_Init(void)
{

// 初始化LED的IO配置

rGPMCON = 0x11111;

rGPMPUD = 0x0;

rGPMDAT = 0x1F;

// 初始化蜂鸣器IO配置

rGPFCON = rGPFCON & (~(0x1 << (31)));

rGPFCON = rGPFCON | (0x1 << (2*15));

rGPFPUD = rGPFPUD & (~(0x3 << (2*15))) ;

rGPFDAT = rGPFDAT & 0x7FFF;
}

void timer_init(void)
{

rTINT_CSTAT |= 1<<0;   //开timer0中断,允许timer0中断发生

rVIC0INTENABLE |= 1<<23;  //开timer0的使能(相当于关掉mask)



rTCFG0 &= ~0xFF;  // 清除预分频因子位

rTCFG0 |= 0x42;   // 设置分频因子(66分频), 定时器时钟频率为1Mhz

rTCFG1 &= ~0x11;  // 设置Divider MUX0为零 1分频



rTCNTB0 = 0x100000;   //设初值(1s)



rTCON |= 1<<1;      //开Manual Update (Update TCNTB0,TCMPB0)设置初值后要更新TCNTB

rTCON |= 1<<3;      //Auto Reload on  自动重装开启

rTCON |= 1<<0;        //timer0 open;



rTCON &= ~(1<<1);   //不再Update TCNTB0,TCMPB0
}

// 循环延时
void msDelay(int time)
{

volatile unsigned int i, j;

for(i = 0; i < 2000000; i++)

{

for (j = 0; j < time; j++);

}
}

// 打开控件蜂鸣器的三极管
void BeepOff(void)
{

rGPFDAT = rGPFDAT  & 0x7fff;
}
// 关闭控件蜂鸣器的三极管
void BeepOn(void)
{

rGPFDAT = rGPFDAT | 0x8000;
}

int i = 0;
// IRQ异常中断
void IRQ_Exception()
{

i %= 4;

// 打开一个灯,并闭另外一个灯

rGPMDAT = ~(1<<i++);

BeepOn();

msDelay(5);

BeepOff();



// 清除定时器中断状态位

while((rTINT_CSTAT & 0x20)) rTINT_CSTAT |= (1 << 5);
}

void Main()
{

GPIO_Init();

timer_init();

while(1);
}

这是我的init.s

IMPORT main

IMPORT IRQ_Exception


AREA |C$$code|, CODE, READONLY

ENTRY


start

;interrupt vectors

;中断向量表
Reset

LDR     PC, ResetAddr
    LDR     PC, UndefinedAddr
    LDR     PC, SWI_Addr
    LDR     PC, PrefetchAddr
    LDR     PC, DataAbortAddr
    DCD     0xb9205f80
    LDR     PC, IRQAddr
    LDR     PC, FIRQAddr

ResetAddr           DCD     ResetInit
UndefinedAddr       DCD     Undefined
SWI_Addr            DCD     SoftwareInterrupt
PrefetchAddr        DCD     PrefetchAbort
DataAbortAddr       DCD     DataAbort
                    DCD     0
IRQAddr             DCD     IRQHandler
FIRQAddr            DCD     FIRQHandler

;未定义指令
Undefined

B       Undefined
;软中断
SoftwareInterrupt   
        B       SoftwareInterrupt
;取指令中止
PrefetchAbort
        B       PrefetchAbort
;取数据中止
DataAbort
        B       DataAbort

;
IRQHandler
        STMFD SP!,{r0-r3,r12,lr}           ;保存现场
        ldr lr, =int_return                ;设置中断异常处理程序返回地址到下面的位置
        B  IRQ_Exception                   ;直接进入到中断函数处理
int_return
        LDMFD SP!,{r0-r3,r12,lr}           ;恢复现场
        SUBS PC,LR,#4                      ;返回进入中断前的代码

;
FIRQHandler

STMFD sp!,{r0-r12,lr}   

B      FIRQHandler

LDMFD sp!, {r0-r12,lr}

SUBS  pc, lr,#4   

;禁止中断

DISABLE_IRQ

MRS R0, CPSR

ORR R0, R0, #0x80

MSR CPSR_c, R0

MOV PC, LR


;允许中断
ENABLE_IRQ

MRS R0, CPSR         ;将CPSR保存至R0寄存器中

BIC R0, R0, #0x80    ;R0 = R0 & ~0x80,清除中断位

MSR CPSR_c, R0       ;将R0写回CPSR状态寄存器

MOV PC, LR           ;返回到调用代码
ResetInit

LDR R14, =0x50100000 ;初始化一下栈指针

BL       ENABLE_IRQ  ;打开中断允许位

B       main
     ;跳入MAIN程序

END



现在我的问题是:
谁能告诉我他这个启动码是按照什么流程来写,大概给我一些注释就行(首先是什么,然后是什么,接着是什么,最后是什么)

相关帖子

沙发
wsshopping|  楼主 | 2012-10-5 19:36 | 只看该作者
主要问题在init.s这个问题上

使用特权

评论回复
板凳
阿南| | 2012-10-6 11:39 | 只看该作者
首先是一段各中断(或称异常)的入口,然后在0x0处转到起始处关看门狗、中断等,初始化内存控制器、各异常模式下的堆栈等,安装各中断向量表,再复制镜像代码到内存区运行等。。。
三星的所有处理器的启动代码基本相同,所以详细情况你可以参考《ARM Linux入门与实践》一书的关于S3C2410的启动代码。

使用特权

评论回复
地板
wsshopping|  楼主 | 2012-10-6 16:23 | 只看该作者
3# 阿南 谢谢南哥,在问你一下,我简单的想实现6410定时器的中断,是用这上面的汇编代码还是应该用这个啊mrc p15,0,r0,c1,c0,0  
orr r0,r0,#(1<<24)  
mcr p15,0,r0,c1,c0,0

使用特权

评论回复
5
阿南| | 2012-10-6 16:35 | 只看该作者
定时器中断,首先要初始化定时器寄存器及中断相关的寄存器,使用上面的汇编和那段代码都还不够。
p15是协处理器

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
wsshopping + 1
6
wsshopping|  楼主 | 2012-10-6 19:50 | 只看该作者
5# 阿南 噢,受益良多啊,还有一个就是我上面发的那个程序,用JLINK调试的时候就是进不了定时器中断,真心不晓得为什么,我把我的调试信息贴上,帮忙看看,谢谢啦,我都是按顺序来的!

1.jpg (80.98 KB )

这是我调试开始进入的地方

这是我调试开始进入的地方

2.jpg (89.7 KB )

这是我单步运行一下的图片

这是我单步运行一下的图片

3.jpg (84.81 KB )

这是我运行到主函数处的图片

这是我运行到主函数处的图片

4.jpg (118.37 KB )

这是我全速运行后停止的图片,我感觉有问题,全部是dataAbort

这是我全速运行后停止的图片,我感觉有问题,全部是dataAbort

使用特权

评论回复
7
wsshopping|  楼主 | 2012-10-6 19:52 | 只看该作者
在线等你回复了,程序里面的代码都是上面贴出来了的

使用特权

评论回复
8
阿南| | 2012-10-7 08:31 | 只看该作者
把你调试时设置为混合模式,可以看到反汇编及代码实践的地址数据。
在0x18处设置一个断点,然后跟踪进去看是否是中断向量表没有安装好。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

8

帖子

0

粉丝