可以说除了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++;
}
}