您的位置:首页 > 其它

LED流水灯(二)

2015-10-18 14:25 225 查看
记住看汇编的时候是红在上面 黑色在下面startup.s 程序; MDK跑马灯实验
;
  PRESERVE8 // 字节对齐关键词 ,汇编有8位对齐的要求,要添加  AREA RESET, CODE, READONLY // AREA 伪指令 用于定义一个代码段或数据段,这里就是一个 代码段,段名为 RESET ,定义成 只读 ,参考 http://blog.csdn.net/beyondioi/article/details/7854011
  ENTRY // ENTRY伪指令用于指定汇编程序的入口点 ,参考 http://blog.csdn.net/beyondioi/article/details/7854011 start // 作为汇编程序的一个标号,定义了程序的入口,既程序从start:处开始执行。 缺省也是可以的,但是奇怪的是 这里怎么没有 : 冒号啊,不是必须添加的吗???; 关闭看门狗
  ldr r0, = 0x53000000 ; 将看门狗控制寄存器地址放入r0 // 寄存器也是有地址的 参考 s3C2440 手册或者书 99页,watch dog 地址 便是 0x53000000 ,可以看知乎: http://www.zhihu.com/question/30155201?sort=created   mov r1, #0 //
  str r1, [r0] ; 设置看门狗控制寄存器的值为0, str 指令 将r1寄存器的值,传送到地址值为r0的(存储器)内存中  bl initmem ; 跳转到initmem代码段,初始化内存 // 黄色箭头指到这里的时候,使用

图标,跳转到 initmem 标号的代码中IMPORT xmain ; 引入xmain.c中的xmain函数
 ldr sp, =0x34000000 ; 调用C程序之前先初始化栈指针
  ldr lr, =endxmain ; 设置xmain函数的返回地址 为什么PC+ 0x0070
  ldr pc, =xmain ; 跳转到C程序中的xmain函数的入口处执行endxmain
  ldr r0, =0x56000010 ; LED的GPIO接口配置寄存器
  ldr r1, =0x00015400 ; GPIO配置数据
  str r1, [r0] ; 设置GPIO
  ldr r0, =0x56000014 ; LED控制寄存器地址
  ldr r1, =0x000000e0 ; 全部LED亮
  str r1,[r0]
loop
  b loop ; 死循环initmem ; 内存初始化
  ldr r0, =0x48000000 ; 加载内存相关寄存器首地址r0
  ldr r1, =0x48000034 ; 加载内存相关寄存器尾地址到r1 // 相当于 LDR R1 ,[PC,#0x0058] 参考书 ARM体系(P85也),将内存单元 PC+0x0058 中的字读取到 R0 寄存器中,

计算机为什么会 这样做呢?? PC=0x3C 加上 0x58 还是 94啊 不是 9C 相差了 8位,有点乱了,不过差不多了  adr r2, memdata ; 将寄存器配置数据地址段首地址加载到r2
PC=0x000040 + 0x00010 = 0x00050 + 8 (也相差8位),读到了, R2=58 ,这么说来 R2 原来就是 0initmemloop
  ldr r3, [r2], #4 ; 循环设置存寄存器 ,将地址为R2的内存单元数据读取到 r3 中,并且 R1=R1+4
  str r3, [r0], #4 ; 与上面一样
  teq r0, r1
  bne initmemloop ; 循环到最后一个寄存器时退出函数,BNE指令,是个条件跳转,即:是“不相等(或不为0)跳转指令”。如果不为0就跳转到后面指定的地址,继续执行  BX lr ; mov pc,lrmemdata
  DCD 0x22000000 ;BWSCON // PC 指针 0X000058
  DCD 0x00000700 ;BANKCON0
  DCD 0x00000700 ;BANKCON1
  DCD 0x00000700 ;BANKCON2
  DCD 0x00000700 ;BANKCON3
  DCD 0x00000700 ;BANKCON4
  DCD 0x00000700 ;BANKCON5
  DCD 0x00018005 ;BANKCON6   
  DCD 0x00018005 ;BANKCON7
  DCD 0x008e07a3 ;REFRESH
  DCD 0x000000b1 ;BANKSIZE
  DCD 0x00000030 ;MRSRB6
  DCD 0x00000030 ;MRSRB7  END第二个函数 cmain.c 函数
/*C语言函数*/
/*端口F寄存器预定义*/

#define    GPBCON        (*(volatile unsigned long *)0x56000010)  // GPBCON   控制寄存器的地址
#define    GPBDAT        (*(volatile unsigned long *)0x56000014)
#define LEDS           (1<<5|1<<6|1<<7|1<<8)
#define DELAYVAL    (0xffff)

extern int delay(int time); /*声明汇编函数*/

int xmain(void)
{
int i = 3;
GPBCON = 0x00015400;// 定义了 四个LED 都为输出端口
while(i>0)
{
GPBDAT=(GPBDAT&(~LEDS)) | (1<<6|1<<7|1<<8);  //  LED1 亮了,其余灭
delay(DELAYVAL);//调用汇编语言编写的延时程序

GPBDAT=(GPBDAT&(~LEDS)) | (1<<5|1<<7|1<<8);   // LED2 亮了,其余灭
delay(DELAYVAL);//调用汇编语言编写的延时程序

GPBDAT=(GPBDAT&(~LEDS)) | (1<<5|1<<6|1<<8);   // LED3 亮了,其余灭
delay(DELAYVAL);//调用汇编语言编写的延时程序

GPBDAT=(GPBDAT&(~LEDS)) | (1<<5|1<<6|1<<7);   // LED4 亮了,其余灭
delay(DELAYVAL);//调用汇编语言编写的延时程序
i--;
}
return 0;
}
现在我们主要老讨论下面这两行代码:
#define LEDS           (1<<5|1<<6|1<<7|1<<8)

GPBDAT=(GPBDAT&(~LEDS)) | (1<<6|1<<7|1<<8);  //  LED1 亮了,其余灭

这个可以去看 另外一篇 LED 随笔,终于懂了啊


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: