第二期:第五节, LED的C语言代码

逻辑是 让板卡上的两个灯 , 循环的闪烁。

1 首先是 对于  结构体的解释

typedef struct {
				unsigned int CON;
				unsigned int DAT;
				unsigned int PUD;
				unsigned int DRV;
}gpx1;
#define GPX1 (* (volatile gpx1 *)0x11000C20 )

这如果 要 对寄存器进行赋值的话, 直接 使用  GPX1.CON= xxxx ,就可以了。

GPX 本事就是 一个 (*P)  的类型了。

移位: 这里有些不理解。直接使用  p->xx , 这样的方式可以吗?

2 然后是 对于 灯循环函数的解释。

while(1)
{

    led_on(i%2)
    led_off(((i-1)+2)%2)
    i++
    delay_ms(500)
}

举例:

当i=0 时,

0号灯, 开。

1号灯,关。(第一次,它虽然是关的,但是也把它关掉)

I 加一。

然后是延时。

3 然后是代码

首先是汇编代码:

.text
.global _start
_start:
		ldr		r0,stacktop         /*get stack top pointer*/
		mov		sp,r0
		b		main

stacktop:    .word 		stack+4*512
.data

stack:	 .space  4*512

这里首先是 开辟了一段内存,作为栈。

并且把 sp 指针 指向了 这段栈的 最高处。

5 完整的代码:

 //GPL2_0
typedef struct {
                                unsigned int CON;
                                unsigned int DAT;
                                unsigned int PUD;
                                unsigned int DRV;
}gpl2;
#define GPL2 (* (volatile gpl2 *)0x11000100 )



//GPK1_1
typedef struct {
                                unsigned int CON;
                                unsigned int DAT;
                                unsigned int PUD;
                                unsigned int DRV;
}gpk1;
#define GPK1 (* (volatile gpk1 *)0x11000060 )


void led_init(void)
{
        GPK1.CON = (GPK1.CON & (~(0xf <<4))) | (0x1<<4);
        //GPK1.PUD = GPK1.PUD | 0x05;

        GPL2.CON = (GPL2.CON & (~(0xf<<0))) | (0x1<<0);
        //GPL2.PUD = GPL2.PUD | 0x5;
}
void led_on(int n)
{
        switch(n)
        {
        case 0:
                GPK1.DAT = GPK1.DAT|(0x1<<1);
                break;
        case 1:
                GPL2.DAT = GPL2.DAT|(0x1<<0);
                break;
        }
}



//void led_on(void)
//{
//              GPK1.DAT = GPK1.DAT|(0x1<<1);
//              GPL2.DAT = GPL2.DAT|(0x1<<0);
//}

void led_off(int n)
{
        switch(n)
        {
        case 0:
                GPK1.DAT = GPK1.DAT&(~(0x01<<1));
                break;
        case 1:
                GPL2.DAT = GPL2.DAT&(~(0x01<<0));
                break;
        }
}
void  delay_ms(unsigned int num)
{
        int i,j;
        for(i=num; i>0;i--)
                for(j=1000;j>0;j--)
                ;
}
int main(void)
{
        int i = 0;
        led_init ();
        while(1)
        {

                led_on(i%2);
                led_off(((i-1)+2)%2);
                i++;
                delay_ms(500);

        }
    return 0;
}

       

然后是makefile 的编写。

TARGET=asm
TARGETC=led
all:
        arm-none-linux-gnueabi-gcc -O0 -g -c -o $(TARGETC).o  $(TARGETC).c


        arm-none-linux-gnueabi-gcc -O0 -g -c -o $(TARGET).o $(TARGET).s
        arm-none-linux-gnueabi-gcc -O0 -g -S -o $(TARGETC).s  $(TARGETC).c

#       arm-none-eabi-ld        $(TARGETC).o    $(TARGET).o -Ttext 0x40008000 -N -o $(TARGET).elf
        arm-none-linux-gnueabi-ld       $(TARGETC).o    $(TARGET).o -Tmap.lds  -o  $(TARGET).elf

        arm-none-linux-gnueabi-objcopy -O binary -S $(TARGET).elf $(TARGET).bin
#       arm-none-linux-gnueabi-objdump -D $(TARGET).elf > $(TARGET).dis

clean:
        rm -rf *.o *.elf *.dis *.bin

然后是连接脚本

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
        . = 0x40008000;
        . = ALIGN(4);
        .text      :
        {
                asm.o(.text)
                *(.text)
        }
        . = ALIGN(4);
    .rodata :
        { *(.rodata) }
    . = ALIGN(4);
    .data :
        { *(.data) }
    . = ALIGN(4);
    .bss :
     { *(.bss) }
}

疑问: 可不可以这么理解, 就是 在 .data 段里面 就有 栈段了。

4 然后是 代码的编译与烧写。

烧写测试是 正常的。

注意: 关于switch 语句。

        switch(n)
        {
        case 0:
                GPK1.DAT = GPK1.DAT&(~(0x01<<1));

        case 1:
                GPL2.DAT = GPL2.DAT&(~(0x01<<0));
 
        }

如果没有 break 语句的话, 那么 所有的 指令 都会执行, 有点像汇编里面的 标号。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值