S3C2440A UART


本文是基于韦东山视频的学习笔记

汇总点这

UART

由于对UART还是比较熟悉的,记得以前还试过用引脚模拟,就不写原理了。

这次实现putchar,getchar 函数,波特率115200

以最简单的方式实现UART通信,而通信最重要的两点,配置好即可。

  • 波特率
  • 传输数据
  • 其他(检验位啥的)

波特率

UART ULCON0 普通配置

同理(没想到有一天我也写这个词),查文档可得

  • ULCON0 地址为 0x50000000
  • [6] Infrared Mode 为正常模式:ULCON0[6] = 0
  • [5:3] Parity Mode 没有校验位(简单嘛):ULCON0[5:3] = 0xx
  • [2] Number of Stop Bit 每帧一个停止位 : ULCON0[2] = 0
  • [1:0] Word Length 数据位数为8位: ULCON0[1:0] = 0b11

也就是 ULCON0 = 0b11 = 0x3

普通配置好像就这么设置完了

UART UCON0普通配置

UCON0 地址是0x50000004

  • [15:12] FCLK Divider 不需要用,所以就不设置吧,默认0,不用
  • [11:10] Clock Selection 选择PCLK : UCON0[11:10] = 00 or 10
  • [9] Tx Interrupt Type 默认0,不用
  • [8] Rx Interrupt Type 默认0,不用
  • [7] Rx Time Out Enable 默认0,不用
  • [6] Rx Error Status Interrupt Enable 默认0,不用
  • [5] Loopback Mode 默认0,不用
  • [4] Send Break Signal 默认0,不用
  • [3:2] Transmit Mode 设置为中断模式,没其他可以选了:UCON0[3:2] = 0b01
  • [1:0] Receive Mode 设置为中断模式,没其他可以选了:UCON0[1:0] = 0b01

即 UCON0 = 0x5 or 0x805

UART状态寄存器

FIFO 和 AFC 都先不用,直接看状态寄存器吧

UTRSTAT0 地址为 0x50000010

  • [2] Transmitter empty 数据发完了就是1
  • [1] Transmit buffer empty 数据缓存空的就是1
  • [0] Receive buffer data ready 有数据可接收时是1

UTXH0 地址为 0x50000020(L)1

  • [7:0] TXDATAn 数据都在这!

URXH0 地址为 0x50000024(L)1

  • [7:0] RXDATAn 数据都在这!

波特率寄存器

Each UART’s baud-rate generator provides the serial clock for the transmitter and the receiver. The source clock for the baud-rate generator can be selected with the S3C2440A’s internal system clock or UEXTCLK. In other words, dividend is selectable by setting Clock Selection of UCONn. The baud-rate clock is generated by dividing the source clock (PCLK, FCLK/n or UEXTCLK) by 16 and a 16-bit divisor specified in the UART baud-rate divisor register (UBRDIVn). The UBRDIVn can be determined by the following expression:
UBRDIVn = (int)( UART clock / ( buad rate x 16) ) –1

得到了一条重要的公式。想要得到相应波特率,算出相应的UBRDIVn再配置即可。UART clock 可以是 PCLK, FCLK/n or UEXTCLK, 通过 UCONn 配置。

查阅手册可得,就不贴图了,感觉贴图了好难看。

UCON0 地址是0x50000004
UART clock 设置为PCLK :UCON0[11:10] = 0b00 or 0b10

上次我们已经设置了 PLCK 50MHz,带入公式

UBRDIVn = (int)( 50 000 000 / ( 115200 x 16) ) –1 = 26.12 ≈ 26

直接看文档得,UBRDIV0 地址为 0x50000028

  • [15:0] UBRDIV0 设置为26:UBRDIV0[15:0] = 26

即 UBRDIV = 26 = 0x1A

配置引脚

同样不贴图了

TXD0 - GPH2
RXD0 - GPH3

GPHCON 地址为 0x56000070

  • [7:6] GPH3 设置为RXD[0]:GPHCON[7:6] = 0b10
  • [5:4] GPH2 设置为TXD[0]:GPHCON[5:4] = 0b10

至此,相关配置完毕

uart.c

