S5PV210 包含 4 个异步收发器(UART),提供 4 个独立的异步串行输入/输出(I/O)端口。所有端口可工作于中断模式或 DMA 模式。提供高达 3Mbps 的位速率。每个 UART 包含 2 个 FIFO 用于接收和发送数据。具有可编程的波特率、红外收发、1 位或 2 位停止位、5~8 位数据位、校验。

其中UART1和UART2也被转为232接口
S5PV210的uart结构图如下

数据发送:要发送的数据帧是可编程的。它包含 1 位起始位, 5~8 位数据位, 1 个可选校验位, 1
或 2 位停止位,这些都通过 ULCONn 寄存器来设置。在 FIFO 模式下发送器将要发送的数据发送给 Tx FIFO,
在非 FIFO 模式下,发送器将要发送的数据发送给 Tx 保持寄存器。
数据接收:和数据发送类似。

串口编程操作步骤如下
1、配置时钟,选择时钟源。
2、配置ULCONn寄存器,设置模式,校验位,停止位和数据位
3、配置UCONn寄存器,设置数据接收和发送模式,以及时钟源等
4、配置UFCONn寄存器,启用或禁用FIFO
5、配置UBRDIVn和UDIVSLOTn寄存器:计算波特率
6、发送数据UTXHn:查询状态寄存器UTRSTATn等待发送器为空,将要发送的8位数据赋给发送缓存寄存器UTXHn
7、接收数据URXHn:查询状态寄存器UTRSTATn等待接收缓冲区有数据可读,从接收缓存寄存器URXHn中取出数据

波特率计算

计算出来的小数部分需要进行查表

start.S

.global _start               /* 声明一个全局的标号 */
_start:bl uart_init     /* 串口初始化 */bl main          /* 跳转到C函数去执行 */
halt:b halt                  /* 死循环 */

uart.c

#define GPA0CON      *((volatile unsigned int *)0xE0200000)
#define ULCON0      *((volatile unsigned int *)0xE2900000)
#define UCON0       *((volatile unsigned int *)0xE2900004)
#define UFCON0      *((volatile unsigned int *)0xE2900008)
#define UTRSTAT0    *((volatile unsigned int *)0xE2900010)
#define UTXH0       *((volatile unsigned int *)0xE2900020)
#define URXH0       *((volatile unsigned int *)0xE2900024)
#define UBRDIV0     *((volatile unsigned int *)0xE2900028)
#define UDIVSLOT0   *((volatile unsigned int *)0xE290002C)/* UART0初始化 */
void uart_init()
{/*** 配置GPA0_0为UART_0_RXD** 配置GPA0_1为UART_0_TXD*/GPA0CON &= ~0xFF;GPA0CON |= 0x22;/* 8-bits/One stop bit/No parity/Normal mode operation */ULCON0 = 0x3 | (0 << 2) | (0 << 3) | (0 << 6);/* Interrupt request or polling mode/Normal transmit/Normal operation/PCLK/*/UCON0 = 1 | (1 << 2) | (0 << 10);/* 静止FIFO */UFCON0 = 0;/*** 波特率计算:115200bps** PCLK = 66MHz** DIV_VAL = (66000000/(115200 x 16))-1 = 35.8 - 1 = 34.8** UBRDIV0 = 34(DIV_VAL的整数部分)** (num of 1's in UDIVSLOTn)/16 = 0.8** (num of 1's in UDIVSLOTn) = 12** UDIVSLOT0 = 0xDDDD (查表)*/UBRDIV0 = 34;UDIVSLOT0 = 0xDDDD;
}static void uart_send_byte(unsigned char byte)
{while (!(UTRSTAT0 & (1 << 2)));  /* 等待发送缓冲区为空 */UTXH0 = byte;           /* 发送一字节数据 */
}static unsigned char uart_recv_byte()
{while (!(UTRSTAT0 & 1));       /* 等待接收缓冲区有数据可读 */return URXH0;             /* 接收一字节数据 */
}void putchar(int c)
{uart_send_byte(c);/* 如果只写'\n',只是换行,而不会跳到下一行开头 */if (c == '\n')uart_send_byte('\r');
}int getchar()
{int c;c = uart_recv_byte();return c;
}void puts(char *str)
{char *p = str;while (*p)putchar(*p++);putchar('\n');
}

main.c

#define GPC0CON      *((volatile unsigned int *)0xE0200060)
#define GPC0DAT     *((volatile unsigned int *)0xE0200064)int main()
{int c;GPC0CON &= ~(0xFF << 12);GPC0CON |= 0x11 << 12;        // 配置GPC0_3和GPC0_4为输出GPC0DAT &= ~(0x3 << 3);     // 熄灭LED1和LED2puts("UART Test in S5PV210");puts("1.LED1 Toggle");puts("2.LED2 Toggle");puts("Please select 1 or 2 to Toggle the LED");while (1){c = getchar();         // 从串口终端获取一个字符putchar(c);           // 回显putchar('\r');if (c == '1')GPC0DAT ^= 1 << 3; // 改变LED1的状态else if (c == '2')GPC0DAT ^= 1 << 4; // 改变LED2的状态}return 0;
}

Makefile

uart.bin: start.o uart.o main.oarm-linux-ld -Ttext 0xD0020010 -o uart.elf $^arm-linux-objcopy -O binary uart.elf $@arm-linux-objdump -D uart.elf > uart.dis%.o : %.carm-linux-gcc -c $< -o $@ -fno-builtin
%.o : %.Sarm-linux-gcc -c $< -o $@clean:rm *.o *.elf *.bin *.dis

实验现象: 按数字 1 改变 LED1 的状态;按数字 2 改变 LED2 的状态。

