随笔 - 60, 文章 - 0, 评论 - 197, 引用 - 0
数据加载中……

学习 ARM 系列 -- FS2401 发光二极管循环点亮

一、目的
   通过实现FS2410板子上的D9、D10、D11、D12四个发光二极管的循环点亮,了解ARM嵌入
   式开发的基本流程。

二、建立开发环境
   (1) 安装编译器 arm-linux-gcc
       我用的是 arm-linux-gcc-3.4.1, 执行安装步骤如下:
       tar xjvf arm-linux-gcc-3.4.1.tar.bz2 -C /

   (2) 生成的编译工具在 /usr/local/arm/3.4.1/bin下, 修改 /etc/profile 将
       arm-linux-gcc 加入到 PATH环境变量, 这样以后可以直接使用 arm-linux-gcc 等
       编译工具而不必指定路径, 方便不少:
      
       PATH=$PATH:/usr/local/arm/3.4.1/bin
       export
      
       注意重启后生效, 可通过 which arm-linux-gcc 来检测你的设置是否生效。

三、简单了解开发板
   因为我们是要控制开发板上的D9、D10、D11、D12四个发光二极管,让它们依次循环点
   亮,所以有必要了解FS2410开发板是如何控制它们的。通过查此开发板的原理图, 我们
   发现,实际上 D9、D10、D11、D12 对应 GPFCON 寄存器的 GPF7、GPF6、GPF5、GPF4
   ,而 GPF4,5,6,7分别是GPFCON寄存器的 第9和8、11和10、13和12、15和14位,对应关
   系如下:

    -----------------------------------------------------
    GPFCON     Bit               Description
    -----------------------------------------------------
    GPF7           [15:14]        00 = Input 01 = Output
                                           10 = EINT7 11 = Reserved
    -----------------------------------------------------
    GPF6           [13:12]        00 = Input 01 = Output
                                           10 = EINT6 11 = Reserved
    -----------------------------------------------------
    GPF5           [11:10]        00 = Input 01 = Output
                                           10 = EINT5 11 = Reserved
    -----------------------------------------------------
    GPF4           [9:8]            00 = Input 01 = Output
                                           10 = EINT4 11 = Reserved
    -----------------------------------------------------       

   需将 GPF4,5,6,7 设置成 output 以控制点亮D12, D11, D10 和 D9 四个发光二极管。
   因为这四个发光二极管均为低电平有效,需要设置 GPFDAT 的对应位为0。

四、编写程序
   (1) 一段汇编程序:
       ; led_on.s
       .text
       .global _start
     _start:
        mov r3, #4                    ; 记数器,用以循环点亮四个灯
        ldr r0, =0x56000050    ; 设置 R0 为GPFCON寄存器,此寄存器
                                            ; 用以选择端口F各个引脚的功能是输出、
                                            ; 输入、还是其它
        mov r1, #0x1
        mov r2, r1, LSL#8
     _loop:
        ldr r4, =100000
        str r2, [r0]
      
        ldr r5, =0x56000054    ; 设置 R5 为GPFDAT寄存器,用于读/写
                                            ; 端口F各引脚的数据
        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
      
       呵呵, 你也许要问为何要用汇编, 因为我们现在是直接跑在“裸”的芯片上, 没有
       操作系统的支持,无法初始化 C 环境, 而且我们的程序将来要烧写到Nand flash
       的前 4K里,而Nand flash是没有地址总线的, 如果用C, 它的变量、函数是无法找
       到的。

   (2) 编写 Makefile
       Linux下写程序离不开Makefile, 它能减化你的编译过程:
       led_on:led_on.s
               arm-linux-gcc -c -o led_on.o led_on.s
               arm-linux-ld  -Ttext 0x00000000 -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.o
               rm -f led_on
               rm -f led_on_tmp.o

       注意, Makefile 中相应的命令前要有一个TAB。

   (3) 编译程序
       执行 make -f Makefile 来生成 led_on, 呵呵, 我们要的终于生成了

五、烧写程序
   把刚刚生成的 led_on 拿到 winxp下, 我们通过 JTAG 将它烧到开发板的Nand flash
   执行 sjf2410.exe /f:led_on 回车后, 当出现提示时依次输入 0, 0, 0, 烧写完成后
   出现提示, 输入 2 退出即可。
  
   Reset 一下开发板, 看到依次被循环点亮的发光二极管了吗 ^_^

