s3c2440之UART学习笔记

3 篇文章 0 订阅
3 篇文章 0 订阅

一、原理解析

UART(Universal Asynchronous Receiver/Transmitter,通用异步接收/发送装置)用于异步通信,可以实现全双工发送和接收。它不仅可以实现不同嵌入式系统之间的通信,还可以实现与PC之间的通信。

数据传输流程如下:

(1)平时数据线处于空闲状态(1状态);

(2)当要发送数据时,UART改变TxD数据线的状态(变为0状态)并维持1位的时间,这样接收方检测到开始位后,在等待1.5位的时间就开始一位一位地检测数据线的状态得到所传输的数据;

(3)UART一帧中可以有5、6、7或8位的数据,发送方一位一位地改变数据线的状态将他们发送出去,首先发送最低位

(4)如果使用校验功能,UART在发送完数据后,还要发送1位校验位。有两种校验方法:奇校验、偶校验——数据位连同校验位中,1的数据等于奇数或偶数;

(5)最后,发送停止位,数据线恢复到空闲状态(1状态)。停止位的长度有3种:1位、1.5位、2位。

下图演示了UART使用7个数据位、偶校验、2个停止位的格式传输字符‘A’(二进制值为0b1000001)时,TTL/COM逻辑电平对应的波形。

s3c2440提供了三个UART端口,它们都可以通过查询、中断和DMA方式传输数据,而且每个UART都分别有一个64个字节的接收FIFO和一个64个字节的发送FIFO。如下图所示:每个UART包含一个波特率发生器、发送器、接收器和一个控制单元。波特率发生器可以由PCLK、FCLK/n或UEXTCLK(外部输入时钟)时钟驱动。UART通过使用系统时钟可以支持最高115.2Kbps的比特率。如果是使用外部器件提供UEXTCLK的UART,则UART可以运行在更高的速度。发送器和接收器各包含一个64字节的FIFO和数据移位器。要发送数据时,先将数据写入到FIFO接着在发送前复制到发送移位器中,随后将数据从发送数据引脚(TXDn)移出;接收数据时,从接收数据引脚(RXDn)移入接收移位器,接着从移位器复制到FIFO。

二、寄存器配置代码

1、配置串口引脚(GPHCON)及内部上拉(GPHUP)

注:在串口开始前的空闲状态处于高电平,开始位为低电平,需要进行内部上拉保证空闲状态为高电平。

2、设置波特率及选择时钟源

3、设置数据格式

4、程序

uart.h

1 #ifndef     _UART_H                // 如果某个文件第一次包含这个头文件,_UART_H这个宏没有定义时
2 #define     _UART_H                // 定义_UART_H这个宏
3 
4 void uart0_init(void);
5 int putchar(int c);
6 int getchar(void);
7 int puts(const char *s);
8 
9 #endif

uart.c

#include "s3c2440_soc.h"


/* 115200,8n1 */
void uart0_init()
{
	/* 设置引脚用于串口 */
	
	/* GPH2,3用于TxD0, RxD0 */
	GPHCON &= ~((3<<4) | (3<<6));  //寄存器4-7位清0
	GPHCON |= ((2<<4) | (2<<6));   //4-7位1010,其余位为1

	GPHUP &= ~((1<<2) | (1<<3));  /* 使能内部上拉为高电平,低电平开始位 */
	

	/* 设置波特率 */
	/* UBRDIVn = (int)( UART clock / ( buad rate x 16) ) –1
	 *  UART clock = 50M
	 *  UBRDIVn = (int)( 50000000 / ( 115200 x 16) ) –1 = 26
	 */

	UCON0 = 0x00000005; /* PCLK,中断/查询模式 */
	UBRDIV0 = 26;

	/* 设置数据格式 */
	ULCON0 = 0x00000003; /* 8n1: 8个数据位, 无较验位, 1个停止位 */

	/*  */

}

int putchar(int c)
{
	/* UTRSTAT0 */
	/* UTXH0 */

	while (!(UTRSTAT0 & (1<<2)));   //当发送缓冲寄存器和发送移位器不是空的时候,循环等待
	UTXH0 = (unsigned char)c;  //反之,当上一个发送完了,再向发送缓冲寄存器写入字符(这里是按单个字节发送)
	
}

int getchar(void)
{
	while (!(UTRSTAT0 & (1<<0)));  //当接收缓冲寄存器是空的时候,循环等待
	return URXH0;                  //当接收缓冲寄存器非空的时候,返回接收缓冲寄存器得到的值
}

int puts(const char *s)
{
	while (*s)
	{
		putchar(*s);
		s++;
	}
}

main.c

 1 #include "s3c2440_soc.h"
 2 #include "uart.h"
 3 int main(void)
 4 {    unsigned char c;
 5     uart0_init();
 6     puts("Hello,world!\n\r");
 7     while(1)
 8     {
 9         c=getchar();               // 从PC键盘上得到输入字符(串 )
10         if (c == '\r')              //  换行处理 ,不论输入\n或者\r,都会换行并使光标到行首 
11         {
12             putchar('\n');
13         }
14         if (c == '\n')
15         {
16             putchar('\r');
17         }
18         putchar(c);              // 输出得到的字符(串 )到PC,PC屏幕会显示串口传过来的字符(串 )
19     }    
20     return 0;
21 }

makefile

all:
    arm-linux-gcc -c -o led.o led.c
    arm-linux-gcc -c -o uart.o uart.c
    arm-linux-gcc -c -o main.o main.c
    arm-linux-gcc -c -o start.o start.S
    arm-linux-ld -Ttext 0 start.o led.o uart.o main.o -o uart.elf
    arm-linux-objcopy -O binary -S uart.elf uart.bin
    arm-linux-objdump -D uart.elf > uart.dis
clean:
    rm *.bin *.o *.elf *.dis

三、printf函数实现

部分图片参考http://www.cnblogs.com/Wayne123/p/9818225.html的博客

本文章是基于韦东山JZ2440开发版的学习笔记,日后会不断更新与完善。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值