s5pv210 用汇编点亮led灯

一,分析硬件工作原理

1.LED灯的物理特性

LED本身有2个接线点,一个是LED的正极,一个是LED的负极。LED这个硬件的功能就是点亮或者不亮

物理上想要点亮一颗LED只需要给他的正负极上加正电压即可,要熄灭一颗LED只需要去掉电压即可。

二, 分析原理图

通过原理图分析,发现LED灯 D22, D23, D24, D25 分别受 寄存器 GPJ0_3 , GPJ0_4, GPJ0_5, PWMTOUT1 控制

4个LED灯的阳极都连接到3.3v的电源 VDD_IO 上, 四个阴极连接到Soc的引脚上,通过Soc来控制LED阴极来输出正电平(1)或负电平(0),使得LED灯两端电压发生改变 控制LED灯的亮灭 。

 

 

 

三, 分析数据手册

1. 通过原理图分析发现,LED灯的阴极受GPJ0寄存器的控制,所以得先了解GPJ0寄存器

2 .通过编程控制Soc中的GPJ0寄存器来操控LED的亮灭

3. GPJ0 :general purpose input output 通用输入输出

4. GPIO就是芯片的引脚(芯片上的引脚有些不是GPIO,只有一部分是),作为GPIO的这类引          脚,他的功能和特点是可以被编程控制它的工作模式,也可以编程控制他的电压高低等。

5. GPJ0相关的寄存器有以下:

  GPJ0CON, (GPJ0 control)GPJ0控制寄存器,用来配置各引脚的工作模式    
  GPJ0DAT, (GPJ0 data)当引脚配置为input/output模式时,寄存器的相应位和引脚的电平高低    相对应。
  GPJ0PUD, (pull up down)控制引脚内部弱上拉、下拉 

  GPJ0DRV, (driver)配置GPIO引脚的驱动能力
  GPJ0CONPDN,(记得是低功耗模式下的控制寄存器)
  GPJ0PUDPDN  (记得是低功耗模式下的上下拉寄存器)
   注:在驱动LED点亮时,应该将GPIO配置为output模式。

  (写)输出  CPU向外部输出, (读)输入  CPU接收外部数据

6 .实际上真正操控LED的硬件,主要的有:GPJ0CON, GPJ0DAT 这么2个。
7. 如何点亮LED,编程的步骤是:
    1、操控GPJ0CON寄存器中,选中output模式
    2、操控GPJ0DAT寄存器,相应的位设置为0

GPJ0端口一共有8个引脚,分别记住:GPJ0_0 ~ GPJ0_7 , 相关重要寄存器就是GPJ0CON和GPJ0DAT

GPJ0CON寄存器中设置8个引脚的工作模式(32/8=4,每个引脚可以分到4位,譬如GPJ0_0对应的bit位为bit0~bit3,GPJ0_3对应的位为bit12~bit15。工作方法是:给相应的寄存器位写入相应的值,该引脚硬件就会按照相应的模式去工作。譬如给bit12~bit15写入0b0001,GPJ0_3引脚就成为输出模式了)

四, 找到相关的SFR(特殊功能寄存器) 

即GPJ0C0N GPJ0DAT 这两个寄存器

GPJODAT 寄存器中有8个bit为  0——7每一个位 写0或1来控制 GPJOCON寄存器的 GPJOCON_0———7的7个引脚
每一个寄存器是32位的,用到的位就配置,其他未用到的未就随便配置都没有影响
 

五, 写代码设置寄存器得到想要的效果

1. 汇编实现流水灯

//实现led流水灯效果


#define GPJ0CON 0xE0200240    
#define GPJ0DAT 0xE0200244

.global _start
_start:                                //_start 是一个符号,是汇编程序的的默认入口标号,每一 
                                       //个汇编程序的开头都要有
	                                   // r0 --r17 通用寄存器
	//第一步对GPJ0CON寄存器进行模式设置
	ldr r0, =0x11111111                //从后面的“=” 可以看出 ldr 是伪指令, 因为需要编译器 
                                       //来判断这个数是合法立即数还是非法立即数 一般写代码都 
                                       //用ldr伪指令ldr把0x11111111数据读到 r0 通用寄存器中
	ldr r1, =GPJ0CON                   
	str r0, [r1]                       //寄存器的间接寻址, 功能是把r0中的数写入到r1中的数为 
                                       //地址的内存中去

	//循环体,led亮灭循环
