JZ2440:uart 串口

本文的目的是简单的配置出一个查询方式的串口,来实现字符的打印

1. 硬件上:


要使用板子上的资源:
    串口0 - 丝印P10 :一个 usb 转串口的接口,板子上已经有了 pl2303 芯片,可以很方便的链接到带usb的电脑上了。

跟芯片链接的引脚:
JZ2440:uart 串口_第1张图片

2. 软件控制:


2.1 开启引脚的功能


既然硬件上链接的是 GPHx 引脚,那我们需要对 GPH 引脚进行配置:

寄存器

地址

R/W

描述

复位值

GPHCON

0x56000070

R/W

配置端口H

0x0

GPHUP

0x56000078

R/W

端口H的上拉使能位

0x000

 

GPHCON

Bit

描述

...

...

...

GPH4

[9:8]

00 = Input                 01 = Output

10 = TXD[1]             11 = Reserved

GPH3

[7:6]

00 = Input            01 = Output

10 = RXD[0]        11 = reserved

GPH2

[5:4]

00 = Input           01 = Output

10 = TXD[0]        11 = Reserved

GPH1

[3:2]

00 = Input                 01 = Output

10 = nRTS0         11 = Reserved

GPH0

[1:0]

00 = Input                 01 = Output

10 = nCTS0              11 = Reserved

...

...

...

 

GPHCON

Bit

描述

GPH[10:0]

[10:0]

0:使能相应的引脚为上拉

1:不上拉

 我们需要开启 GPH2 和 GPH3 的第二功能,让他们分别作为串口0的 TXD0 和 RXD0。


2.2 串口相关设置:


对串口的配置,正如我们都知道的需要配置:

  • 8N1 (8个数据位,无校验,1个停止位)    ULCON0
  • 对于数据来没来和发出去没发出去的判定方式 UCON0
  • 使用不使用 FIFO    UFCON0
  • 使用不使用流控     UMCON0
  • 设置波特率         UBRDIV0

下边一次列出相应的寄存器:

2.2.1 8N1:


寄存器

地址

R/W

描述

复位值

ULCON0

0x50000000

R/W

串口0的行控制器

0x00

 

ULCONn

Bit

描述

初始值

保留

[7]

-

0

红外模式

[6]

决定是否使用红外模式

0 = 普通模式操作  1 = 红外 Tx/Rx模式

0

奇偶校验模式

[5:3]

指定在 UART 发送和接收操作期间奇偶校验产生和检查的类型

0xx = 无奇偶校验   

100 = 奇校验  101 = 偶校验

110 = 固定/检查奇偶校验为 1  111 =固定/检查奇偶校验为 0

000

停止位数

[2]

指定用于结束帧信号的停止位的个数

0 = 每帧 1个停止位  1 = 每帧 2个停止位

0

字长度

[1:0]

指出每帧用于发送或接收的数据位的个数

00 = 5 位  01 = 6 位  10 = 7 位  11 = 8 

00

 

GPHCON

Bit

描述

GPH[10:0]

[10:0]

0:使能相应的引脚为上拉

1:不上拉


 2.2.2 对于数据来没来和发出去没发出去的判定方式: 


寄存器

地址

R/W

描述

复位值

UCON0

0x50000004

R/W

串口0的控制寄存器

0x00

 

UCONn

Bit

描述

初始值

FCLK分频器

[15:12

当 UART 时钟源选择了 FCLK/n 时的分频器值。‘n’由 UCON0[15:12]、  

UCON1[15:12]UCON2[14:12]所决定。

UCON2[15]为 FCLK/n 时钟使能/禁止位。

设置‘n’为 至 21 时,则使用 UCON0[15:12];设置‘n’为 22 至 36 时,

则使用 UCON0[15:12]; 设置‘n’为 37 至 43 时, 则使用 UCON0[14:12]。  

UCON2[15]0 = 禁止 FCLK/n 时钟;1 = 使能 FCLK/n 时钟。

UCON0 的情况:UART 时钟 = FCLK / (分频器+6);分频器>0

UCON1UCON2 必须为 0。   

例)  1UART 时钟 = FCLK/72UART 时钟 = FCLK/8

3UART 时钟 = FCLK/9;……15UART 时钟 = FCLK/21。  

UCON1 的情况:UART 时钟 = FCLK / (分频器+21);分频器>0

UCON0UCON2 必须为 0

例)  1UART 时钟 = FCLK/222UART 时钟 = FCLK/23

3UART 时钟 = FCLK/24;……15UART 时钟 = FCLK/36

UCON2 的情况:UART 时钟 = FCLK / (分频器+36);分频器>0

UCON0UCON1 必须为 0

例)  1UART 时钟 = FCLK/372UART 时钟 = FCLK/38

3UART 时钟 = FCLK/39;……15UART 时钟 = FCLK/43