由于我们在 uart.c 中使用了和 C 库同名的函数: putchar、 getchar、 puts,为了不和 C 库中的同名函
数发送冲突,需要给 gcc 加一个选项-fno-builtin,不使用内建函数。

问:为什么我们没有进行时钟配置相关的操作
答:因为 S5PV210 在启动时,运行 iROM 里的代码已经为我们初始化了时钟,其中 PCLK=66MHz

UART(一)裸机编程相关推荐

  1. 07 树莓派裸机编程,并在Windows MSYS2 QEMU模拟器中运行

    作者 将狼才鲸 创建日期 2022-11-14 Gitee源码和工程地址:才鲸嵌入式 / 开源安防摄像机(嵌入式软件) CSDN文章地址:项目介绍:开源安防摄像机(嵌入式软件) 4)完整的环境安装步骤 ...

  2. mini2440 裸机编程 -led

    又重新做回了嵌入式,想把以前学到的东西从头复习一下.首先从裸机编程开始. 本系列使用的硬件环境是友善之臂的 mini2440,百问网的OpenJtag,所有程序在 linux gcc下编译, 具体硬件 ...

  3. Esp8266 进阶之路25【高级篇】深聊下esp8266的串口 Uart 通讯中断编程,为您准备好了 NONOS 版本 和 RTOS 系统的串口驱动文件。(附带Demo)

    本系列博客学习由非官方人员 半颗心脏 潜心所力所写,不做开发板.仅仅做个人技术交流分享,不做任何商业用途.如有不对之处,请留言,本人及时更改. 序号 SDK版本 内容 链接 1 nonos2.0 搭建 ...

  4. BSP板机支持包、linux启动分析、ARM裸机编程

    文章目录 一.BSP 二.驱动 驱动的基本要素 三.启动分析 1.uboot 2.uboot的作用 3.uboot相关命令 关键的内容: 1)bootargs,启动参数 2)启动命令 3)修改启动延时 ...

  5. 应用编程与裸机编程、驱动编程的区别(Linux应用编程篇)

    用嵌入式Linux硬件平台下的软件开发来说,我们大可将编程分为三种,分别为裸机编程.Linux驱动编程以及 Linux应用编程. 裸机编程: 一般把没有操作系统支持的编程环境称为裸机编程环境,譬如单片 ...

  6. 03 - 程序设计框架:裸机编程中应用层、中间层、驱动层划分

    03-程序设计框架:裸机编程中应用层.中间层.驱动层划分 1.框架设计层次 <代码大全>第五章中,把程序设计分为四个层次: 软件系统,就是整个系统.整个程序 分解为子系统或包.比如我们可以 ...

  7. TQ210_裸机编程(一)——点亮LED灯

    TQ210_裸机编程点亮LED灯 首先查看 TQ210 的底板原理图: 我们可以看到 两个 LED 分别接到 S5PV210 的 GPC0_3 和 GPC0_4 引脚. 这里用了 NPN 三极管,具有 ...

  8. S5PV210(TQ210)裸机编程

    本文更多的是教会大家如何学习. 4.1    汇编学习 4.1.1 基础知识     4.1.2 ARM模拟器 4.2    S5PV210启动流程 4.3    点亮一个LED 4.4    串口 ...

  9. ARM2440触摸屏编程(裸机编程)

    俗话说:合抱之木,生于毫末;九层之台,起于累土;千里之行,始于足下.只有基础扎实了,做事情才能更得心应手.对于编程也是一样的,只有对各个器件的工作原理摸得一清二楚,才能高效地写出好代码.所以学习驱动和 ...

  10. TQ210裸机编程(3)——按键(查询法)

    首先查看TQ210的底板原理图 这次编程只操作KEY1和KEY2,在TQ210核心板原理图中搜索XEINT0 可以看出KEY1和KEY2分别接在S5PV210的GPH0_0和GPH0_1引脚. 这次编 ...

最新文章

  1. AngularJS $eval $parse
  2. 首次使用mysql_mysql的初次使用操作
  3. 脑机交互研究及标准化实践
  4. VS2005调试时变慢解决办法
  5. 数据库面试题目经典大全
  6. oracle拓展磁盘空间,Oracle磁盘空间使用统计
  7. 淘宝双12趣味大数据:150万件打底裤被男人买走了;套套销量暴涨50%...
  8. 贺利坚老师汇编课程50笔记:call和ret配合
  9. 使用rem进行页面适配
  10. KKR创始人亨利·克拉维斯:像实业家那样思考和行动
  11. 【又见LCS】NYOJ-37 回文字符串
  12. CSS中常用的选择器
  13. 使用python gzip进行解压和压缩
  14. 手持振弦采集仪对振弦传感器激励方法和激励电压
  15. 华为AX3路由器获取ipv6外网地址方式
  16. 更改OneDrive网页版OneNote笔记使用桌面应用打开时的默认应用
  17. js中Numer类型最大值9007199254740991,精度丢失问题解决
  18. WordNet相关API介绍及语义相似度计算方法
  19. 新手操作更换固态和重装系统竟然这么麻烦?!
  20. python入门小程序之列表练习

热门文章

  1. 二级域名解析配置方法
  2. Activiti流程定义缓存源码分析5-流程缓存
  3. syntax error near unexpected token else
  4. python名称由来_python的词源_python的由来_同根词_同源词_趣词词源字典
  5. videoder有什么用_videoder
  6. Js鼠标放上去图片变大变小
  7. android高德地图截屏,高德地图-地图截屏
  8. 永不服输的Java之路---重学Java (第二章)
  9. 新款苹果手机_售价千元!苹果今日推出新款手机壳,买吗
  10. 珠海 第十届亚洲机器人锦标赛_逾2000名选手云集珠海竞技第十届亚洲机器人锦标赛...