ARM S5PV210 串行通信编程实战

一、串行通信编程实战1

1、整个程序流程分析

(1) 整个串口通信相关程序包含 2 部分:uart_init 负责初始化串口,uart_putc 负责发送一个字节。


2、串口控制器初始化关键步骤

(1) 初始化串口的 Tx 和 Rx 引脚所对应的GPIO(查原理图可知 Rx 和 Rx 分别对应GPA0_1和GPA0_0)

可以看到,S5PV210 上面一共有 4 个 UART 外设。
在这里插入图片描述


可以看到,UART0 外设的RXD/TXD 对应的引脚名称如下。

在这里插入图片描述


因此,在我们的核心板原理图上可以找到,UART0 的 RXD/TXD 引脚的对应关系:
UART0 RXD -> GPA0_0
UART0 TXD -> GPA0_1

在这里插入图片描述


(2) GPA0CON(0xE0200000),bit[3:0] = 0b0010 bit[7:4] = 0b0010

在这里插入图片描述


(3) 初始化这几个关键寄存器:UCON0, ULCON0, UMCON0, UFCON0, UBRDIV0, UDIVSLOT0.

在这里插入图片描述


3、主要的几个寄存器

(1) ULCON0 = 0x3 // 0校验位、8数据位、1停止位
在这里插入图片描述

(2) UCON = 0x5 // 发送和接收都是polling mode
在这里插入图片描述
在这里插入图片描述

(3) UMCON0 = 0x0 // 禁止modem、afc
在这里插入图片描述

(4) UFCON0 = 0x0 // 禁止FIFO模式
在这里插入图片描述
在这里插入图片描述

(5) UBRDIV0 和 UDIVSLOT0 和波特率有关,要根据公式去算的
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


4、在C源文件中定义访问寄存器的宏

/*  uart.c */
#define GPA0CON         0xE0200000
#define UCON0           0xE2900004
#define ULCON0          0xE2900000
#define UMCON0          0xE290000C
#define UFCON0          0xE2900008
#define UBRDIV0         0xE2900028
#define UDIVSLOT0       0xE290002C
#define UTRSTAT0        0xE2900010
#define UTXH0           0xE2900020
#define URXH0           0xE2900024

#define rGPA0CON        (*(volatile unsigned int *)GPA0CON)
#define rUCON0          (*(volatile unsigned int *)UCON0)
#define rULCON0         (*(volatile unsigned int *)ULCON0)
#define rUMCON0         (*(volatile unsigned int *)UMCON0)
#define rUFCON0         (*(volatile unsigned int *)UFCON0)
#define rUBRDIV0        (*(volatile unsigned int *)UBRDIV0)
#define rUDIVSLOT0      (*(volatile unsigned int *)UDIVSLOT0)
#define rUTRSTAT0       (*(volatile unsigned int *)UTRSTAT0)
#define rUTXH0          (*(volatile unsigned int *)UTXH0)
#define rURXH0          (*(volatile unsigned int *)URXH0)
/**************************************************************************************/
#define ULCON0_FUNC_NO_PARITY_MODE             (0b000 << 3)  // 无校验
#define ULCON0_FUNC_NUMBER_STOP_0_BIT          (0b0   << 2)  // Stop bit: 0
#define ULCON0_FUNC_WORLD_LENGTH_8_BIT         (0b11  << 0)  // 8 位数据位

/**************************************************************************************/
#define UCON0_FUNC_CLOCK_SELECTION_PLCK        (0b0   <<10)  //选择PCLK
#define UCON0_FUNC_LOOPBACK_MODE_NORMAL        (0b0   << 5)  //正常模式
#define UCON0_FUNC_TX_MODE_POLLING             (0b01  << 2)  //轮询模式
#define UCON0_FUNC_RX_MODE_POLLING             (0b01  << 0)  //轮询模式

/**************************************************************************************/
#define UFCON0_FUNC_FIFO_DISABLE               (0b0   << 0)  //禁止 FIFO 模式

/**************************************************************************************/
#define UTRSTAT0_FUNC_TRANSMITTER_EMPTY                       (0b1   << 2)  //发送缓冲区为空
#define BIT_LOCATION_UTRSTAT0_FUNC_TRANSMITTER_EMPTY          (0b1   << 2)  //发送缓冲器状态位
#define UTRSTAT0_FUNC_RECEIVE_BUFFER_DATA_READY               (0b1   << 0)  //接收缓冲区已接收到数据
#define BIT_LOCATION_UTRSTAT0_FUNC_RECEIVE_BUFFER_DATA_READY  (0b1   << 0)  //接收缓冲区状态位

