ARM裸机开发(四)串口编程

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

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

  程序流程:首先上电复位,进入复位异常处理,关闭看门狗,初始化系统时钟(FCLK=400MHZ,HCLK=100MHZ,PCLK=50MHZ),初始化串口(无检验位,1位停止位,8位数据位,115200bps),最后跳到test_uart子程序,在该程序里不断等待用户输入数据(一个字节),如果用户输入了数据就跳到发送数据子程序,在子程序里将用户输入的数据+1后再发送给用户,此时用户可以在终端看到被+1了的数据。

uart.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 
 18 #define GPHCON 0x56000070 
 19 
 20 
 21 .global _start
 22 _start:
 23     b reset
 24 
 25 
 26 reset:
 27     bl disable_watchdog
 28     bl init_clock
 29     bl init_uart
 30     b test_uart
 31 
 32     
 33 //关闭看门狗
 34 disable_watchdog:
 35     ldr r0,=WTCON    
 36     bic r1,r0,#0x20
 37     str r1,[r0]
 38 
 39     mov pc,lr
 40 
 41 //FCLK=400MHZ,HCLK=100MHZ,PCLK=50MHZ
 42 //UCLK=48MHZ
 43 init_clock:
 44     ldr r0,=LOCKTIME
 45     ldr r1,=0x00ffffff
 46     str r1,[r0]
 47     ldr r0,=CLKDIVN
 48     ldr r1,=0x05
 49     str r1,[r0]
 50     //设为异步总线模式(因为FCLK不等于HCLK)
 51     mrc p15,0,r1,c1,c0,0
 52     orr r1,r1,#0xc0000000
 53     mcr p15,0,r1,c1,c0,0
 54 
 55     ldr r0,=MPLLCON
 56     ldr r1,=0x5c011
 57     str r1,[r0]
 58     ldr r0,=UPLLCON
 59     ldr r1,=0x38022
 60     str r1,[r0]
 61 
 62     mov pc,lr
 63 
 64 //初始化串口
 65 init_uart:
 66     //IO口设置为串口功能
 67     ldr r0,=GPHCON    
 68     ldr r1,=0xa0
 69     str r1,[r0]
 70     //无检验位,1位停止位,8位数据位
 71     ldr r0,=ULCON0
 72     ldr r1,=0x03
 73     str r1,[r0]
 74     //PCLK作为时钟源(50MHZ)
 75     ldr r0,=UCON0
 76     ldr r1,=0x05
 77     str r1,[r0]
 78     //波特率115200bps
 79     ldr r0,=UBRDIV0
 80     ldr r1,=0x1a
 81     str r1,[r0]
 82 
 83 //发送一个字节
 84 send_one_byte:
 85 wait_se:
 86     //读发送状态位
 87     ldr r0,=UTRSTAT0    
 88     ldr r1,[r0]
 89     and r1,r1,#0x4
 90     cmp r1,#0x4
 91     //如果发送状态位不为0则不断读状态位    
 92     bne wait_se
 93     //写入要发送的数据(用户输入的数据+1)
 94     ldr r3,=UTXH0
 95     add r4,r4,#1
 96     str r4,[r3]
 97     
 98     mov pc,lr
 99 
100 test_uart:
101 wait_rec:
102     //读接收状态位
103     ldr r0,=UTRSTAT0
104     ldr r1,[r0]
105     and r1,r1,#0x1
106     cmp r1,#0x1
107     //如果接收状态位不为1则不断读状态位
108     bne wait_rec
109     //读入用户输入的数据
110     ldr r2,=URXH0 
111     ldr r4,[r2]
112     //调用发送函数
113     bl send_one_byte
114     b test_uart //不断循环        

Makefile:

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

       执行make之后将生成的uart.bin文件通过BIOS下载到nand flash,从nand flash启动。

原文地址:https://www.cnblogs.com/lknlfy/p/2663282.html