如果 UCON00/1[15:12]和 UCON2[14:12]都全为‘0’, 则分频器将为 44

即 UART 时钟 = FCLK/44。总分频范围在 到 44 之间。

0000

时钟选择

[11:10]

选择 PCLKUEXTCLK或 FCLK/n 给 UART 波特率。

UBRDIVn = (int)(被选时钟 / (波特率  × 16) ) – 1

00 = PCLK  10 = PCLK  01 = UEXTCLK  11 = FCLK/n

(如果希望选择 FCLK/n,应该在选择或取消选择 FCLK/n 后加上

NOTE”的代码。 )

00

Tx 中断类型

[9]

中断请求类型。

0 = 脉冲(非 FIFO 模式中 Tx缓冲器一变为空或FIFO 模式中达到 Tx FIFO 触发深度就

请求中断)

1 = 电平(当非FIFO 模式中 Tx缓冲器为空或 FIFO模式中达到Tx FIFO 触发深度时请

求中断)

0

Rx 中断类型

[8]

中断请求类型。

0 = 脉冲 (非 FIFO模式中 Rx缓冲器接收到数据或FIFO 模式中达到Rx FIFO 触发深度

则立刻请求中断)

1 = 电平 (当非 FIFO 模式中 Rx缓冲器正在接收数据或FIFO 模式中达到 Rx FIFO触发

深度请求中断)

0

Rx 超时使能

[7]

当使能了 UART FIFO 使能/禁止 Rx 超时中断。该中断是一个接收中断

0 = 禁止  1 = 使能

0

Rx 错误状态

中断使能

[6]

异常时允许 UART 产生中断,如接收操作期间的断点、帧错误、奇偶

错误或溢出错误。

0 = 不产生接收错误状态中断  1 = 产生接收错误状态中断

0

环回模式

[5]

设置环回模式为 使得 UART 进入环回模式。此模式只用于测试。

0 = 正常操作  1 = 环回模式

0

发出断点信号

[4]

设置此位使得 UART 在单帧期间发出一个断点信号。此位在发出断点

信号后将自动清零。

0 = 正常传输  1 = 发出断点信号

0

 

这里需要注意的是:

    应该在选择和取消选择FCLK/n 后加上如下代码:

        GPHCON = rGPHCON & ~(3<<16); //GPH8(UEXTCLK) input  

        Delay(1); // about 100us

        rGPHCON = rGPHCON & ~(3<<16) | (1<<17); //GPH8(UEXTCLK) UEXTCLK  


 2.2.3 使用不使用 FIFO:


寄存器

地址

R/W

描述

复位值

UFCON0

0x50000008

R/W

串口0FIFO控制寄存器

0x0

 

UFCONn

Bit

描述

初始值

Tx FIFO 触发深度

[7:6]

决定发送 FIFO 的触发深度

00 = 空  01 = 16字节

10 = 32字节  11 = 48字节

00

Rx FIFO 触发深度

[5:4]

决定接收 FIFO 的触发深度

00 = 1 字节  01 = 8 字节

10 = 16字节  11 = 32字节

00

保留

[3]

-

0

Tx FIFO 复位

[2]

复位 FIFO 后自动清零

0 = 正常  1 = Tx FIFO 复位

0

Rx FIFO 复位

[1]

复位 FIFO 后自动清零

0 = 正常  1 = Rx FIFO复位

0

FIFO 使能

[0]

0 = 禁止  1 = 使能

0

 

这里需要注意的是:注意:

    当 UART 未达到 FIFO 触发深度或在带 FIFO 的 DMA 接收模式中 字周期期间没有收到数据时,将发生 Rx 中断(接收超时),用户应该检查FIFO状态并读出剩余部分。 


2.2.4 使用不使用流控:


寄存器

地址

R/W

描述

复位值

UMCON0

0x5000000C

R/W

串口0Modem 控制寄存器

0x0

 

UMCONn

Bit

描述

初始值

保留

[7:5]

这些位必须为‘0

000

自动流控制(AFC)

[4]

0 = 禁止  1 = 使能

0

保留

[3:1]

这些位必须为‘0

000

请求传送

[0]

如果 AFC 位为使能,将忽律此值。这种情况下 S3C2440A将自动控制

nRTS。如果 AFC 位为禁止,nRTS必须由软件控制。

