串口是嵌入式中常用的通信方式,他使用逐位发送,逐位接收。串行通信。串口有许多功能,诸如打印调试,连接各种模块。他安全可靠,连接简易所以被广泛使用。
串口通讯的基本定义:
1.波特率
2.格式:数据位,停止位,校验位,流量控制。
3.发送机与接收机用TX与RX相连接
USART的逻辑电平:
原来TX(即发送控制端)为高电平,ARM给予拉低并且保持1Bit的时间。PC机在低电平时开始计时,因为发送机于接收机之间有约定好的波特率,即按照约定好的波特率每隔一段时间读取一次发送引脚的电平。(一般是读取一个Bit中间时间的值),这样循环八次就完成了一个字节的接收。在接受完一个字节之后,以一个约定好的停止位结束本次字节的接收(停止位一般为1-2位数据)。在有些情况下,在八位数据与停止位的中间还会带有一个校验位。(一般为奇数偶数校验位,即一个字节中高电平的个数)。
串口存储:
因为是逐位发送的,在每接收到一位数据后会存入芯片中的FIFIO等待内存把他取出,取出之后再存入。
串口发送速度:
例如115200的波特率,一秒发送的Bit数目为115200/10=11520Bit
接下来我们开始分析编写USART的代码:
1.首先我们先从数据手册分析查看寄存器的配置:
GPH2与GPH3分别可以可以配置为串口0的TX与RX(即发送接收模式)
所需的条件是GPFCON[5:4]=10与GPFCON[7:6]=10
上面说过,串口不工作的时候引脚的电平默认为高电平
我们这里将GPH引脚初始化为高电平,即GPHUP[2]为1;
这样我们的引脚初始化就完成了。
2.接着我们来设定波特率
首先我们在手册中找到波特率的计算公式:
UBRDIVn = (int)( UART clock / ( buad rate x 16) ) –1
由此可以计算得到UBRDOVn= 50000000/(115200*16)-1=26
所以向UBRDIV0写入26
由模式设置寄存器中查的应向UCON0寄存器中写入0x00000005
3.设置完这些后,接下来我们设置串口的数据模式
由数据手册的列表中中得到: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++;
}
}在这里插入代码片
到这里就基本完成整个实验了,可以下载到开发板里面去试试开机的时候串口是否有打印出Hello World
备注:
实验代码:
在这里#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++;
}
}
插入代码片