skyeye学习之s3c2410的串口通信

来源:互联网 发布:mac使用fontawesome 编辑:程序博客网 时间:2024/06/05 04:29

s3c2410手册 :   http://wenku.baidu.com/view/105ddc264b35eefdc8d3338a.html

http://wenku.baidu.com/view/c5c9171a59eef8c75fbfb3b5.html

s3c2410引脚分类: http://wenku.baidu.com/view/003795f8c8d376eeaeaa3102.html



在网上苦苦寻找skyeye的使用教程,发现根本没有搜到几篇文章。即使有,也是说说理论部分,根本不会详细的说明源代码如何使用,编译,链接,生成,对于我这种刚刚接触skyeye的人来说,要使用skyeye来进行模拟真的非常难啊。故鉴于网上资料少之又少,只好自己硬着头皮去研究例子和源代码,至此记录skyeye的学习。

 

对skyeye模拟s3c2410引脚,时钟,串口等寄存器的详细描述,可以看skyeye的源代码:skyeye/soc/arm/s3c2410x下的s3c2410x.h

由此可以知道skyeye中s3c2410所支持的外设模块有哪些。

 

S3C2410的UART的寄存器有11X3个(3个UART)之多,我选UART0来进行通信,用到的寄存器有8个。不过初始化就用去了5个寄存器,剩下的3个用于接收、发送数据。

第一步:串口编写流程

         1、初始化引脚: 把使用到的引脚GPH2、GPH3定义为TXD0、RXD0

                    GPHCON |= 0xa0 

                    GPHUP |= 0x0c

         2、设置串口数据格式寄存器ULCON0:8个数据位,1个停止位,无校验,正常操作模式(与之相对的是Infra-Red Mode,此模式表示0、1的方式比较特殊)

                    ULCON0  = 0x03

         3、设置串口控制寄存器UCON0:设置发送、接收都使用“中断或查询方式”

                    UCON0  = 0x05

         4、设置串口FIFO寄存器UFCON0:本次不使用FIFO,设为默认值0 

                   UFCON0 = 0x00

         5、UMCON0 (UART channel 0 Modem control register ):本次不使用流控,设为默认值0 

                   UMCON0 = 0x00

         6、设置波特率寄存器UBRDIV0:波特率计算公式UBRDIVn = (int)(PCLK / (bps x 16) ) –1 ,要看说明书验算一下此波特率是否在可容忍的误差范围之内;如果不在,则需要更换另一个波特率,本次使用的57600是符合的

                   UBRDIV0 = 0x12

至此,串口初始化完毕,下面进行数据的收发:

          串口状态寄存器:UTRSTAT0  其位功能如下

         位[2]:无数据发送时,自动设为1。当我们要使用串口发送数据时,先读此位以判断是否有数据正在占用发送口。 

         位[1]:发送FIFO是否为空,本次未用此位 

         位[0]:接收缓冲区是否有数据,若有,此位设为1。需要用到这位,需要不断查询此位一判断是否有数据已经被接收。 

          串口发送寄存器UTXH0 :把要发送的数据写入此寄存器。 

3、接收数据: 

        UTRSTAT0:如同上述“发送数据”所列,我们用到位[0] 

        串口发送寄存器URXH0 : 当查询到UTRSTAT0 位[0]=1时,读此寄存器获得串口接收到的数据。

对程序有了大概的流程后,下一步开始编码:

我的工程的组成:

                            start.s         设置中断,堆栈环境

                            s3c2410.h   定义寄存器宏

                            serial.c serial.h 串口初始化函数,收发函数

                            hello.c          主要函数

-----------------------------------------------------------------------------------------------------------------------------

 start.s 的代码如下

#define MODE_SVC 0x13

#define I_BIT   0x80

.text

.align 4

.global begin

.type begin, function

begin:

/*disable I-bit*/

mov     r0, #I_BIT|MODE_SVC

msr     cpsr_c, r0

mov r1,#0xd2

sub r2,r0,r1

ldr sp, =irq_stack           @ set sp_irq = irq_stack

bl hello

b begin

.data

.align  4

irq_stack:

.space 4096

-----------------------------------------------------------------------------------------------------------------------------

s3c2410.h的代码如下

/* WOTCH DOG register */

#define WTCON (*(volatile unsigned long *)0x53000000)

/* SDRAM regisers */

#define MEM_CTL_BASE 0x48000000

#define SDRAM_BASE 0x30000000

/* NAND Flash registers */

#define NFCONF (*(volatile unsigned int  *)0x4e000000)

#define NFCMD (*(volatile unsigned char *)0x4e000004)

#define NFADDR (*(volatile unsigned char *)0x4e000008)

#define NFDATA (*(volatile unsigned char *)0x4e00000c)

#define NFSTAT (*(volatile unsigned char *)0x4e000010)

/*GPIO registers*/

#define GPBCON (*(volatile unsigned long *)0x56000010)

#define GPBDAT (*(volatile unsigned long *)0x56000014)

#define GPHCON (*(volatile unsigned long *)0x56000070)

#define GPHDAT (*(volatile unsigned long *)0x56000074)

#define GPHUP (*(volatile unsigned long *)0x56000078)

/*UART registers*/

#define ULCON0 (*(volatile unsigned long *)0x50000000)

#define UCON0 (*(volatile unsigned long *)0x50000004)

#define UFCON0 (*(volatile unsigned long *)0x50000008)

#define UMCON0 (*(volatile unsigned long *)0x5000000c)

#define UTRSTAT0 (*(volatile unsigned long *)0x50000010)

#define UTXH0 (*(volatile unsigned char *)0x50000020)