0 = 高电平(撤消 nRTS)  1 = 低电平(激活 nRTS

0

Rx FIFO 复位

[1]

复位 FIFO 后自动清零

0 = 正常  1 = Rx FIFO复位

0

FIFO 使能

[0]

0 = 禁止  1 = 使能

0


2.2.5 设置波特率:


寄存器

地址

R/W

描述

复位值

UBRDIV0

0x50000028

R/W

波特率分频寄存器 0

-

 

UBRDIVn

Bit

描述

初始值

UBRDIV

[15:0]

波特率分频值 UBRDIVn > 0

使用 UEXTCLK作为输入时钟时,可以设置 UBRDIVn 为‘0’。

-

计算:

 存储在波特率分频寄存器中的值(UBRDIVn)是用于决定如下的串行Tx/Rx时钟率(波特率): 

         UBRDIVn = (int)( UART时钟 / ( 波特率  × 16) ) –1 
         ( UART时钟:PCLK,FCLK/n 或UEXTCLK ) 
    此处,UBRDIVn应该是从1 到(216-1),但只在使用低于PCLK的UEXTCLK时可以设置为0。 
例子:
    如果波特率为115200 bps并且UART时钟为40 MHz,UBRDIVn 为: 
        UBRDIVn  = (int)(40000000 / (115200 x 16) ) - 1 
        = (int)(21.7) - 1    [取最接近的整数] 
        = 22 - 1 = 21 

2.5.6 用于查询的状态寄存器:


寄存器

地址

R/W

描述

复位值

UTRSTAT0

0x50000010

R

UART0状态寄存器

0x6

 

UTRSTATn

Bit

描述

初始值

发送器空

[2]

当发送缓冲寄存器无有效数据要发送并且发送移位寄存器为空时将自

动设置为 1

0 = 非空  1 = 发送器(发送缓冲和移位寄存器)空

1

发送缓冲器空

[1]

当发送缓冲寄存器为空时自动设置为 1

0 = 缓冲寄存器非空

1 = 空(非 FIFO 模式中,请求中断或 DMAFIFO 模式中,当 Tx FIFO触发深度设置

为 00(空)时请求中断或 DMA

如果 UART 使用 FIFO,用户应该用 UFSTAT 寄存器中的 Rx FIFO 

数位和 Rx FIFO 满位取对代此位的检查。

1

接收缓冲器

数据就绪

[0]

每当通过 RXDn 端口接收数据,接收缓冲寄存器包含了有效数据时自

动设置为 1

0 = 

1 = 缓冲寄存器接收到有效数据(非 FIFO 模式中,请求中断或 DMA

如果 UART 使用 FIFO,用户应该用 UFSTAT 寄存器中的 Rx FIFO 

数位和 Rx FIFO 满位取对代此位的检查。

0

 

2.5.7 发送缓冲寄存器:

 

寄存器

地址

R/W

描述

复位值

UTXH0

0x50000020(L)

0x50000023(B)

W

(字节)

UART0发送缓冲寄存器

-

 

UTXHn

Bit

描述

初始值

TXDATAn

[7:0]

UARTn 要发送的数据

-

 

3. 程序举例:

#define TXD0READY   (1<<2)
#define PCLK            50000000    
#define UART_CLK        PCLK       
#define UART_BAUD_RATE  115200  //这里更改波特率
#define UART_BRD        ((UART_CLK  / (UART_BAUD_RATE * 16)) - 1)


void uart0_init(void)
{
    GPHCON  |= 0xa0;    // GPH2,GPH3用作TXD0,RXD0
    GPHUP   = 0x0c;     // GPH2,GPH3内部上拉

    ULCON0  = 0x03;     // 8N1
    UCON0   = 0x05;     // 查询方式
    UFCON0  = 0x00;     // 不使用 FIFO
    UMCON0  = 0x00;     // 不使用流控
    UBRDIV0 = UART_BRD; // 设置波特率,如果更改,需要改 UART_BAUD_RATE  这个宏
}

void putc(unsigned char c)
{
    /* 等待,知道发送缓冲区中的数据发送完 */
    while (!(UTRSTAT0 & TXD0READY));

    UTXH0 = c;
}
void puts(char *str)
{
    int i=0;
    while(str[i])
        {
            putc(str[i]);
            i++;
        }
}

上边部分可以查看 git@osc 中的init.c中内容。不用另外的建立 .h 头文件。

在main.c中:

extern void uart0_init(void);
extern void puts(char *str);
void delay(unsigned long de20ns)
{
   for (; de20ns; de20ns--);
}

int main(int argc, const char *argv[])
{
    uart0_init();
    while (1)
    {
        puts("Is ok?\n\r");
        delay(500000);
    } 
    return 0;
}

程序说明

上边的main.c程序只是程序的一部分,程序的其他部分,可以到 git@osc 上下载。下载完之后,将新建一个main.c,将程序写完,更改一下Makefile中的目标文件TARGET指定。make生成目标文件,便能下载到板子上运行了。程序生成都会统一放到build目录下边。


恩,到这里总算写完了,只是涉及串口很少的部分,就写了这么多,详细的内容还是要看数据手册的,这里举的这个例子,就是让你感受下流程,只是骨架,有了骨架,旁征博引的也就很好配置其他串口或者私人定制自己的串口了。

你可能感兴趣的:(JZ2440-V2,jz2440)