Exynos4412异步串口通信及实验
通信传输方式
- 串行通信(二进制) 串行传送,数据是按顺序一位一位传送,一条数据线或差分线传输
- 并行通信 数据各位同时传送,多条数据线
比较:串行通常传输速度比较慢,成本低,适用于计算机间的远距离传输。并行传输速率高,成本也高,适用于近距离设备传输,当然了还有RS-485,RS-422,使用了串行差分通信总线,传输速率快,抗干扰性能好,同时传输距离远。
同步传输与异步传输
这里的空闲位起修正误差的作用,在波特率设置寄存器会产生误差。
RS-232串行接口标准详细介绍
目前RS-232是PC机与通信工业中应用最广泛的一种串行接口。RS-232被定义为一种在低速率串行通讯中增加通讯距离的单端标准。RS-232采取不平衡传输方式,即所谓单端通讯。
9针COM接口功能说明
脚位
|
中文说明
|
英文标识
|
1
|
数据载波检测
|
DCD
|
2
|
接收数据
|
RXD
|
3
|
发送数据
|
TXD
|
4
|
数据终端准备
|
DTR
|
5
|
信号地
|
GND
|
6
|
数据设备准备好
|
DSR
|
7
|
请求发送
|
RTS
|
8
|
清除发送
|
CTS
|
9
|
振铃指示
|
DELL
|
数据通信方式
- 单工 只能向一个方向进行数据传输
- 半双工 双向,同一时间内只能向一个方向传输
- 全双工 双向 ,同一时间内可以双向通信
数据通信的传输模式
- 轮询 通过程序执行流,不停的检测状态寄存器的结果,对于不频繁的外设效率低。
send
{
while(1)
{
逻辑判断
操作
}
}
2.中断
3.DMA(直接内存访问)
UART通用异步接收器和发送器
Exynos4412uart的特点
- 5组手法通道,同时支持中断模式及DMA操作
- 通道0,1,2,3支持红外模式
- 通道0带256字节的FIFO,通道1,4带64字节的FIFO,通道2,3带16字节FIFO
- 通道0,1,2支持自动流控功能
- 通道4支持GPS通信和自动流控
As shown in Figure 28-1, each UART contains:
- Baud-rate generator (波特率生成器)
- Transmitter (发送器)
- Receiver (接收器)
- Control unit (控制单元)
各通道大小
256 bytes in Ch0
64 bytes in Ch1 and Ch4
16 bytes in Ch2 and Ch3
64 bytes in Ch1 and Ch4
16 bytes in Ch2 and Ch3
控制器框架图
以篇幅有限就不具体的把各个寄存器的设置贴出来了
根据查阅手册波特率设置寄存器
下面计算假设串口时钟SCLK_UART=40MHz,设置波特率为115200,
1.计算DIV_VAL
DIV_VAL = (SCLK_UART/(bps * 16)) - 1
DIV_VAL = (40000000/(115200 * 16)) - 1
= 21.7 – 1
= 20.7
2.设置UBRDIVn = 20 (DIV_VAL的整数部分)
3.计算AC_VAL数值
UFRACVALn/16 = 0.7(DIV_VAL的小数部分)
UFRACVALn=11.2
4.设置UFRACVALn = 11
根据以上资料配置串口通信
- ULCONn 0x0000 Specifies line control 0x0000_0000 行控制寄存器
- UCONn 0x0004 Specifies control 0x0000_3000 控制位寄存器
- UBRDIVn 0x0028 Specifies baud rate divisor 0x0000_0000 波特率高位
- UFRACVALn 0x002C Specifies divisor fractional value 0x0000_0000 波特率低位
- UTRSTATn 0x0010 Specifies Tx/Rx status 0x0000_0006 发送/接收状态监测 发送状态监测:缓冲区为空才能发送数据(等待发送缓冲区发送完数据为空)否则要等缓冲区发送完数据才能操作缓冲区。 接受状态监测:缓冲器非空的时候才能接受数据(读接受缓冲区数据)否则等缓冲区接收完数据才能操作缓冲区
- UTXHn 0x0020 Specifies transmit buffer Undefined 指定发送缓冲区
- URXHn 0x0024 Specifies receive buffer 0x0000_0000 接受缓冲区
串口电路图
具体实现代码如下
#include "exynos_4412.h"
void mydelay_ms(int time) {
int i, j;
while (time--) {
for (i = 0; i < 5; i++)
for (j = 0; j < 514; j++)
;
}
}
void putc(const char data) {
while (!(UART2.UTRSTAT2 & 0x2))
; //shifter check
UART2.UTXH2 = data;
if (data == '\n')
putc('\r');
}
void puts(const char *pstr) {
while (*pstr != '\0')
putc(*pstr++);
}
int uart_init() {
GPA1.CON = 0x22;
UART2.ULCON2 = 0x3; //8N1 与串口调试工具设置相同
UART2.UCON2 = 0x5; //set polling mode
UART2.UBRDIV2 = 0x35; //波特率整数
UART2.UFRACVAL2 = 0x5; //baud-rate 小数部分
}
int main() {
uart_init();
char str[] = "hello uart test!\n";
while (1) {
puts(str);
mydelay_ms(800);
}
return 0;
}
void mydelay_ms(int time) {
int i, j;
while (time--) {
for (i = 0; i < 5; i++)
for (j = 0; j < 514; j++)
;
}
}
void putc(const char data) {
while (!(UART2.UTRSTAT2 & 0x2))
; //shifter check
UART2.UTXH2 = data;
if (data == '\n')
putc('\r');
}
void puts(const char *pstr) {
while (*pstr != '\0')
putc(*pstr++);
}
int uart_init() {
GPA1.CON = 0x22;
UART2.ULCON2 = 0x3; //8N1 与串口调试工具设置相同
UART2.UCON2 = 0x5; //set polling mode
UART2.UBRDIV2 = 0x35; //波特率整数
UART2.UFRACVAL2 = 0x5; //baud-rate 小数部分
}
int main() {
uart_init();
char str[] = "hello uart test!\n";
while (1) {
puts(str);
mydelay_ms(800);
}
return 0;
}