#define URXH0 (*(volatile unsigned char *)0x50000024)

#define UBRDIV0 (*(volatile unsigned long *)0x50000028)

-----------------------------------------------------------------------------------------------------------------------------

serial.h的代码如下void init_uart(void);void putc(unsigned char c);unsigned char getc(void);

-----------------------------------------------------------------------------------------------------------------------------

serial.c的代码如下#include "s3c2410.h"#include "serial.h"
#defineTXD0READY(1<<2)#defineRXD0READY(1)
void init_uart( ){//初始化UART        GPHCON |= 0xa0;//GPH2,GPH3 used as TXD0,RXD0        GPHUP = 0x0c;//GPH2,GPH3内部上拉
        ULCON0 = 0x03;//8N1        UCON0 = 0x05;//查询方式        UFCON0 = 0x00;//不使用FIFO        UMCON0 = 0x00;//不使用流控        UBRDIV0 = 12;//波特率为57600}
void putc(unsigned char c){        while( ! (UTRSTAT0 & TXD0READY) );        UTXH0 = c;}
unsigned char getc( ){        while( ! (UTRSTAT0 & RXD0READY) );        return URXH0;}


-----------------------------------------------------------------------------------------------------------------------------

hello.c的代码如下

#include "s3c2410.h"

#include "serial.h"

 

#define BOGO_MIPS 1000000

 

void hello(void)

{

int i;

char * hellostr="helloworld";

int timeout ;

i = *hellostr - 'h';

init_uart();

 

while(1){

timeout = 0;

while(++timeout != BOGO_MIPS);

for(i=0;i<10;i++)

{

putc(hellostr[i]);

}

}

return;

}

-----------------------------------------------------------------------------------------------------------------------------接下来就是要写链接文件了,它决定文件的存储域,加载域,允许域等东西,是合并文件所需要的下面就是hello.lds的类容了,具体含义上网看看lds链接文件的含义吧OUTPUT_ARCH(arm)ENTRY(begin)SECTIONS{ . = 0xc0000000; .text :  { *(.text)  *(.rodata) }

. = ALIGN(8192);
.data : {*(.data)}
.bss : {*(.bss)}

        /* Stabs debugging sections.    */        .stab 0 : { *(.stab) }        .stabstr 0 : { *(.stabstr) }        .stab.excl 0 : { *(.stab.excl) }        .stab.exclstr 0 : { *(.stab.exclstr) }        .stab.index 0 : { *(.stab.index) }        .stab.indexstr 0 : { *(.stab.indexstr) }        .comment 0 : { *(.comment) }        .debug_abbrev 0 : { *(.debug_abbrev) }        .debug_info 0 : { *(.debug_info) }        .debug_line 0 : { *(.debug_line) }        .debug_pubnames 0 : { *(.debug_pubnames) }        .debug_aranges 0 : { *(.debug_aranges) }
}

-----------------------------------------------------------------------------------------------------------------------------

接下来就是写个Makefile文件,最终生成我们的目标文件

下面是我写的Makefile的内容了

#begin

    CC=arm-elf-gcc

    LD=arm-elf-ld

    CFLAGS= -c -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -pipe -g -mapcs-32 -march=armv4 -mtune=arm7tdmi 

    LDFLAGS= -N -p -X -Thello.lds

    LIB=

 

    all: hello 

    hello: start.o hello.o serial.o 

$(LD) $(LDFLAGS)  start.o hello.o serial.o -o hello

arm-elf-objdump -xS hello > hello.s 

arm-elf-readelf -a hello > hello.r

arm-elf-nm hello > hello.n

 

    start.o:start.S

$(CC) $(CFLAGS) start.S

    hello.o:hello.c

$(CC) $(CFLAGS) hello.c

    serial.o:serial.c

$(CC) $(CFLAGS) serial.c

 

    clean:

rm -rf *.o *.elf *.gdb *.r *.n *.s

    test:

skyeye -e hello -c skyeye.conf

#end

---------------------------------------------------------------------------------------

Makefile的基本语法过程也应该会点吧,不会的话就应该自己补补了

最后就是skyeye的skyeye.conf的文件置配了

关于skyeye.conf里面的内容介绍,请看skyeye的官方PDF文档,里面说的很清楚

在这里需要设置内存的分布图,外设IO,cpu体系结构等,下面是我的skyeye.conf文件的置配内容

#skyeye config file sample

 

cpu:  arm920t

mach: s3c2410x

 

#physical memory  

#mem_bank: map=M, type=RW, addr=0x01000000, size=0x00400000

#mem_bank: map=M, type=RW, addr=0x20000000, size=0x01000000

mem_bank: map=M, type=RW, addr=0xc0000000, size=0x01000000

mem_bank: map=M, type=RW, addr=0xc1000000, size=0x00600000, file=./initrd.img

mem_bank: map=M, type=RW, addr=0xc1600000, size=0x00a00000

#all peripherals I/O mapping area

#mem_bank: map=I, type=RW, addr=0xfefa0000, size=0x00060000

mem_bank: map=I, type=RW, addr=0x48000000, size=0x20000000

mem_bank: map=I, type=RW, addr=0x19000300, size=0x00000020

uart:mod=term

#net: type=cs8900a, base=0x19000300, size=0x20,int=9, mac=0:4:3:2:1:f, ethmod=tuntap, hostip=10.0.0.1

#lcd:type=s3c2410x,mod=gtk

#dbct:state=on

好了,至此skyey的s3c2410的串口编写的整个流程都搞好了

在工程目录下终端键入make生成

键入 make test,自动进入skyeye,然后start,run就可以了

以下是测试通过的图


原创粉丝点击