作者最近在学习keil和ARM,哎,只能感叹自己老了,这里简单的记录下学习笔记吧。
备注:
这里的代码都是作者自己写的,作者刚开始学习ARM,对于汇编和C的混编时的PUSH和POP也不是非常清楚,不能保证正确性。
程序状态寄存器如下:
(图片来自《Cortex-M3权威指南》,版权归原作者所有)
中断控制及状态寄存器ICSR如下:
(图片来自《Cortex-M3权威指南》,版权归原作者所有)
作者的工程基于【ARM学习随手笔记:使用systick定时器】,修改main函数和中断响应函数:
/* 使用嵌入式汇编,没有使用返回值。增加第二个参数是因为这样可以占用掉R1。 */ __asm void getirq1(int *pIrq, int unused) { MRS R1,IPSR STR R1,[R0,#0x00] BX LR } /* 使用嵌入式汇编,使用返回值,这样R0会被自动占用。 */ __asm int getirq2() { MRS R0,IPSR BX LR } /* 使用内联汇编和虚拟寄存器方式获取IPSR的值,但是M3应该不支持这种语法,但是这里编译通过了,比较奇怪。 */ int getirq3() { int R0; __asm { MRS R0,IPSR } return R0; } /* 直接访问寄存器 */ int getirq4() { return (*((unsigned int *)0xE000ED04)) &0x3FF; } /* SysTick中断响应函数,参考startup_ARMCM3.s */ void SysTick_Handler(void) { int irq1,irq2,irq3,irq4; getirq1(&irq1, 0); irq2 = getirq2(); irq3 = getirq3(); irq4 = getirq4(); printf("SysTick_Handler Called irq1:%d irq2:%d irq3:%d irq4:%d\n",irq1,irq2,irq3,irq4); } int main(void) { unsigned int *pControl = (unsigned int *)(0xE000E010); unsigned int *pReload = (unsigned int *)(0xE000E014); unsigned int *pCurrent = (unsigned int *)(0xE000E018); *pControl = 0; //先关闭SysTick *pReload = 0xFFFFFFF; //设置定时值 *pCurrent = 0; //清理掉当前值 *pControl = 0x7; //启动SysTick while(1) ; }
编译执行后使用模拟器运行如下图:
发表评论