您的位置:首页 > 其它

TQ2440串口裸板程序uart0

2013-04-23 20:27 330 查看
开发环境

系统:ubuntu 10.04.4

单板:TQ2440

编译器:arm-linux-gcc-4.3.2

搭建开发环境详见ubuntu 10.04.4开发环境配置。

目标:实现tq2440 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.o

2_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:%.c
arm-linux-gcc -Wall -O2 -c -o $@ $<

%.o:%.S
arm-linux-gcc -Wall -O2 -c -o $@ $<

clean:
rm -f *.bin uart_elf uart.dis *.o
二、编译

change@change:~/Si/TQ2440/2_uart0$ cd /home/change/

change@change:~$ cd Si/TQ2440/2_uart0/

change@change:~/Si/TQ2440/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/TQ2440/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/TQ2440/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/TQ2440/2_uart0$ cp 2_uart.bin /home/change/work/tftpboot/

三、烧写、测试

很多人电脑都没有并口或者openjtag编程器,这里介绍直接用u-boot烧写。前提是单板已有u-boot并且支持网卡。

我用NOR Flash里的u-boot烧写程序到NAND Flash,过程如下:

单板拨到NOR启动,上电:

U-Boot 1.1.6 (Mar 24 2012 - 03:44:51)

DRAM: 64 MB

Flash: 2 MB

NAND: 256 MiB

In: serial

Out: serial

Err: serial

Hit any key to stop autoboot: 0

TQ2440 # set ipaddr 172.16.1.133

TQ2440 # set gatewayip 172.16.1.1

TQ2440 # set serverip 172.16.1.135

TQ2440 # ping 172.16.1.135

dm9000 i/o: 0x20000000, id: 0x90000a46

MAC: 00:80:00:80:00:80

could not establish link

host 172.16.1.135 is alive

TQ2440 # tftp 0x32000000 2_uart.bin

dm9000 i/o: 0x20000000, id: 0x90000a46

MAC: 00:80:00:80:00:80

could not establish link

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)

TQ2440 # nand erase 0 0x40000

NAND erase: device 0 offset 0x0, size 0x40000

Erasing at 0x20000 -- 100% complete.

OK

TQ2440 # nand write 0x32000000 0 0x40000

NAND write: device 0 offset 0x0, size 0x40000

262144 bytes written: OK

TQ2440 #

接着单板拨到NAND启动,运行上面通过NOR Flash 里u-boot烧写到NAND Flash的串口程序。上电输入以下字符测试OK

sdaqwe

tq2440 uart0 test
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: