一、在使用S5PV210的串口发送和接收的时候,首先要对S5PV210的串口进行配置,我们使用轮询方式时的配置有哪些?

1、配置GPIO,使对应管脚作为串口的发送和接收管脚

  GPA0 0 1 管脚 2 3 可以配置,但我们没有使用
  GPA0CON寄存器[7:4][3:0] 0x22
  GPA0PUD寄存器[3:0] 0 禁止上下拉电阻
2、配置串口单元本身寄存器
  ULCON0 0xE2900000
  数据位:8位
  停止位:1位
  校验位:无
  使用的正模式,非红外。
3、UCON0 0xE2900004

  串口的收发模式:轮训

  串口的时钟使用的PCLK  UFCON0 0xE2900008

  禁止FIFO
  UMCON0 0xE290000C
  禁止Modem
  UBRDIV0 0xE2900028
  UDIVSLOT0 0xE290002C
  UBRDIV0 = PCLK或者SCLK_UART/波特率/16 - 1 的整数部分
  UDIVSLOT0 查表,怎么查?
  PCLK或者SCLK_UART/波特率/16 - 1 的小数部分 * 16 取整
  查表
  PCLK=66500000
  波特率是115200
  UBRDIV0 = 35
  UDIVSLOT0 = 0x0080
  发送数据流程(轮询方式)
  uart0_putc()
  判断UTRSTAT0的BIT1,如果BIT1是0等待如果BIT1是1,就把要发送的一个字节数据写到发送寄存器(UTXH0,0xE2900020)
接收数据流程(轮询方式)
  uart0_getc
  判断UTRSTAT0的BIT0,如果BIT0是0等待如果BIT0是1,从URXH0 0xE2900024读取一个字节的数据。

编程时:
0xE2900000地址单元写3
0xE2900004地址单元写5
0xE2900008地址单元写0
0xE290000C地址单元写0
0xE2900028地址单元写35
0xE290002C地址单元写0x80

uart.h

 #ifndef _UART_H_
#define _UART_H_ #define GPA0CON (*(volatile unsigned int *)0xE0200000)
#define GPA0PUD (*(volatile unsigned int *)0xE0200008) #define ULCON0 (*(volatile unsigned int *)0xE2900000)
#define UCON0 (*(volatile unsigned int *)0xE2900004)
#define UFCON0 (*(volatile unsigned int *)0xE2900008)
#define UMCON0 (*(volatile unsigned int *)0xE290000C)
#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) #define PCLK (66500000) //函数原型声明
extern void uart0_init(void);
extern void uart0_puts(const char *);
extern void uart0_putc(char);
extern char uart0_getc(void);
extern void uart0_gets(char *,int); #endif // _UART_H_

uart.c

 #include "uart.h"

 //初始化串口寄存器
void uart0_init(void){
//配置GPIO口 根据CPU 手册中设置下面的寄存器
//GPA0CON GPA0PUD
ULCON0 = ;
UCON0 = ;
UFCON0 = ;
UMCON0 = ;
UBRDIV0 = ;
UDIVSLOT0 = 0x0080;
GPA0CON = ;
GPA0PUD = ~0xF;
}
//发送一个字符
void uart0_putc(char c){
//判断状态位
while(!(UTRSTAT0 & (<<)));
//发送字符
UTXH0 = c;
}
//接收一个字符
char uart0_getc(void){
while(!(UTRSTAT0 & )); return URXH0;
} //接收一串字符
void uart0_gets(char *str,int len){
char* tmp = str;
int in = len;
//int i;
while(--len){
*tmp = uart0_getc();
if(*tmp == '\r'){
uart0_putc('\n'); //若此处为 \r 则不会输出,若为 \n 则在下一行跳跃输出字符的长度,然后输出字符串
uart0_putc('\r');
break;
}
if(*tmp == ){  //127 是 ubuntu下 kermit软件中的 BACKSPACE按键 需要实现的效果就是当按下回车键的时候终端的上一个数据会被删掉,
len++; //由于此分支的 127 输入到了 *tmp 中,此时的127是无用的,所以要进行 len++ ,但是有一个问题,我们的退格的目的是删除上一个字母,所以127的上一个字符也没用了,需要对len做两次自加进行还原 但是又出现一个问题,如果已经删到第0个元素就不能再自加两次了,这样会造成 len 越来越大。因此要在下面做一个判断
if(len < in){
len++;
}
if(tmp == str){
continue;
} uart0_putc('\b');
uart0_putc(' ');
uart0_putc('\b');
--tmp;
continue;
}
uart0_putc(*tmp);
tmp++;
}
*tmp = ;
} //发送一串字符
void uart0_puts(const char *str){
if(str == ){
return;
}
while(*str){
uart0_putc(*str);
if(*str == '\n'){
uart0_putc('\r');
}
str++;
}
}