flash:
	 //D4亮
	ldr r0, =(0<<3 | 1<<4 | 1<<5)      //把0写入到GPJODAT寄存器中,引脚即输出低电平,LED亮
	ldr r1, =GPJ0DAT
	str r0, [r1]

	//延时函数
	bl delay      //调用函数

	//D5亮  D4灭
	ldr r0, =(1<<3 | 0<<4 | 1<<5)
	ldr r1, =GPJ0DAT
	str r0, [r1]

	//延时

	bl delay      //调用函数
	//D6亮 D5灭

	ldr r0, =(1<<3 | 1<<4 | 0<<5)
	ldr r1, =GPJ0DAT
	str r0, [r1]

	//延时

	bl delay      //调用函数

	b flash       //跳转到flash的位置执行

delay:
	ldr r2, =9000000
	ldr r3, =0x0
delay_loop:             //循环体 相当于while()
	sub r2, r2, #1      //r2 = r2-1
	cmp r2, r3          //判断r2 是否与 r3相等 影响z位
	bne delay_loop      // 如果不相等则 继续执行循环
	mov pc, lr          //函数返回值


使用位运算进行改进

对GPJODAT寄存器进行赋值 用位运算(&与  |或  ~非(取反)  位移(<<左移   >>右移))的方式

// 改进流水灯  代码

#define GPJ0CON 0xE0200240
#define GPJ0DAT 0xE0200244

.global _start
_start:
	
	//对GPJ0CON寄存器进行模式设置

	ldr r0, =0x11111111
	ldr r1, =GPJ0CON
	str r0, [r1]

	//用循环来实现流水灯效果

flash:
	
	//点亮 D4
	ldr r0, =~(1<<3)    //位移与取反  0000 1000  取反得 1111 0111
	ldr r1, =GPJ0DAT
	str r0, [r1]

	//延时
	bl delay //调用延时函数
	//点亮 D5
	ldr r0, =~(1<<4)
	ldr r1, =GPJ0DAT
	str r0, [r1]
	//延时

	bl delay //调用延时函数
	//点亮 D6
	ldr r0, =~(1<<5)    
	ldr r1, =GPJ0DAT
	str r0, [r1]
	//延时
	bl delay //调用延时函数
	b flash
delay:
	ldr r2, =9000000
	ldr r3, =0x0
delay_loop:
	sub r2, r2, #1
	cmp r2, r3
	bne delay_loop
	mov pc, lr

六, 用到的相关汇编代码

.global   伪指令 在外部对汇编头的声明,保证 _start在文件外部也能用 (.global把_start链接属性改为外部,消除链接时的警告)

ldr    伪指令 用于从存储器中将一个32位的字数据传送到目的寄存器中。并检查立即数是否

例  ldr r0 ,=0x11111111

立即数  我们通常把在立即寻址方式指令中给出的数称为立即数

b是跳转指令  .代表当前这一句指令的地址,

b . 表示跳转到 . 执行      即死循环

str  是ARM汇编中的内存访问指令,表示字数据写入,用于将一个32位的字数据写入到指令中指定的内存单元

例  str r0, [r1]           把r0中的数据写到r1中指定的内存单元

sub  汇编中 是减的意思

例 sub r0 , r0, #1   意思为  r0 = r0 - 1

cmp  (比较)指令执行从目的操作数中减去源操作数的隐含减法操作,并且不修改任何操作数。

cmp 目的操作数, 源操作数      例 cmp r2, r3  比较 r2 和r3 中的 数据是否相等 cmp会影响CPSR寄存器中的z位

bl  函数调用

例 bl 函数名

mov pc, lr  函数返回 

ARM中的通用寄存器 

r0~r3 主要用于子程序间传递参数, r4~r11 主要用于保存局部变量,但在 Thumb 程序中,通常只能使用 r4~r7 来保存局部变量; r12 用作子程序间scratch 寄存器,即 ip 寄存器; r13 通常用做栈指针,即 sp; r14 寄存器又被称为连接寄存器(lr),用于保存子程序以及中断的返回地址; r15 用作程序计数器(pc),由于 ARM 采用了流水线机制,当正确读取了 PC 的值后,该值为当前指令地址加 8 个字节,即 PC 指向当前指令的下两条指令地址。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值