神灯亮起来

过去有个“傻瓜相机”,现在的软件开发也是越来越傻瓜化,在一个没有各种库,没有各种GUI的乌起码黑的世界里,LED神灯犹如"希望",值得我们去膜拜。

一个6410的例子,现在看来有点过时。

 

汇编语言 + C语言混编

一、汇编代码部分

.globl _start
.globl delay
_start:

   /* 硬件相关设置 */
    ldr r0, =0x70000000
    orr r0, r0, #0x13
    mcr p15,0,r0,c15,c2,4       @ 256M(0x70000000-0x7fffffff)
    
     /* 关闭看门狗 */
	ldr r0, =0x7E004000
	mov r1, #0
	str r1, [r0]

	/* 设置栈 */
	ldr sp, =8*1024  //6410's cpu上的8K
	mov r0, #2
	mov r1, #8
	bl led_ctl     //asm->c
halt:
	b halt	

delay:
delay_loop:		
	cmp r0, #0
	sub r0, r0, #1
	bne delay_loop
	mov pc, lr

  

二、高级语言部分

汇编调用c 函数,同时给c传递参数,也就是参数寄存器赋值,(r0,r1)。

void delay(int count);


int led_ctr(int a, int b)
{
	int i = 0;
	int k = a + b;  //传进来2和8,那么k = 10
	volatile unsigned long *gpmcon = (volatile unsigned long *)0x7F008800;
	volatile unsigned long *gpmdat = (volatile unsigned long *)0x7F008808;
	
	/* gpm 0,1,2,3设为输出引脚 */
	*gpmcon = 0x11110000;
	

    
	while (k--)     /*循环10次,灯闪烁10次*/
	{
		*gpmdat = i;
		i += 16;
		if (i == 240)
		  i = 16;
		delay(5000000);  //c->asm
	}

	return 0;
}

这里c函数又调用汇编,而r0自然等于5000000。

没有定时器,用循环实现延时。

  

然后将程序编译成.bin烧入内存一个地址,比如0c000000,然后go 0c000000。

哈哈,神灯就这么闪了十下,asm->c 的参数传对了。但延时比较短,因为是汇编的缘故,灯闪烁的较快,若用c实现delay,灯会慢许多。

一直以来,将心思放在内核代码,偶然发现,仔细研究下arm五花八门的控制器,也是一种乐趣,毕竟软件的基础是硬件,硬件的大脑就是这么个arm,若能充分了解arm寄存器的控制,对内核的理解才会突破瓶颈,柳暗花明。

 

End.

posted @ 2011-07-27 16:42  郝壹贰叁  阅读(518)  评论(0编辑  收藏  举报