ARM之S5pv210的亮灯实验

第一我在此强调的是,要学会根据原理图和相关的手册实现基本功能,主要学习这个过程。

正文:

    第一步:先看原理图了解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--);
}
欢迎各位指出不足之处




猜你喜欢

转载自blog.csdn.net/qq_41003024/article/details/80303063