#define GPHCON 		(*((volatile unsigned int *)0x56000070))
#define ULCON0 		(*((volatile unsigned int *)0x50000000))
#define UCON0 		(*((volatile unsigned int *)0x50000004))
#define UTRSTAT0	(*((volatile unsigned int *)0x50000010))
#define UBRDIV0 	(*((volatile unsigned int *)0x50000028))
#define UTXH0	 	(*((volatile unsigned char *)0x50000020))
#define URXH0	 	(*((volatile unsigned char *)0x50000024))
#define GPHUP	 	(*((volatile unsigned char *)0x56000078))

void uart0_config()
{

	/* 配置引脚为TXD和RXD 
	- [7:6] GPH3 设置为RXD[0]:GPHCON[7:6] = 0b10
	- [5:4] GPH2 设置为TXD[0]:GPHCON[5:4] = 0b10
	 */
	
	GPHCON &= ~((3<<4)|(3<<6)); //清零
	GPHCON |=  ((1<<5)|(1<<7)); //置一
	
	GPHUP &= ~((1<<2) | (1<<3));  /* 使能内部上拉 */
	/* 配置ULCON0
	 - [6]	 Infrared Mode 为正常模式:ULCON0[6] = 0
	 - [5:3] Parity Mode 没有校验位(简单嘛):ULCON0[5:3] = 0xx
	 - [2]	 Number of Stop Bit 每帧一个停止位 : ULCON0[2] = 0
	 - [1:0] Word Length 数据位数为8位: ULCON0[1:0] = 0b11
	 - 也就是 ULCON0 = 0b11 = 0x3
	*/
	ULCON0 = 3;

	/* 配置UCON0
	- [15:12]  FCLK Divider 不需要用,所以就不设置吧,默认0,不用
	- [11:10]  Clock Selection 选择PCLK : UCON0[11:10] = 00 or 10
	- [9] Tx Interrupt Type 默认0,不用
	- [8] Rx Interrupt Type 默认0,不用
	- [7] Rx Time Out Enable 默认0,不用
	- [6] Rx Error Status Interrupt Enable 默认0,不用
	- [5] Loopback Mode 默认0,不用
	- [4] Send Break Signal 默认0,不用
	- [3:2] Transmit Mode 设置为中断模式,没其他可以选了:UCON0[3:2] = 0b01
	- [1:0] Receive Mode 设置为中断模式,没其他可以选了:UCON0[1:0] = 0b01
	
	**即 UCON0 = 0x5 or 0x805**
	*/
	UCON0 = 0x5;

	/* 配置波特率UBRDIVn
	 * UBRDIVn = (int)( 50 000 000 / ( 115200 x 16) ) –1 = 26.12 ≈ 26 
	 */
	UBRDIV0 = 26;
	
}

int putchar(int c)
{
	/* UTRSTAT0寄存器
	 - [2] Transmitter empty 数据发完了就是1
	 - [1] Transmit buffer empty 数据缓存空的就是1
	 - [0] Receive buffer data ready 有数据可接收时是1
	 */
	
while(!(UTRSTAT0&(1<<2))); //当寄存器第二位是1时一直循环
	UTXH0 = (unsigned char)c;	//UTXH0是1个字节的

}

int getchar()
{
	/* UTRSTAT0寄存器
	 - [2] Transmitter empty 数据发完了就是1
	 - [1] Transmit buffer empty 数据缓存空的就是1
	 - [0] Receive buffer data ready 有数据可接收时是1
	 */
	while(!(UTRSTAT0&(1<<0))); 

	return URXH0;
}

int puts(const char *s)
{
	
while(*s)

	{
		putchar(*s++);		

	}
}



main.c

void uart0_config();
int putchar(int c);
int getchar();
int puts(const char *s);


int main()
{
	unsigned char c;

	uart0_config();	//配置UART

	puts("Hello!!!\n\r");

	while (1)
	{
		c = getchar();
	
		if(c == '\r') putchar('\n');
		if(c == '\n') putchar('\r');

		putchar(c);
	}

	return 0;
		
}



  1. (L): The endian mode is Little endian. ↩︎ ↩︎

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值