posted on 2008-01-01 20:36 Normandy 阅读(2631) 评论(10)  编辑 收藏 引用 所属分类: Embeded Area

评论

# re: FS2401 发光二极管循环点亮  回复  更多评论   

好东西,支持!
2008-01-01 20:48 | hukq

# re: FS2401 发光二极管循环点亮  回复  更多评论   

很好的资料,其实点灯大法语言上的技巧不是最重要的,通过点灯了解嵌入式编程的基本步骤和思路才是最有用的东西。
具体到每个开发板,要点灯,首先是从原理图上找到每个你想要点亮的灯对应的寄存器,然后通过芯片手册找到与该寄存器相应的用法,接下来的编程就有了目标。当然,前提是你要会烧些开发板。个人认为,点灯大法在裸板上烧写要有意思一些,在带os的开发板上电灯可以考虑做成模块或者实现一些复杂的计数计时功能。
2008-01-02 15:57 | hukq

# re: FS2401 发光二极管循环点亮  回复  更多评论   

关于为什么不能用c语言可以再说一下:
其实用c语言使用define也勉强能行,不过很不方便。主要是因为我们的程序是直接烧写到nand flash上的,在c语言里定义任何变量或者函数,都不可避免的要确定一个固定的段,会分配自己的段地址和段限长。但是nand flash是没有地址总线和cpu相连的,因此sdram对nand flash的处理办法就是通过一段固化的load程序,将nand flash中的头4k代码读到自己的缓存区中,然后再在内存(sdram)中去运行它。由于代码被移动过,而地址只可能有一个,因此,不特别指定,地址上肯定是对应不上的。
所以一般bootloader要成功运行,就必须在这宝贵的4k代码中成功地将自身从nand flash上拷贝到相应的地址,然后再跳转到这段被拷过来的地址中(一般会是c语言的main入口地址)。这个时候,已经将文件都指定到了内存中的正确的位置上,cpu在遇到变量和函数跳转的时候就能够跳到正确的位置了。
如果用nor flash就会比较轻松一些,nor flash不但能够断电保存,还支持cpu的地址总线,所以存储在nor flash中的程序就不用再拷到sdram中,可以直接从当前位置运行,由于没有被挪动过位置,那么它所被分配的逻辑段地址就可以很好的和段本身对应上了。
不过nor flash很贵,而且烧写的成功率也差不少。
2008-01-02 16:11 | hukq

# re: 学习 ARM 系列 -- FS2401 发光二极管循环点亮[未登录]  回复  更多评论   

事实上楼主的程序是有点小问题的,不知道大家发现没。楼主是希望大家多动动脑子啊,呵呵
2008-03-15 17:16 | wz

# re: 学习 ARM 系列 -- FS2401 发光二极管循环点亮  回复  更多评论   

@wz

呵呵,这个程序在 FS2410 能跑的。不知有何问题? 还请不吝赐教啊!
2008-03-17 10:27 | Normandy

# re: 学习 ARM 系列 -- FS2401 发光二极管循环点亮  回复  更多评论   

蛮好的资料,买了FS2410好久了,一直没怎么学,打算跟你一块学习了。呵呵,望多多指教~
2008-03-18 15:17 | FAN

# re: 学习 ARM 系列 -- FS2401 发光二极管循环点亮  回复  更多评论   

@FAN
呵呵,谈不上指教,只是早点入门而已, 以后有问题多切磋、交流, 这样大家都能提高的快些!
2008-03-19 10:24 | Normandy

# re: 学习 ARM 系列 -- FS2401 发光二极管循环点亮[未登录]  回复  更多评论   

貌似sub r4, r4, #1和sub r3, r3, #1应该是subs吧,要不bne拿什么判断。我在fs2410的板子上实际跑了一下,不改的话就陷入_delay中了。
2008-03-26 08:54 | wz

# re: 学习 ARM 系列 -- FS2401 发光二极管循环点亮  回复  更多评论   

@wz
你说的有道理,只有 subs 才能影响 CPSR 的 N 标志位, 看来确实是我大意了。谢谢指正,以后多交流啊!
2008-03-26 16:36 | Normandy

# re: 学习 ARM 系列 -- FS2401 发光二极管循环点亮  回复  更多评论   

好东西,谢谢共享
2008-04-06 15:00 | kerwintian

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理