本文的目的是简单的配置出一个查询方式的串口,来实现字符的打印
寄存器 |
地址 |
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。
对串口的配置,正如我们都知道的需要配置:
寄存器 |
地址 |
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:不上拉 |
寄存器 |
地址 |
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’为 7 至 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。 UCON1,UCON2 必须为 0。 例) 1:UART 时钟 = FCLK/7;2:UART 时钟 = FCLK/8; 3:UART 时钟 = FCLK/9;……15:UART 时钟 = FCLK/21。 UCON1 的情况:UART 时钟 = FCLK / (分频器+21);分频器>0。 UCON0,UCON2 必须为 0。 例) 1:UART 时钟 = FCLK/22;2:UART 时钟 = FCLK/23; 3:UART 时钟 = FCLK/24;……15:UART 时钟 = FCLK/36 UCON2 的情况:UART 时钟 = FCLK / (分频器+36);分频器>0。 UCON0,UCON1 必须为 0。 例) 1:UART 时钟 = FCLK/37;2:UART 时钟 = FCLK/38; 3:UART 时钟 = FCLK/39;……15:UART 时钟 = FCLK/43 如果 UCON00/1[15:12]和 UCON2[14:12]都全为‘0’, 则分频器将为 44, 即 UART 时钟 = FCLK/44。总分频范围在 7 到 44 之间。 |
0000 |
时钟选择 |
[11:10] |
选择 PCLK,UEXTCLK或 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] |
设置环回模式为 1 使得 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
寄存器 |
地址 |
R/W |
描述 |
复位值 |
UFCON0 |
0x50000008 |
R/W |
串口0的FIFO控制寄存器 |
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 接收模式中 3 字周期期间没有收到数据时,将发生 Rx 中断(接收超时),用户应该检查FIFO状态并读出剩余部分。
寄存器 |
地址 |
R/W |
描述 |
复位值 |
UMCON0 |
0x5000000C |
R/W |
串口0的Modem 控制寄存器 |
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 |
寄存器 |
地址 |
R/W |
描述 |
复位值 |
UBRDIV0 |
0x50000028 |
R/W |
波特率分频寄存器 0 |
- |
UBRDIVn |
Bit |
描述 |
初始值 |
UBRDIV |
[15:0] |
波特率分频值 UBRDIVn > 0。 使用 UEXTCLK作为输入时钟时,可以设置 UBRDIVn 为‘0’。 |
- |
计算:
存储在波特率分频寄存器中的值(UBRDIVn)是用于决定如下的串行Tx/Rx时钟率(波特率):
寄存器 |
地址 |
R/W |
描述 |
复位值 |
UTRSTAT0 |
0x50000010 |
R |
UART0状态寄存器 |
0x6 |
UTRSTATn |
Bit |
描述 |
初始值 |
发送器空 |
[2] |
当发送缓冲寄存器无有效数据要发送并且发送移位寄存器为空时将自 动设置为 1。 0 = 非空 1 = 发送器(发送缓冲和移位寄存器)空 |
1 |
发送缓冲器空 |
[1] |
当发送缓冲寄存器为空时自动设置为 1。 0 = 缓冲寄存器非空 1 = 空(非 FIFO 模式中,请求中断或 DMA。FIFO 模式中,当 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 |
寄存器 |
地址 |
R/W |
描述 |
复位值 |
UTXH0 |
0x50000020(L) 0x50000023(B) |
W (字节) |
UART0发送缓冲寄存器 |
- |
UTXHn |
Bit |
描述 |
初始值 |
TXDATAn |
[7:0] |
UARTn 要发送的数据 |
- |
#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目录下边。
恩,到这里总算写完了,只是涉及串口很少的部分,就写了这么多,详细的内容还是要看数据手册的,这里举的这个例子,就是让你感受下流程,只是骨架,有了骨架,旁征博引的也就很好配置其他串口或者私人定制自己的串口了。