历史上的今天
今天是:2024年11月25日(星期一)
2019年11月25日 | TX2440裸机程序-uart
2019-11-25 来源:eefocus
一、uart原理简介
数据通信方式为:并行通信与串行通信两种:
§并行通信:利用多条数据线将数据的各位同时传送。
它的特点是:传输速度快,是用于短距离通信;
§串行通信:利用一条数据线将数据一位位地顺序传送。
特点是通信线路简单,利用简单的线缆就实现通信,低成本,是用于远距离通信。
异步通信:
ª异步通信:以一个字符为传输单位,通过两个字符间的时间间隔是不固定的,然而同一字符中的两个相邻位之间的时间间隔是固定的。
ª通信协议:是指通信双方约定的一些规则。在异步通讯时,对数据格式有如下约定:规定有空闲位、起始位、资料位、奇偶校验位、停止位。
起始位:先发一个逻辑“0”信号,表示传输字符的开始;
数据位:紧接在起始位之后。数据位的个数可以是4、5、6、7、8等,从最低位开始传送,靠时钟定位。
奇偶校验位:数据位加上这一位后,使得“1”的位数应为偶数(偶校验)或(奇校验),以此校验数据传送的正确性。
停止位:它是一个字符数据的结束标志。
空闲位:处于逻辑“1”状态,表示当前线路没有数据传送。
UART:Universal Asynchronous Receiver/Transmitter(通用异步收发送器),用来传输串行数据,发送数据时,CPU将并行数据写入UART,UART按照一定格式在TxD线上串行发出;接收数据时,UART检测到RxD线上的信号,将串行收集放到缓冲区中,CPU即可读取UART获得的这些数据。
UART最精简的连线形式只有3根线,TXD用于发送,RXD用于接收,GND用于提供参考电平。UART之间以帧作为数据传输单位,帧由具有完整意义的若干位组成,它包含开始位、数据位、校验位和停止位。发送数据之前,互相通信的UART之间要约定好数据传输速率(波特率的倒数)、数据的传输格式(多少个数据位、是否使用校验位、奇校验还是偶校验、多少个停止位)。
二、s3c2440 uart特性
S3C2440的通用异步收发器(UART)配有3个独立异步串行I/O(SIO)端口,每个都可以通过产生中断或DMA请求(及查询)来进行CPU和UART之间的数据传输。如下图所示:每个UART包含一个波特率发生器、发送器、接收器和一个控制单元。
波特率发生器可以由PCLK、FCLK/n或UEXTCLK(外部输入时钟)时钟驱动。UART通过使用系统时钟可以支持最115.2Kbps的比特率。如果是使用外部器件提供UEXTCLK的UART,则UART可以运行在更高的速度。发送器和接收器各包含一个64字节的FIFO和数据移位器。
发送数据:
1、将外设总线的数据写入到发送缓冲区(缓冲区由控制单元中UFCONn控制寄存器设置:FIFO模式或非FIFO模式)
2、将发送缓冲区数据复制到8bit的发送移位器中。若非FIFO模式,操作一次即可;而FIFO模式根据存储深度决定。
3、波特率发生器提供将数据从发送数据引脚(TXDn)移出的移位时钟。
接收数据同发送数据相似。从接收数据引脚(RXDn)移入收到的数据,接着从移位器复制到FIFO。

波特率发生器
每个UART的波特率发生器为发送器和接收器提供串行时钟,波特率发生器的时钟源可以选择S3C2440A的内部时钟系统或者UEXTCLK。波特率时钟是通过16和由UART波特率分频寄存器(UBRDIVn)指定的16位分频系数来分频源时钟(PCLK,FCLK/n或者UEXTCLK)产生的,UBRDIVn由下列表达式确定:
UBRDIVn=(int)(UART时钟/(波特率*16))-1
UART时钟:PCLK,FCLK/n或者UEXTCLK,例如,如果波特率为115200bps并且UART时钟为25MHz,则UBRDIVn为:
UBRDIVn=(int)(25000000/(115200*16))-1=(int)(13.5)-1(取最接近的整数)=14-1=13
三、s3c2440 uart应用
我用的开发板是天祥的TX2440,电路连接如图所示:

介绍发送和接收操作之前,先介绍几个重要的寄存器
UBRDIVn寄存器:设置波特率,UART的时钟源有两种选择:PCLK、UEXTCLK、FCLK/n,其中n的值通过UCON0-UCON2联合设置
ULCONn寄存器:设置传输格式

UCONn寄存器:它用于选择UART时钟源、设置UART中断方式



UFCONn寄存器:用于设置是否使用FIFO,设置各FIFO的触发阙值,即发送FIFO中有多少个数据时产生中断、接收FIFO中有多少个数据时产生中断。并可以通过设置UFCONn寄存器来复位各个FIFO。读取UFSTATn寄存器可以知道各个FIFO是否已经满,其中有多少个数据。

UMCONn寄存器:用于流量控制

