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启动。