第一我在此强调的是,要学会根据原理图和相关的手册实现基本功能,主要学习这个过程。
正文:
第一步:先看原理图了解LED是和哪个管脚连接的,然后我们才能通过操作寄存器的方式
控制管脚,进而控制LED
通过原理图可知:要想将LED点亮,只需要将GPJ0端设置为低电平,并且为输出状态
就可以了,这里我们只设置前面三个GPJ0端口的。
对应的端口是GPI0_3,GPI0_4,GPI0_5
第二步:
1、 查看涉及到的寄存器
我们看到与GPI0相关的寄存器共有6个,相应的功能是:
GPJ0CON:(地址:0xE0200240)(control)控制寄存器,配合各引脚的工作模式
GPJ0DAT:(地址:0xE0200244)(data)当引脚为输入/输出模式时,寄存器相应位和
引脚高低电平一致
GPI0PUD:(pull up down)控制引脚内部弱上拉,下拉
GPJ0DRV:(driver)配置引脚的驱动能力
根据以上的分析得出结论:我们只需要写GPJ0CON和GPJ0DAT
2、具体分析各个所用到的寄存器
往寄存器里面写1可以设置为输出模式了。(初始值为0,默认为输入模式)。
为什么要设置为低电平和输出模式那?
当电流从高电平流向低电平是LED会亮从原理图中可以看出左边接的是高电压,所以右边的端口肯定
接低电平了。
当端口设置为输入模式时,我们GPJ0DAT所对应的位的数据(1或0)是由GPJ0接口本身的状态决定
的。当端口为低电平时,寄存器上的值为0,为高电平是,寄存器上的值为1。
而当端口设置为输出模式时,端口的状态是由GPJ0DAT所对应的位(1或0)决定的。也就是说我们往
寄存器上写0,端口就是低电平;写1时,端口上就是高电平。
这就是我们为什么要用输出模式和低电平。
三、具体代码实现
(1)、功能:全部点亮
_start: //这里用的是ldr的伪命令,就是不用区分合法立即数还是非法立即数,=就是伪,%#就是真 ldr r0, =0xE0200240 //0xE0200240对应的是GPJ0CON寄存器,它就是控制接口的状态的,是输出还是输入 ldr r1, =0x11111111 //0x11111111就对应着8个接口的状态,1就表示输出状态,0就表示输入状态,每个接口就有 str r1, [r0] //8个状态,其他状态可以查数据手册就知道了 ldr r0, =0x0 //这里的0表示的就是输出了低电平,如果是1的话就输出的是高电平 ldr r1, =0xE0200244 //0xE0200244对应的是GPJ0DAT寄存器,它就是用来输出什么的,是输出高电平还是低电平 str r0, [r1] b .
(2)、功能:用位操作来实现指定的灯亮
.global _start _start: ldr r0, =GPJ0CON ldr r1, =0x11111111 str r1, [r0] ldr r0, =(1<<3) | (0<<4) | (1<<5) //这里就是使用了那个或运算,和左移,它的作用和0x2的作用一样 ldr r1, =GPJ0DAT //在中间加了那个0是为了比较容易看清楚代码的作用 str r0, [r1] b . //和那个b . 的作用是一样的啊
(3)、一个延时函数的写法,及其汇编代码的解释
delay: ldr r2, =9000000 ldr r3, =0x0 delay_loop: sub r2, r2, #1 //这里就是等价于:sub r2, #1,其实就是r2 = r2 - 1; cmp r2, r3 //比较r2和r1的值 bne delay_loop //cmp 和bne连用: 先是用cmp进行那个比较,然后将比较的结果与0比较,如果不为0,则跳到bne紧跟着的标记(如bne sleep,则跳到sleep处)。就是说不相等就跳转。 mov pc, lr
(4)、C语言实现灯一闪一闪
#define GPJ0CON 0xE0200240 #define GPJ0DAT 0xE0200244 void delay(void); //这个函数就用来实现一闪一闪的功能 void led_blink(void) { unsigned int *p = (volatile unsigned int *)GPJ0CON; //强制类型转换 unsigned int *p1 = (volatile unsigned int *)GPJ0DAT; *p = 0x11111111; //把那个接口的模式调为输出模式 while(1) //死循环 { //点亮 *p1 = (0<<3)|(0<<4)|(0<<5); //延迟 delay(); //熄灭 *p1 = (1<<3)|(1<<4)|(1<<5); //这里写成了那个*p = (1<<3)|(1<<4)|(1<<5),出错了 //就是把接口关闭了,所以后面就不亮了 //延迟 delay(); } } void delay(void) { volatile unsigned int i = 900000; //volatile的意思就是让编译器不对这进行那个优化了 //如果进行了优化,就可能起不到延迟的功能了 while(i--); }欢迎各位指出不足之处