ARM裸机开发(五)SPI

        以下裸机程序基于GT2440,编译器为arm-linux-gcc-4.4.3。

       程序结构:本程序只有一个spi.S文件。

       程序流程:首先上电复位进入复位异常,在复位异常里依次调用子程序关闭看门狗、初始化系统时钟、初始化串口,最后调用spi发送数据,spi发送的数据在程序里指定,对于本程序发送数据为一个字节的字符‘A’,最后spi将接收到的数据发送到串口,在终端上显示出来。

 

spi.S:

  1 //寄存器物理地址宏定义
  2 #define WTCON  0x53000000
  3 
  4 #define LOCKTIME 0x4C000000 
  5 #define MPLLCON 0x4C000004 
  6 #define UPLLCON 0x4C000008 
  7 #define CLKDIVN 0x4C000014 
  8 #define CAMDIVN 0x4C000018
  9 
 10 #define ULCON0 0x50000000 
 11 #define UCON0  0x50000004 
 12 #define UFCON0 0x50000008 
 13 #define UTRSTAT0 0x50000010 
 14 #define UTXH0  0x50000020
 15 #define URXH0  0x50000024
 16 #define UBRDIV0 0x50000028 
 17 //for uart IO
 18 #define GPHCON 0x56000070
 19 
 20 #define SPICON0 0x59000000 
 21 #define SPSTA0  0x59000004 
 22 #define SPPRE0  0x5900000C 
 23 #define SPTDAT0 0x59000010 
 24 #define SPRDAT0 0x59000014 
 25 //for spi0 IO
 26 #define GPECON 0x56000040 
 27 
 28 
 29 .global _start
 30 _start:
 31     b reset
 32     
 33 //复位异常处理
 34 reset:
 35     bl disable_watchdog
 36     bl init_clock
 37     bl init_uart
 38     bl spi_send
 39 loop:
 40     b loop
 41 
 42 //关闭看门狗
 43 disable_watchdog:
 44     ldr r0,=WTCON    
 45     bic r1,r0,#0x20
 46     str r1,[r0]
 47 
 48     mov pc,lr
 49 
 50 
 51 //初始化时钟
 52 //FCLK=400MHZ,HCLK=100MHZ,PCLK=50MHZ
 53 //UCLK=48MHZ
 54 init_clock:
 55     ldr r0,=LOCKTIME
 56     ldr r1,=0x00ffffff
 57     str r1,[r0]
 58     ldr r0,=CLKDIVN
 59     ldr r1,=0x05
 60     str r1,[r0]
 61     //设为异步总线模式(因为FCLK不等于HCLK)
 62     mrc p15,0,r1,c1,c0,0
 63     orr r1,r1,#0xc0000000
 64     mcr p15,0,r1,c1,c0,0
 65 
 66     ldr r0,=MPLLCON
 67     ldr r1,=0x5c011
 68     str r1,[r0]
 69     ldr r0,=UPLLCON
 70     ldr r1,=0x38022
 71     str r1,[r0]
 72 
 73     mov pc,lr
 74 
 75 
 76 //初始化串口
 77 init_uart:
 78     //IO口设置为串口功能
 79     ldr r0,=GPHCON    
 80     ldr r1,=0xa0
 81     str r1,[r0]
 82     //无检验位,1位停止位,8位数据位
 83     ldr r0,=ULCON0
 84     ldr r1,=0x03
 85     str r1,[r0]
 86     //PCLK作为时钟源(50MHZ)
 87     ldr r0,=UCON0
 88     ldr r1,=0x05
 89     str r1,[r0]
 90     //115200bps
 91     ldr r0,=UBRDIV0
 92     ldr r1,=0x1a
 93     str r1,[r0]
 94 
 95     mov pc,lr
 96 
 97 spi_send:
 98     //设置IO为SPI模式
 99     ldr r0,=((0x2<<26)|(0x2<<24)|(0x2<<22))
100     ldr r1,=GPECON
101     str r0,[r1]
102     //时钟分频数(PCLK/2/(249+1))
103     ldr r0,=SPPRE0
104     ldr r1,=0xf9
105     str r1,[r0]
106     //polling模式,主机模式,使能SCLK,自动发送垃圾模式
107     ldr r0,=SPICON0
108     ldr r1,=0x19
109     str r1,[r0]
110 
111 wait_send:
112     //检查状态寄存器是否已经准备好
113     ldr r2,=SPSTA0
114     ldr r1,[r2]    
115     ldr r3,=0x01
116     and r3,r1,r3
117     cmp r3,#0x01
118     bne wait_send
119     //发送一个字节
120     ldr r0,=SPTDAT0
121     ldr r1,=0x41  //字符A
122     str r1,[r0]
123 
124 wait_read:
125     //检查状态寄存器是否已经准备好
126     ldr r1,[r2]
127     ldr r3,=0x01
128     and r3,r1,r3
129     cmp r3,#0x01
130     bne wait_read
131     //读接收到的数据到r5
132     ldr r0,=SPRDAT0
133     ldr r5,[r0]
134     //调用串口将接收到的数据发送到终端
135     bl aurt_send_one_byte    
136     
137     mov pc,lr
138 
139 
140 aurt_send_one_byte:
141 wait_se:
142     //读发送状态位
143     ldr r0,=UTRSTAT0    
144     ldr r1,[r0]
145     and r1,r1,#0x4
146     cmp r1,#0x4
147     //如果发送状态位不为0则不断读状态位    
148     bne wait_se
149     //写入要发送的数据
150     ldr r3,=UTXH0
151     str r5,[r3]
152 
153     mov pc,lr

Makefile:

1 spi.bin:
2     arm-linux-gcc -g -c -o spi.o spi.S
3     arm-linux-ld -Ttext 0x00000000 -g spi.o -o spi_elf
4     arm-linux-objcopy -O binary -S spi_elf spi.bin
5     rm -f uart_elf spi.o
6 
7 clean:
8     rm -f spi.bin

执行make后将生成的spi.bin文件通过BIOS烧写到nand flash,将MOSI和MISO两个引脚短接,从nand flash启动。

 

posted @ 2012-09-04 09:43  lknlfy  阅读(1176)  评论(0编辑  收藏  举报