micro2440串口裸板程序uart0

来源:互联网 发布:by2爱上你 知乎 编辑:程序博客网 时间:2024/06/01 07:11
开发环境
系统:ubuntu 10.04.4
单板:micro2440
编译器:arm-linux-gcc-4.3.2
搭建开发环境详见ubuntu 10.04.4开发环境配置。
目标:实现micro2440 uart0 显示任意输入字符

一、编写源代码

根据s3c2440手册编写代码,包括源文件start.S clock.c clock.h main.c uart.c uart.h lib.c lib.h Makefile

文件start.S:

@******************************************************************************@ File:start.S@ 功能:管看门狗、初始化时钟@******************************************************************************          .extern     main.text .global _start _start:Reset:                      ldr sp, =4096           @ 设置栈指针,以下都是C函数,调用前需要设好栈    bl  disable_watch_dog   @ 关闭WATCHDOG,否则CPU会不断重启    bl  clock_init          @ 设置MPLL,改变FCLK、HCLK、PCLK    ldr pc, =main           @ 调用main函数halt_loop:    b   halt_loop

文件clock.c:

#include "s3c24xx.h"#include "clock.h"/* * 关闭WATCHDOG,否则CPU会不断重启 */void disable_watch_dog(void){    WTCON = 0;  // 关闭WATCHDOG很简单,往这个寄存器写0即可}#define S3C2410_MPLL_200MHZ     ((0x5c<<12)|(0x04<<4)|(0x00))#define S3C2440_MPLL_200MHZ     ((0x5c<<12)|(0x01<<4)|(0x02))/* * 对于MPLLCON寄存器,[19:12]为MDIV,[9:4]为PDIV,[1:0]为SDIV * 有如下计算公式: *  S3C2410: MPLL(FCLK) = (m * Fin)/(p * 2^s) *  S3C2410: MPLL(FCLK) = (2 * m * Fin)/(p * 2^s) *  其中: m = MDIV + 8, p = PDIV + 2, s = SDIV * 对于本开发板,Fin = 12MHz * 设置CLKDIVN,令分频比为:FCLK:HCLK:PCLK=1:2:4, * FCLK=200MHz,HCLK=100MHz,PCLK=50MHz */void clock_init(void){    // LOCKTIME = 0x00ffffff;   // 使用默认值即可    CLKDIVN  = 0x03;            // FCLK:HCLK:PCLK=1:2:4, HDIVN=1,PDIVN=1    /* 如果HDIVN非0,CPU的总线模式应该从“fast bus mode”变为“asynchronous bus mode” */__asm__(    "mrc    p15, 0, r1, c1, c0, 0\n"        /* 读出控制寄存器 */     "orr    r1, r1, #0xc0000000\n"          /* 设置为“asynchronous bus mode” */    "mcr    p15, 0, r1, c1, c0, 0\n"        /* 写入控制寄存器 */    );    /* 判断是S3C2410还是S3C2440 */    if ((GSTATUS1 == 0x32410000) || (GSTATUS1 == 0x32410002))    {        MPLLCON = S3C2410_MPLL_200MHZ;  /* 现在,FCLK=200MHz,HCLK=100MHz,PCLK=50MHz */    }    else    {        MPLLCON = S3C2440_MPLL_200MHZ;  /* 现在,FCLK=200MHz,HCLK=100MHz,PCLK=50MHz */    }       }
文件clock.h:

void clock_init(void);void disable_watch_dog(void);

文件main.c:

#include "uart.h"#include "lib.h"int main(){    unsigned char c;    uart0_init();   // 波特率115200,8N1(8个数据位,无校验位,1个停止位)    while(1)    {        // 从串口接收数据后,判断其是否数字或子母,若是则加1后输出 do { c = getc(); if (c == '\n' || c == '\r')   {    putc('\n');putc('\r');   } else   {     putc(c);   }        } while (c == '\n' || c == '\r');   }    return 0;}
文件uart.c:

#include "s3c24xx.h"#include "uart.h"#define PCLK            50000000    // init.c中的clock_init函数设置PCLK为50MHz#define UART_CLK        PCLK        //  UART0的时钟源设为PCLK#define UART_BAUD_RATE  115200      // 波特率#define UART_BRD        ((UART_CLK  / (UART_BAUD_RATE * 16)) - 1)/* * 初始化UART0 * 115200,8N1,无流控 */void uart0_init(void){    GPHCON  |= 0xa0;    // GPH2,GPH3用作TXD0,RXD0    GPHUP   = 0x0c;     // GPH2,GPH3内部上拉    ULCON0  = 0x03;     // 8N1(8个数据位,无较验,1个停止位)    UCON0   = 0x05;     // 查询方式,UART时钟源为PCLK    UFCON0  = 0x00;     // 不使用FIFO    UMCON0  = 0x00;     // 不使用流控    UBRDIV0 = UART_BRD; // 波特率为115200}
文件uart.h:

void uart0_init(void);
文件lib.c:

#include "s3c24xx.h"#include "lib.h"#define TXD0READY   (1<<2)#define RXD0READY   (1)/* * 发送一个字符 */void putc(unsigned char c){    /* 等待,直到发送缓冲区中的数据已经全部发送出去 */    while (!(UTRSTAT0 & TXD0READY));        /* 向UTXH0寄存器中写入数据,UART即自动将它发送出去 */    UTXH0 = c;}/* * 接收字符 */unsigned char getc(void){    /* 等待,直到接收缓冲区中的有数据 */    while (!(UTRSTAT0 & RXD0READY));        /* 直接读取URXH0寄存器,即可获得接收到的数据 */    return URXH0;}
文件lib.h:

void putc(unsigned char c);unsigned char getc(void);
文件Makefile:

objs := start.o clock.o main.o uart.o lib.o2_uart.bin: $(objs)arm-linux-ld -Ttext 0x00000000 -o uart_elf $^arm-linux-objcopy -O binary -S uart_elf $@arm-linux-objdump -D -m arm uart_elf > uart.dis%.o:%.carm-linux-gcc -Wall -O2 -c -o $@ $<%.o:%.Sarm-linux-gcc -Wall -O2 -c -o $@ $<clean:rm -f *.bin uart_elf uart.dis *.o

二、编译

change@change:~$ cd Si/micro2440/2_uart0/
change@change:~/Si/micro2440/2_uart0$ make clean
rm -f *.bin uart_elf uart.dis *.o
change@change:~/Si/micro2440/2_uart0$ ls
clock.c  clock.h  lib.c  lib.h  main.c  Makefile  s3c24xx.h  start.S  uart.c  uart.h
change@change:~/Si/micro2440/2_uart0$ make
arm-linux-gcc -Wall -O2 -c -o start.o start.S
arm-linux-gcc -Wall -O2 -c -o clock.o clock.c
arm-linux-gcc -Wall -O2 -c -o main.o main.c
In file included from main.c:2:
lib.h:1: warning: conflicting types for built-in function 'putc'
arm-linux-gcc -Wall -O2 -c -o uart.o uart.c
arm-linux-gcc -Wall -O2 -c -o lib.o lib.c
In file included from lib.c:2:
lib.h:1: warning: conflicting types for built-in function 'putc'
arm-linux-ld -Ttext 0x00000000 -o uart_elf start.o clock.o main.o uart.o lib.o
arm-linux-objcopy -O binary -S uart_elf 2_uart.bin
arm-linux-objdump -D -m arm uart_elf > uart.dis
change@change:~/Si/micro2440/2_uart0$ ls
2_uart.bin  clock.h  lib.c  lib.o   main.o    s3c24xx.h  start.S  uart.dis  uart.h
clock.c     clock.o  lib.h  main.c  Makefile  start.o    uart.c   uart_elf  uart.o
change@change:~/Si/micro2440/2_uart0$ cp 2_uart.bin /home/change/work/tftpboot/

三、烧写、测试

很多人电脑都没有并口或者openjtag编程器,这里介绍直接用u-boot烧写。前提是单板已有u-boot并且支持网卡。
我用NOR Flash里的u-boot烧写程序到NAND Flash,过程如下:

单板拨到NOR启动,上电:

U-Boot 2012.04.01 (Oct 25 2012 - 22:47:25)


CPUID: 32440001
FCLK:      400 MHz
HCLK:      100 MHz
PCLK:       50 MHz
DRAM:  64 MiB
WARNING: Caches not enabled
Flash: 2 MiB
NAND:  256 MiB
In:    serial
Out:   serial
Err:   serial
Net:   dm9000
Warning: dm9000 MAC addresses don't match:
Address in SROM is         ff:ff:ff:ff:ff:ff
Address in environment is  00:0c:29:4d:e4:f4


Hit any key to stop autoboot:  0 
SMDK2410 # printenv
baudrate=115200
bootargs=console=ttySAC0 root=/dev/mtdblock3
bootcmd=nand read 30000000 kernel;bootm 30000000 
bootdelay=5
ethact=dm9000
ethaddr=00:0c:29:4d:e4:f4
gatewayip=172.16.1.1
ipaddr=172.16.1.133
mtddevname=u-boot
mtddevnum=0
mtdids=nand0=micro2440-0
mtdparts=mtdparts=micro2440-0:256k(u-boot),128k(params),2M(kernel),-(rootfs)
netmask=255.255.255.0
partition=nand0,0
serverip=172.16.1.135
stderr=serial
stdin=serial
stdout=serial


Environment size: 476/131068 bytes
SMDK2410 # ping 172.16.1.135
dm9000 i/o: 0x20000000, id: 0x90000a46 
DM9000: running in 16 bit mode
MAC: 00:0c:29:4d:e4:f4
could not establish link
Using dm9000 device
host 172.16.1.135 is alive
SMDK2410 # tftp 0x32000000 2_uart.bin
dm9000 i/o: 0x20000000, id: 0x90000a46 
DM9000: running in 16 bit mode
MAC: 00:0c:29:4d:e4:f4
could not establish link
Using dm9000 device
TFTP from server 172.16.1.135; our IP address is 172.16.1.133
Filename '2_uart.bin'.
Load address: 0x32000000
Loading: #
done
Bytes transferred = 332 (14c hex)
SMDK2410 # nand erase 0 0x40000


NAND erase: device 0 offset 0x0, size 0x40000
Erasing at 0x20000 -- 100% complete.
OK
SMDK2410 # nand write 0x32000000 0 0x40000


NAND write: device 0 offset 0x0, size 0x40000
 262144 bytes written: OK
SMDK2410 # 

单板拨到NAND启动,重新上电

开始测试,输入以下字符,测试OK
AWET18ilfj
micro2440 test