首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

ARM开发调试笔记心得(转)(6)

ARM开发调试笔记心得(转)(6)

四.出现的问题与解决方法
        1> CPU进不了中断,即跳不到IRQ中断向量入口地址。
        原因是打开了Memory窗口,观察中断相关的寄存器。AXD软件为了在Memory窗口中刷新这些寄存器值,在程序运行过程中会访问CPU中相应寄存器值。当中断源触发后,在跳到IRQ的中断入口之前,IRQ的中断向量寄存器AIC_IVR就因为上述原因被读过 ,这时CPU就认为已经完成对IRQ中断的处理,因此
就不再跳转到IRQ中断入口。
        2> 刚一执行“MSR CPSR_c,#Mode_USR”语句使能IRQ中断,CPU就立即产生IRQ中断。
        原因当上一次产生IRQ中断后,没有读PIO的中断状态寄存器,将其清零。因为中断状态寄存器置1时表示自从上一次读取此寄存器,至少检测到了一次电平变化。所以当没有读该寄存器时,该状态位会一直保持着。又因为在重新装载程序进行调试时,没有复位目标CPU,所以当使能IRQ中断后,由于PIO中断状态寄存器为1的原因而产生中断。
        五.总结
        个人认为ARM的中断与51的中断,在本质上并没有多大的区别,出现上述的问题是由于它们在仿真、调试时的差异造成。在用普通的51仿真器进行仿真、调试时,如果我们不进行如单步、全速等执行程序运行,内部的各种寄存器、状态寄存器等是不会改变的,此时目标的CPU处于停止一样。而用ARM仿真器进行仿真、调试时,当你不进行如单步、全速等执行程序运行,内部的各种寄存器、状态寄存器还可能会改变,目标的CPU还会处处响应外部,这种情况在调试内部定时器时会更加明显。

地址重映射控制实验与重映射后的中断实验
一.背景
        无论如何,ARM的中断向量地址都是固定的,它总是位于0x00开始往下的32个字节,而这些代码位于ROM区。当用仿真器进行调试时,由于修改不了ROM区的内容,所以在调试中断时,就不能在中断向量表处执行相应的指令进入用户的中断处理程序入口。解决问题的方法就是进行地址重映射,将原来地址为0x00200000开始的SRAM重映射到以0x0开始处。
        重映射功能的另外一个好处就是将原来在ROM区的用户程序映射到RAM区,因为RAM的读写速度要比ROM的读写速度快很多,所以在执行程序时就不会出现由于ROM的读写反应速度跟不上而使CPU处于等待状态,提高了CPU性能。这个功能我也没有试过,有兴趣的可以亲自试验一下。
二.实验目的
        1>执行重映射命令后,使原来地址为0x00200000开始的SRAM重映射到以0x0开始处。将原来地址为0x0开始的Flash ROM重映射到以0x00100000开始处。可用Memory窗口观察0x0和0x00100000开始的内容查看是否实现上述功能。
        2>当产生IRQ中断后,利用重映射的功能,使程序能够跳转到设定好了的用户中断处理程序入口(AT91F_Default_IRQ_handler)。
三.实验程序和参数设置
        参见附件
四.出现的问题与解决方法
        1> 在调试过程中,(特别是全速运行)有时会进入Undefined Instruction及Data Abort等异常。
        原因是由地址重映射命令引起。有时在重新装载程序而没有复位目标CPU时(此时目标CPU仍处于重映射状态),再次执行了重映射命令。
五.总结
        1> 当执行地址重映射命令,使进入重映射后,如果再次执行该命令会使它恢复重映射前的状态。

I2C接口实验
注:在AT91SAM7Sxx系列中,I2C称作TWI。
一.实验目的
能够正确读写I2C接口芯片存储器(24C02),即写入24C02的数据与读出来的数据相同。
二.实验程序和参数设置
1> 连接器选项设置和启动代码与上一个实验相同
2> I2C驱动程序
ATMEL官方网站上有这方便的参考程序。主要由I2C接口的初始化、I2C的读和写三部分组成。
#include "board.h"
#include "twi.h"
void InitTwi(void)
{ AT91F_TWI_CfgPIO(); //配置TWI的TWD和TWCK管脚 AT91F_PIO_CfgOpendrain(AT91C_BASE_PIOA,(unsigned int)AT91C_PA3_TWD);
AT91F_TWI_CfgPMC (); //使能TWI外围时钟
AT91F_TWI_Configure (AT91C_BASE_TWI); //将TWI设置成主模式
AT91F_SetTwiClock(AT91C_BASE_TWI); //计算、设置时钟发生寄存器
}
//*----------------------------------------------------------------------------
//* n AT91F_SetTwiClock
//*计算、设置TWI时钟发生寄存器
//*----------------------------------------------------------------------------
void AT91F_SetTwiClock(const AT91PS_TWI pTwi)
{ int sclock;
sclock = (10*MCK /AT91C_TWI_CLOCK);
sclock = (MCK /AT91C_TWI_CLOCK);
if (sclock % 10 >= 5)
sclock = (sclock /10) - 5;
else
sclock = (sclock /10)- 6;
sclock = (sclock + (4 - sclock %4)) >> 2; // div 4
pTwi->TWI_CWGR = 0x00010000 | sclock | (sclock << 8);
}
//*----------------------------------------------------------------------------
//* n AT91F_TWI_Write
//* rief Send n bytes to a slave device
//*----------------------------------------------------------------------------
int AT91F_TWI_Write(const AT91PS_TWI pTwi ,int address, char *data2send, int size)
{ unsigned int status;
pTwi->TWI_MMR=(AT91C_EEPROM_I2C_ADDRESS| AT91C_TWI_IADRSZ_1_BYTE ) & ~AT91C_TWI_MREAD;
pTwi->TWI_IADR = address; // Set TWI Internal Address Register
status = pTwi->TWI_SR;
pTwi->TWI_THR = *(data2send++);
pTwi->TWI_CR = AT91C_TWI_START;
while (size-- >1){ // Wait THR Holding register to be empty
while (!(pTwi->TWI_SR & AT91C_TWI_TXRDY));
pTwi->TWI_THR = *(data2send++);// Send first byte
}
pTwi->TWI_CR = AT91C_TWI_STOP;
status = pTwi->TWI_SR;
while (!(pTwi->TWI_SR & AT91C_TWI_TXCOMP)); // Wait transfer is finished
return AT91C_EEPROM_WRITE_OK;
}
继承事业,薪火相传
返回列表