人机交互(串口通信)

可以说除了LCD屏,串口应该是最好的交互工具了。先过一遍串口的基本通信原理。

 

Ⅰ、协议:

通信无非就是双方交换消息,双方要有共同的语言,这样你说什么我才能知道。另外还要有时序同步,你说的太快,我也听不清楚。

 

Ⅱ、时序图

平时串口发送线是高电平的,当要向串口发送消息时,拉低串口发送线(起始位),此时PC端发现RX接收线由高电平变为低电平,那么PC端就知道串口即将有数据发送。那么PC端等待多久开始接收数据呢。这就需要双方在发送和接收前进行约定,这些约定就是串口波特率、数据位、停止位、奇偶校验位等。发完起始位,开始发送8位的数据,例如A:0x41,刚好8bit,同时PC机接收到的就是0x41;发完数据后,至少拉高一个T的时间(停止位),这个T跟波特率有关。

如果在发送数据之前都要人工操作这些时序,估计会疯掉。

2440中就有一个串口控制器,只要把串口的参数填写好,将要发送的数据发送到对应的寄存器,控制器就会自动产生这些时序,将数据发送出去。

一般只需要三条线---发送线(TXD),接受线(RXD),地线(GND)

 

补充:

串口属于串行异步通信,双方时钟不用一样,只需要设置波特率等信息。适合单片机与单片机通信。但是串口通信慢,波特率9600bps,也就是说每秒只能传输9600bit,相当于每秒传输1.2KB。

 

Ⅲ、原理图

串口有3根线,这三根线究竟分别接到soc上的哪些管脚?TXD0?有TXD1,当然有,为什么我选择了TXD0,因为我的板子有USB转串口。这样的话选择这个穿裤作为调试串口最适合不过了。

Ⅳ、芯片手册

作为串口,当然免不了几个重要的参数:起始位、波特率、数据位、停止位、校验位。当然波特率是由时钟决定的,所以还要设置一下串口的运行时钟。对接的引脚当然也要复用为串口功能。

将GPH2、GPH3设置为串口功能!!!

 

	/* 设置引脚用于串口 */
	/* GPH2,3用于TxD0, RxD0 */
	GPHCON &= ~((3<<4) | (3<<6));
	GPHCON |= ((2<<4) | (2<<6));

	GPHUP &= ~((1<<2) | (1<<3));  /* 使能内部上拉 */

设置串口参数---数据格式

 

这是设置串口要不要采用分频,这里不采用分频,我们直接采用PCLK即可,对于不同芯片可以不一样。对于这个寄存器我们只需要设置最后4bit,接收发送模式。

 

 

这里需要注意一点,设置波特率跟时钟频率有关,手册还指明需要根据波特率设置UBRDIV0 寄存器

 

	/* 设置波特率 */
	/* 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个停止位 */

 ?,参数都设置完毕!!!!

 

Ⅴ、发送与接收

 

串口配置完毕,剩下的就是如何发送和接收的问题。

又到了疑问时刻

接收:我怎么知道有数据呢?我从哪里拿数据?

发送:我能不能发送?我往哪里发数据?

 

在芯片手册中有这样的描述:

发送接收状态寄存器,咦,哈哈哈!!!

 

再来两个,数据寄存器,发送时往UTXH0发送一个字符,在URXH0提取一个字符。四个问题解决了!!!

 

Ⅵ、串口编程

 

串口发送

	/* UTRSTAT0 */
	/* UTXH0 */

	while (!(UTRSTAT0 & (1<<2)));
    UTXH0 = (unsigned char)c;

串口接收

while (!(UTRSTAT0 & (1<<0)));
	return URXH0;

完整代码

#include "s3c2440_soc.h"


/* 115200,8n1 */
void uart0_init()
{
	/* 设置引脚用于串口 */
	/* GPH2,3用于TxD0, RxD0 */
	GPHCON &= ~((3<<4) | (3<<6));
	GPHCON |= ((2<<4) | (2<<6));

	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++;
	}
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值