main.c

 #include "uart.h"

 void main(void){
char val[];
uart0_init();
while(){ //uart0_gets(val);
uart0_puts("\nstart\n");
uart0_gets(val,);
uart0_puts(val); // uart0_puts(uart0_getc());
}
}

makefile

 PROG=uart
OBJS=main.o uart.o AS=arm-linux-as
CC=arm-linux-gcc
LD=arm-linux-ld
OBJCOPY=arm-linux-objcopy
AFLAGS=-march=armv5te
CFLAGS=-march=armv5te -nostdlib
LDFLAGS=-nostartfiles -nostdlib -Ttext=0x20008000 -e main $(PROG): $(OBJS)
$(LD) $(LDFLAGS) -o $(PROG) $(OBJS)
$(OBJCOPY) -O binary $(PROG) $(PROG).bin
cp uart.bin /tftpboot %.o:%.s
$(AS) $(AFLAGS) -o $@ $< %.o:%.c
$(CC) $(CFLAGS) -c -o $@ $<
clean:
@rm -vf $(OBJS) $(PROG) $(PROG).bin

二、arm9 TQ2440

  这款 arm9 的串口通信跟 上面的 S5PV210相似:

uart.h

 #ifndef __UART_H__
#define __UART_H__ //gpio
#define GPHCON (*(volatile unsigned long*)0x56000070)
#define GPHUP (*(volatile unsigned long*)0x56000078) //uart0 register
#define ULCON0 (*(volatile unsigned long*)0x50000000) //设置传输格式
#define UCON0 (*(volatile unsigned long*)0x50000004) //选择时钟源和中断方式
#define UFCON0 (*(volatile unsigned long*)0x50000008) //是否使用FIFO
#define UMCON0 (*(volatile unsigned long*)0x5000000C) //流量控制模式
#define UTRSTAT0 (*(volatile unsigned long*)0x50000010) //设置状态寄存器 [0] 当接收到数据时,此位被自动设为1 [1] 当发送缓冲区中没有数据时,此位被设置为1 [2] 当发送缓冲区中没有数据,并且最后一个数据也已经发送出去时,此位被自动设为1
#define UBRDIV0 (*(volatile unsigned long*)0x50000028) //设置波特率 //收发数据寄存器
#define UTXH0 (*(volatile unsigned long*)0x50000020) //发数据
#define URXH0 (*(volatile unsigned long*)0x50000024) //收数据
#define UTXH0B (*(volatile unsigned long*)0x50000023) //发数据
#define URXH0B (*(volatile unsigned long*)0x50000027) //收数据 //函数声明
extern void uart0_init(void);
extern char uart0_getc(void);
extern void uart0_putc(char);
extern void uart0_gets(char *,int);
extern void uart0_puts(char *); #endif

