LED跑馬燈

 LED跑馬燈

 

 

這裏簡單的總結了一下,主要是通過跑馬燈程序來了解嵌入式編程的基本步驟和思路。

 

1) LED工作遠了原理:

 

   LED又稱發光二接管,二節管是及其有用的半導體設備,它能在一個方向上通過電流,而在另一個方向上截止電流。二節管可用來允許電流從一個部件流到另一個部件,而禁止電流“倒流”的現象。所有的二接管工作是都會產生少量的光(由於二接管的外表封裝通常看不到),而LED非常善於利用這種光。通過LED的電流量有個限制,超越這一限制就可能損害LED。因此,使用時,LED一般與限流電阻串聯(分流),如下(圖一)所示。但是有些限流電阻是集成在LED內部。

  圖一

 

 

                                                                

圖一:

2)通過I/O pin控制LED:

 

   假如處理器的工作電壓爲5v,此時處理器I/O pin輸出低電壓爲0.6v。電源電壓VCC3.3v,那麼VCCLED陰極間的電壓爲2.7v,而LED的正向電壓降(閥值電壓)爲1.6v,故有效的設定限流電阻就可以讓LED導通。這裏可通過調整限流電阻的大小來控制通過LED的電流,從而改變LED亮度。當I/O線由過高電壓驅動時,處理器的I/O pin的輸出電壓至少爲4.3v,此時VCCLED陰極間的電壓降只能是0.7v。而LED的正向電壓降(閥值電壓)爲1.6v,故沒有足夠的電壓使其導通。(可參考上圖,此處例舉的數據只是爲了更好的說明,實際要以具體設備而定)

 

3)建立交叉編譯環境:

  

 下載arm-linux-gcc-3.4.1.tar.bz2

  參考網址:http://www.handhelds.org/download/projects/toolchain/arm-linux-gcc-3.4.1.tar.bz2

 解壓:tar xjvf arm-linux-gcc-3.4.1.tar.bz2 -C /

  添加環境變量:通過修改 /etc/profile文件,將arm-linu工具路徑/usr/local/arm/3.4.1/bin添加到環境變量PATH,重新載入profile文件內容,命令:$ source /etc/profile

  通過命令:$ which arm-linux-gcc 來檢查設置是否生效.

 

4)編輯源代碼:

    

@******************************************************************************
@ File:led_on.s
@ 分別通過對引腳GPF4、GPF5、GPF6、GPF7輸出邏輯低電平來使其發光
@******************************************************************************

 

 

 @@代碼部分:  

       .text
       .global _start
     _start:
        mov r3, #4              @記數器,用以循環點亮四個燈
        ldr r0, =0x56000050     @設置 R0 爲GPFCON寄存器                                              
        mov r1, #0x1
        mov r2, r1, LSL#8
     _loop:
        ldr r4, =200000
        str r2, [r0]
      
        ldr r5, =0x56000054     @設置 R5 爲GPFDAT寄存器                        
        mov r1, #0x0
        str r1, [r5]
       
     _delay:
        nop
        subs r4, r4, #1
        bne _delay
      
        mov r2, r2, LSL#2 
        subs r3, r3, #1
        bne _loop
        b _start

 

 

5)編輯Makefile:

led_on:led_on.s

     arm-linux-gcc -g -c -Wall -o led_on.o led_on.s
     arm-linux-ld -Ttext 0x30200000 -g led_on.o -o led_on_tmp.o
     arm-linux-objcopy -O binary -S led_on_tmp.o led_on
clean:
     rm -f   led_on
     rm -f   led_on.o
     rm -f   led_on_tmp.o

 

 

6) 編譯程序:

 

     執行命令: $ make

     如果順利的話,在當前目錄下可發現 led_on可執行文件生成.

 

     注意:Makefile中命令前要縮進一個TAB字符.

         這裏再簡單的介紹所涉及到的各個選項:   

            rm-linux-gcc  編譯選項,–c:指定編譯成obj文件,-o:輸出文件名.

            arm-linux-ld  鏈接選項,-Ttext:設置代碼段的起始地址,-g:爲兼容其它工具,可不用管它,-o: 輸出文件名.

           arm-linux-objcopy -S:移除所有的標誌及重定位信息,-O binary:由一個文件生成另一個文件.

     如:-O binary xyb xyb.bin 表示由xyb生成二進制文件xyb.bin

 

7)下載程序,運行:

   

    這裏是在vivi下,通過以下命令將led_on下載到目標板,然後運行.

 

    在minicom下,通過xmodem串口下載到指定地址:

    vivi> load ram addr size z

 

    從指定地址開始運行:

    vivi> call addr

 

       注:ram 爲下載的目標存儲器,這裏爲SDRAM

           addr 爲將要下載的目標地址

           size 爲要下載的文件的大小,該數值應該不小於實際文件大小

           call 從指定的地址開始執行代碼

 

      也可以通過Jflash將它下載到nandflash,然後reset鍵重啓開發板,可發現四個LED交替閃爍。

 

 

    下面貼出通過C語言和彙編語言共同執行的代碼,該代碼主要包括了4個文件,分別爲start.s、led_on.c、led.lds、Makefile。彙編源文件start.s主要起到跳轉到led_on.c中main函數的作用。led.lds鏈接腳本供連接器使用,用於將objectfile文件中的各個輸入段鏈接到輸出段中,得到.elf的可執行文件,最後通過arm-linux-objdump來去除鏈接符號和調試信息,形成最終能燒寫到flash執行的映像文件。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

@************************

@filename: start.s
@function: just for jump to main

@************************

 .text
 .global _start
_start:
 bl main
 
halt_loop: 
 b  halt_loop

/*

  filename: led_on.c

  function: turn on led at order D1-D4

 **/

#define GPFCON  (*(volatile unsigned *)0x56000050)
#define GPFDAT  (*(volatile unsigned *)0x56000054)
#define GPFUP   (*(volatile unsigned *)0x56000058)     
#define WTCON   (*(volatile unsigned *)0x53000000)    
void delay(int times);
int main(void)
{
    GPFCON = (GPFCON|0xFF00)&0x55FF;
    GPFUP|=0xF0;
    WTCON = 0x0;     // disable the watchdog

  while(1){

    GPFDAT=(GPFDAT&0x0F)|0xE0;
    delay(400000);

    GPFDAT=(GPFDAT&0x0F)|0xD0;
    delay(400000);

    GPFDAT =(GPFDAT&0x0F)|0xB0;
    delay(400000);

    GPFDAT=(GPFDAT&0x0F)|0x70;
    delay(400000);
  }
  return (0);
}

void delay(int times){

  int i;
  for(i=times;i>0;i--)
      ;
}

 #########################
 #filename: led.lds
 #########################

SECTIONS{

 . = 0x30200000;
 .text : {
  *(.text)
  *(.rodata)
 }

 .data ALIGN(4) : {
  *(.data)
 }

 .bss ALIGN(4) : {
  *(.bss)  
 }
}


 #########################
 #filename: Makefile
 #########################

CFLAGS := -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -ffreestanding -c
led_on : start.s led_on.c
 arm-linux-gcc $(CFLAGS) -o start.o start.s
 arm-linux-gcc $(CFLAGS) -o led_on.o led_on.c
 arm-linux-ld -Tled.lds start.o led_on.o -o led_temp.o
 arm-linux-objcopy -O binary -S led_temp.o led_on

clean:
 rm -f start.o
 rm -f led_on.o
 rm -f led_temp.o
 rm -f led_on

 


 

 注意:Makefile中的命令要縮進一個TAB字符.

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章