/**************************************************************************************/
#define BIT_WIDTH_GPA0                  (4)   
#define GPA0_0_FUNC_INPUT               (0x0 << 0 * BIT_WIDTH_GPA0)
#define GPA0_0_FUNC_OUTPUT              (0x1 << 0 * BIT_WIDTH_GPA0)
#define GPA0_0_FUNC_UART0RXD            (0x2 << 0 * BIT_WIDTH_GPA0)
#define GPA0_0_FUNC_GPA0_INT0           (0Xf << 0 * BIT_WIDTH_GPA0)
							            
#define GPA0_1_FUNC_INPUT               (0x0 << 1 * BIT_WIDTH_GPA0)
#define GPA0_1_FUNC_OUTPUT              (0x1 << 1 * BIT_WIDTH_GPA0)
#define GPA0_1_FUNC_UART0TXD            (0x2 << 1 * BIT_WIDTH_GPA0)
#define GPA0_1_FUNC_GPA0_INT1           (0Xf << 1 * BIT_WIDTH_GPA0)

#define BIT_LOCATION_GPA0_CON0          (0xf << 0 * BIT_WIDTH_GPA0)
#define BIT_LOCATION_GPA0_CON1          (0xf << 1 * BIT_WIDTH_GPA0)

/**************************************************************************************/


定义好了访问寄存器的宏之后,将来写代码时直接使用即可。


二、串行通信编程实战2

1、串口 Tx、Rx 对应的 GPIO 的初始化

给 GPA0CON 的相应 bit 位赋值为相应值,用 C 语言位操作来完成。
    // 初始化 TX RX 对应的 GPIO 引脚
    rGPA0CON &= ~(BIT_LOCATION_GPA0_CON0 | BIT_LOCATION_GPA0_CON1);  
    rGPA0CON |= GPA0_0_FUNC_UART0RXD  | GPA0_1_FUNC_UART0TXD;

2、UCON、ULCON、UMCON、UFCON等主要控制寄存器

依据上节中分析的值进行依次设置即可。
    //几个关键寄存器的设置
    rULCON0 = ULCON0_FUNC_NO_PARITY_MODE | ULCON0_FUNC_NUMBER_STOP_0_BIT | ULCON0_FUNC_WORLD_LENGTH_8_BIT;
    rUCON0 = UCON0_FUNC_CLOCK_SELECTION_PLCK | UCON0_FUNC_LOOPBACK_MODE_NORMAL | UCON0_FUNC_TX_MODE_POLLING | UCON0_FUNC_RX_MODE_POLLING;
    rUMCON0 = 0;
    rUFCON0 = UFCON0_FUNC_FIFO_DISABLE;

3、波特率的计算和设置

(1)第一步,用 PCLK_PSYS 和目标波特率去计算 DIV_VAL: DIV_VAL = (PCLK / (bps x 16)) - 1
(2)第二步,UBRDIV0 寄存器中写入 DIV_VAL 的整数部分
(3)第三步,用小数部分乘以 16 得到 1 的个数,查表得 uBDIVSLOT0 寄存器的设置值
在这里插入图片描述

    //波特率设置  DIV_VAL = (PCLK / (bps X 16) ) - 1
    //PCLK_PSYS 用 66MHz 算  DIV_VAL = (66 X 10^6 / (115200 X 16)) - 1 = 34.807
    //小数是 0.8,0.8 x 16 = 12.8
    rUBRDIV0 = 34;
    //12 0xDDDD(1101_1101_1101_1101b)
    //13 0xDFDD(1101_1111_1101_1101b)
    rUDIVSLOT0 =  0xDDDD;

4、串口发送和接收函数的编写

(1) 写发送函数,主要发送前要用 while 循环等待发送缓冲区为空才能发送。

//串口接收程序,轮询方式,接收一个字节
void uart_putc(char c)
{
    //串口发送一个字符,其实就是把一个字节丢到发送缓冲区中去
    //因为串口控制器发送 1 个字节的速度远远低于 CPU 的速度,所以 CPU 发送1个字节前必须
    //确认串口控制器当前缓冲区是空的(意思就是串口已经发完了上一个字节)
    //如果缓冲区非空则位为0,此时应该循环,直到位为1
    while ((rUTRSTAT0 & BIT_LOCATION_UTRSTAT0_FUNC_TRANSMITTER_EMPTY) != UTRSTAT0_FUNC_TRANSMITTER_EMPTY) ;
    rUTXH0 = c;
}

源自朱有鹏老师.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值