uart.c

 #include "uart.h"

 void uart0_init(void){
//配置 gpio 管脚
GPHCON &= ~0xf0;
GPHCON |= 0xa0;
//GPHUP &= 0x0c; //设置 gph2 gph3 内部上拉
GPHUP &= ~0x6; //设置 gph2 gph3 上下拉电阻禁止 ULCON0 = ; //数据位 8位 一个停止位 无校检 正常模式
UCON0 = ; //查询方式
UFCON0 = ; //禁止FIFO
UMCON0 = ; //禁止流量控制
UBRDIV0 = /(*)-; //
} char uart0_getc(void){
char ch;
while(!(UTRSTAT0 & ));
//ch = URXH0;
return URXH0;
} void uart0_putc(char ch){
while(!(UTRSTAT0 & (<<)));
UTXH0 = ch;
} void uart0_gets(char* ch,int len){
int flag = len;
while(--len){
*ch = uart0_getc();
if(*ch == '\r'){
uart0_putc(*ch);
break;
}
if(*ch == ){ //在dnw中 BACK SPACE按键是8 在 kermit下是127
len++; //此次循环接收的是退格符号所以无论如何len都要自加
if(flag == len){ //为了防止回删到开头,所以做个限制
continue;
}
uart0_putc('\b');
uart0_putc(' ');
uart0_putc('\b');
len++;
ch--;
continue;
}
uart0_putc(*ch);
ch++;
}
*ch = ; }
void uart0_puts(char* ch){
while(*ch){
uart0_putc(*ch);
//如果是在kermit 下需要用到下面代码;
/*
if(*ch == '\n'){
uart0_putc('\r');
}
*/
ch++;
} }

main.c

 #include "uart.h"

 void delay(void);

 int main(void){
uart0_init(); uart0_puts("ok start:\n");
while(){
char ch[];
uart0_puts("netboy# ");
uart0_gets(ch,);
uart0_puts(ch);
uart0_puts("\n");
}
return ;
} void delay(void){
int i;
for(i = ; i < 0xf0000; i++){
;
}
}

uart.lds

 SECTIONS
{
. = 0x30000000;
.text :{
main.o (.text);
*.o (.text);
}
.data :{
*.o (.data);
}
__bss_start = .;
.bss :{
*.o (.bss);
}
__end = .;
};

Makefile

 PROG=uart
OBJS=main.o uart.o CC=arm-linux-gcc
LD=arm-linux-ld
OBJCOPY=arm-linux-objcopy
AFLAGS=-march=armv5te
CFLAGS=-march=armv5te -nostdlib
LDFLAGS=-nostartfiles -nostdlib -Ttext=0x30000000 -e main $(PROG): $(OBJS)
$(LD) $(LDFLAGS) -o $(PROG) $(OBJS)
$(OBJCOPY) -O binary $(PROG) $(PROG).bin
cp uart.bin /mnt/hgfs/linux_share/tq2440/
%.o:%.c
$(CC) $(CFLAGS) -c -o $@ $< clean:
@rm -vf $(PROG) $(OBJS) $(PROG).bin