UTRSTATn寄存器:表明数据是否已经发送完毕、是否已经接收到数据

UERSTATn寄存器,用来表示各种错误是否发生
UTXHn寄存器,CPU将数据写入这个寄存器,UART即会将它保存到缓冲区中,并自动发送出去

URXHn寄存器,当UART接收到数据时,CPU读取这个寄存器,即可获得数据。

对于S3C2440,使用UART之前,首选需要对2440的UART模块进行初始化,
1、uart对应IO端口设置
2、传输帧格式设置(如数据位、停止位、基偶校验位等)
3、传输协议设置(是否FIFO,中断等)
4、波特率生成设置
/*1、uart对应IO端口设置*/
rGPHCON = rGPHCON & (~(0xffff)); //UART0: RXD0<==>GPH3 TXD0<==>GPH2
rGPHCON = rGPHCON | (0xaaa0) ; //设置GPH端口为UART口,详情见S3C2440手册输入输出端口
rGPHUP = 0x0; //使能上拉功能
/*2、传输帧格式设置*/
rULCON0=0x03; //不采用红外线传输模式,无奇偶校验位,1个停止位,8个数据位
/*3、传输协议设置*/
rUFCON0=0x00; // 不使用FIFO
rUMCON0=0x00; //不使用自动流控制
rUCON0=0x245; //发送中断为电平方式,接收中断为边沿方式,禁止超时中断,允许产生错误状态中断,禁止回送模式,禁止中止
//信号,传输模式为中断请求模式,接收模式也为中断请求模式。
/*4、波特率生成设置*/
rUBRDIV0=( (int)(pclk/16/baud+0.5) -1 ); //根据波特率计算UBRDIV0的值
四、uart程序
//=========================================================================
// 工程名称: UART.mcp
// 文件名称: main.c
// 功能描述: 通过超级终端完成PC和S3C2440的数据传输,利用超级终端输入需要发送的字符,回车后,字符会再发送回来显示。
// 1、通过串口0、1发送和接收单个字节
// 2、通过串口0、1发送和接收字符串
// 组成文件: main.c 2440lib.c 2440init.s 2440slib.s
// 头文件: 2440addr.h def.h option.h 2440lib.h 2440slib.h
// 程序分析:
// 硬件连接: 用串口线将开发板和PC机串口相连
// 维护记录: 2011年4月7日
//
//
//=========================================================================
#include "2440addr.h"
#include "2440lib.h"
#include "2440slib.h"
#include "option.h"
#include #include #include #include #include //==================================================== // 函数定义区 //==================================================== extern void Delay(int time); void myUart_Select(int ch); void myUart_Init(int whichuart, int baud); void myUart_SendByte(char ch); char myUart_ReceiveByte(void); void myUart_Send (char *str); void myUart_receive(char *string); void myUart_Printf(char *fmt,...); extern unsigned int PCLK; static int UartNum=0; char *string; //==================================================== // 语法格式:int Main(void) // 功能描述: 发送并接收字符串,测试UART通信 // 入口参数: 字符串指针 // 出口参数: 无 //====================================================================== int Main(void) { SetSysFclk(FCLK_400M);//FCLK_400M=((92<<12)|(1<<4)|1),MPLL=2*(92+8)*12M/((1+2)*2)=400M //电源工作模式默认NORMAL,FCLK=MPLL ChangeClockDivider(2, 1);//设置FCLK HCLK PCLK 分频比1:8:16 CalcBusClk();//启动总线 myUart_Select(0);//UART的端口选择,0--选择UART0,1--选择UART1 (只可以选择UART0和UART1) myUart_Init(0,115200); while(1) { Delay(500); //myUart_Printf("Please Input a string:n"); myUart_Send("Please Input a string:n");//myUart_Printf与myUart_Send功能相同。 myUart_receive(string); //myUart_Printf("hailinn"); //myUart_SendByte(0x35); Delay(500); myUart_Send(string); myUart_Send("n"); } } void myUart_Select(int ch)//UART的端口选择,UartNum定义成全局变量 { UartNum = ch; } //==================================================== // 语法格式:void myUart_Init(int whichuart, int baud) // 功能描述: 对Uart进行初始化,以所需要的波特率为输入参数 // 入口参数: UART端口号 波特率 // 出口参数: 无 //====================================================================== void myUart_Init(int pclk, int baud) { if (pclk == 0) pclk = PCLK; if(UartNum == 0) //判断是否使用UART0 { /*1、uart对应IO端口设置*/ rGPHCON = rGPHCON & (~(0xffff)); //UART0: RXD0<==>GPH3 TXD0<==>GPH2 rGPHCON = rGPHCON | (0xaaa0) ; //设置GPH端口为UART口,详情见S3C2440手册输入输出端口 rGPHUP = 0x0; //使能上拉功能 /*2、传输帧格式设置*/ rULCON0=0x03; //不采用红外线传输模式,无奇偶校验位,1个停止位,8个数据位 /*3、传输协议设置*/ rUFCON0=0x00; // 不使用FIFO rUMCON0=0x00; //不使用自动流控制 rUCON0=0x245; //发送中断为电平方式,接收中断为边沿方式,禁止超时中断,允许产生错误状态中断,禁止回送模式,禁止中止 //信号,传输模式为中断请求模式,接收模式也为中断请求模式。 /*4、波特率生成设置*/ rUBRDIV0=( (int)(pclk/16/baud+0.5) -1 ); //根据波特率计算UBRDIV0的值,通过加上0.5,提高精度。 Delay(10); } else if(UartNum == 1) { rGPHCON = rGPHCON & (~(0xffff)) ; //UART1: RXD1<==>GPH5 TXD1<==>GPH4 rGPHCON = rGPHCON | (0xaaa0) ; //设置GPH端口为UART口 rGPHUP = 0x0; // 使能上拉功能 rULCON1=0x3; rUFCON1=0x0; rUMCON1=0x0; rUCON1=0x245; rUBRDIV1=( (int)(pclk/16./baud+0.5) -1 ); Delay(10); } } //==================================================== // 语法格式:void myUart_SendByte(char ch) // 功能描述: 发送字节数据 // 入口参数: 发送的字节数据 // 出口参数: 无 //==================================================================== void myUart_SendByte(char ch) { if (UartNum ==0) { if(ch=='n')//判断发送的字符是不是'n'(换行) { while(!(rUTRSTAT0 & 0x2)); //等待,直到发送缓冲区为空 // Delay(10); //超级中断的响应速度较慢 WrUTXH0('r'); //发送回车符 } //如果发送的字符不是'n'(换行) while(!(rUTRSTAT0 & 0x2)); //等待,直到发送缓冲区为空 // Delay(10); WrUTXH0(ch); //发送字符 } else //使用UART1 { if(ch=='n')//判断发送的字符是不是'n'(换行) { while(!(rUTRSTAT1 & 0x2)); //等待,直到发送缓冲区为空 // Delay(10); //等待 rUTXH1='r'; } while(!(rUTRSTAT1 & 0x2)); //Wait until THR is empty. // Delay(10); WrUTXH1(ch); } } //==================================================== // 语法格式:char myUart_ReceiveByte(void) // 功能描述: 接收字节数据 // 入口参数: 无 // 出口参数: 接收的字节数据 //==================================================================== char myUart_ReceiveByte(void) { if(UartNum==0) { while(!(rUTRSTAT0 & 0x1)); //判断接收缓冲区是否有有效数据,有数据时UTRSTAT0.1=1 //等待接收数据 return RdURXH0(); } else if(UartNum==1) { while(!(rUTRSTAT1 & 0x1)); //等待接收数据 return RdURXH1(); } return 0; } //==================================================== // 语法格式:void myUart_Send (char *str) // 功能描述: 发送字符串 // 入口参数: 字符串指针 // 出口参数: 无 //==================================================================== void myUart_Send (char *str) { myUart_Init(0,115200);//每次发送字符串时,都初始化串口UART while (*str)//发送字符串,直到字符串的结束符‘0’(对应ASCII的0,即空操作),停止发送字符
上一篇:TX2440裸机程序-AD
下一篇:TX2440裸机时钟-PWM
史海拾趣
|
就是用CeCreateDatabaseEx2 / CeOpenDatabaseEx2.....等API创建打开的简单数据库 现在的情况是:创建、打开、添加、删除、关闭等,统统OK 。 我的问题出现再排序字段上: 我的一条记录有5个字段,其中有两个字段(都是字符串类型) ...… 查看全部问答> |
|
我在我的开发板上运行CE5.0的SMDK2410(flash读写已经修改了) EBoot,运行到OEMPreDownload函数时 打印调试信息发现始终没运行到EbootInitEtherTransport这个函数中 请高人指点一下啊??… 查看全部问答> |
|
大家好,我是一个爱好单片机的初学者。 这几天我一直在关注这个论坛,真的不错这个论坛, 学习单片机是因为我看到汽车的底盘灯很好看,自己想做一个,然后想让他呈流水状,就是流水灯,跑马灯,开始以为就是像汽车的转向器一样,结果上网 ...… 查看全部问答> |
|
【视频】TI制胜解决方案(二):高输入电压、低噪音电源解决方案 好东西陆续有来。 今天给大家介绍TI制胜解决方案——高输入电压、低噪音电源解决方案,该方案主要面向医疗、车载以及工业等对噪音敏感的领域。 欢迎大家评价并关注我的更新与分享哟!… 查看全部问答> |
|
手上有个spartan6的板子,自带PHY芯片和网口。设计时从XPS里面创建了microblaze软核,并向里面添加了以太网的IP核,测试的目的就是用PC机向网口发送一个数据,fpga接受到该数据并显示出来。 这里我有几点疑问: &nbs ...… 查看全部问答> |