【嵌入式】——arm裸机开发 step by step 之 串口通信的更多相关文章

  1. ARM裸机开发中内存管理库RT_HEAP的使用

    在使用arm芯片进行裸机开发的时候,很多时候都需要内存管理的功能,我们可以使用自己写的内存管理程序,也可以直接使用标准库,不过我一般比较喜欢标准库,速度快,今天就来说说在C语言环境下怎么样进行内存的动 ...

  2. 【嵌入式】——arm裸机开发 step by step 之 按键控制 LED 和 蜂鸣器

    一.arm-9 TQ2440 key.h #ifndef __KEY_H__ #define __KEY_H__ #define GPFCON (*(volatile unsigned long *) ...

  3. ARM裸机开发之交叉工具链和MakeFile工程管理

    一.交叉工具链 嵌入式Linux开发采用交叉开发,简单来说就是在宿主机(PC机)上面编译出能够在其他硬件平台上面运行的程序.在这个过程中,需要用到许多的交叉工具,这些交叉工具的集合就叫做交叉工具链.下 ...

  4. 嵌入式ARM系统开发基础

    从.net到delplhi 从windows到Linxu 未来有多远? 如何突破自己? 什么是自己? 我从哪里来,要到哪里去? 世界是什么? 是世选择了我,还是我选择了世界? 怎么才能够完成蜕变? 去 ...

  5. (转载)用vs2010开发基于VC++的MFC 串口通信一*****两台电脑同一个串口号之间的通信

    此文章以visual C++数据採集与串口通信測控应用实战为參考教程 此文章适合VC++串口通信入门 一.页面布局及加入控件 1, 安装好vs2010如图 2, 新建一个基于VC++的MFC项目com ...

  6. S3C2440—2.裸机开发步骤及工具使用

    文章目录 一.裸机开发步骤简介 1.在X86架构的Windows系统中 2.在X86架构的Ubuntu系统中 3.ARM裸机开发 二.soucre insight使用 1.sourec insight ...

  7. Step by Step: 基于MFC下的COM组件开发-Helloworld

    http://blog.csdn.net/sybifei/article/details/45008745 [这篇文章有问题, 仅供参考] http://blog.csdn.net/define_us ...

  8. 使用Xamarin开发手机聊天程序 -- 基础篇(大量图文讲解 step by step,附源码下载)

    如果是.NET开发人员,想学习手机应用开发(Android和iOS),Xamarin 无疑是最好的选择,编写一次,即可发布到Android和iOS平台,真是利器中的利器啊!而且,Xamarin已经被微 ...

  9. 精通initramfs构建step by step

    (一)hello world  一.initramfs是什么  在2.6版本的linux内核中,都包含一个压缩过的cpio格式 的打包文件.当内核启动时,会从这个打包文件中导出文件到内核的rootfs ...

随机推荐

  1. Spring Security教程(四):自定义登录页

    在前面的例子中,登陆页面都是用的Spring Security自己提供的,这明显不符合实际开发场景,同时也没有退出和注销按钮,因此在每次测试的时候都要通过关闭浏览器来注销达到清除session的效果. ...

  2. DCOS中监控和弹性伸缩方案经验

    监控的选型 我们的DCOS 主要是面向2种业务形态:互联网应用,NFV组件和相关的数据库.2种不同的业务虽然说都是跑在容器内部,但是其实需要监控的信息和指标都是各不相同.因此在选择监控方案的时候我们更 ...

  3. SQL Server 2008 附加数据库之后显示为 只读 的解决方法

    嗯,附加完成后,数据库的灰色的,后面括号里写着(只读). 方法一: 碰到这中情况一般是使用的 sa 或者其它 SQL Server 身份验证登录的,只要改为 Windows 身份验证,再附加数据库即可 ...

  4. [转] 在 Windows 中让任务栏时间显示“秒”

    1.运行 regedit,按回车键进入注册表编辑器 2.定位到: HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explore ...

  5. 分布式系统的那些事儿(四) - MQ时代的通信

    之前在讲RPC通信的各种好处,特别好用,但是RPC并不是万能的,也并不是适用于各种场景的,因为他是同步的:现如今很多场景下的调用都是异步的,系统A调用B后,并不需要知道B的结果,而且对B的结果无所谓, ...

  6. DDR3控制

    很简单的,app_en和app_rdy一握手,代表MIG接受了一个写数据请求或者读数据请求,只要保证app_en和app_rdy握手,根本就不关心写数据rdy,这是MIG的一个bug,你看它源码就知道 ...

  7. bitcoin双花

    https://en.bitcoin.it/wiki/Irreversible_Transactions https://www.reddit.com/r/Bitcoin/comments/2e7bf ...

  8. linux命令(42):tr命令

    Linux tr命令 Linux tr 命令用于转换或删除文件中的字符. tr 指令从标准输入设备读取数据,经过字符串转译后,将结果输出到标准输出设备. 语法: tr [-cdst][--help][ ...

  9. raise EnvironmentError("%s not found" % (mysql_config.path,)) EnvironmentError: mysql_config not found 解决办法

    报错信息如下: Downloading https://pypi.tuna.tsinghua.edu.cn/packages/a5/e9/51b544da85a36a68debe7a7091f068d ...

  10. java中的动态加载和热替换

    https://blog.csdn.net/u010833547/article/details/54312052 ****************************************** ...