TX2440裸机程序-uart
2013-10-27 15:53
309 查看
该文章部分参考/article/8096645.html
一、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 <stdarg.h> #include <string.h> #include <stdlib.h> #include <stdio.h> #include <ctype.h> //==================================================== // 函数定义区 //==================================================== 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("hailin\n"); //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,即空操作),停止发送字符 myUart_SendByte(*str++);//*str++ 1、先发送指针*str指向字符 // 2、指针str=str+1,指向下个字符 } //==================================================== // 语法格式:void myUart_receive(char *string) // 功能描述: 接收字符串 // 入口参数: 字符串指针 // 出口参数: 无 //=================================================================== void myUart_receive(char *string) { char *string2 ; char c; string2 = string; myUart_Init(0,115200); while((c = myUart_ReceiveByte())!='\r')//'\r'--回车,当有回车按下,表示字符串输入结束 { if(c=='\b')//'\b'--退格,当有TAB键按下,在SecureCRT显示退格 { if( (int)string2 < (int)string ) { printf("\b \b"); string--; } } else { *string++ = c; myUart_SendByte(c); } } *string='\0'; myUart_SendByte('\n'); } void myUart_Printf(char *fmt,...) { va_list ap; char string[256]; va_start(ap,fmt); vsprintf(string,fmt,ap); myUart_Send(string); va_end(ap); }
原计划:通过逻辑分析仪监测2440与PC机的uart通信,但是uart采用RS232模式,只支持点对点,不支持一对多。所以无法实现监测。目前通过监测2440的TXD对应的RS232发送端,了解数据发送过程。
在main()执行下面程
myUart_Printf("hailin\n");
myUart_SendByte(0x35);
利用逻辑分析仪查看2440的TXR端 的波形如下:(监测到发送端与程序一致。)
通道0设置如下:
五、uart传输分析
uart传输格式:1起始位 +8位数据位+1位停止位。RS232逻辑是负逻辑,即+12V为逻辑0,-12V为逻辑1;而2440的uart逻辑是正逻辑。而下图是2440的TXD端经过max3232芯片转换为RS232负逻辑,即显示逻辑0实质是2440发送的逻辑1。2440发送0x68(即h)数据,发送顺序:以字节形式先LSB发送后MSB发送。发送数据0001,0110 。
相关文章推荐
- 八、mini2440裸机程序之UART(2)UART0与PC串口通信
- TX2440裸机程序-触摸屏
- FriendlyARM UART裸机程序源码
- FriendlyARM UART裸机程序源码
- 八、mini2440裸机程序之UART(1)简单介绍【转】
- 八、mini2440裸机程序之UART(2)UART0与PC串口通信【转】
- TQ2440裸机上的UART程序分析
- 八、mini2440裸机程序之UART(1)简单介绍
- ARM裸机程序开发21(2440串口:申嵌源码2440lib.c文件中关于UART的操作)
- ARM9裸机的UART程序测试
- 第三章 裸机_第一个裸机程序(上)
- eclipse调试arm裸机程序
- 【OK6410裸机程序】串口初始化
- s3c6410 uart 裸机 轮询 非fifo
- 只用串口和网络裸机开发ARM程序(OK6410开发板)
- ARM裸机程序之LED灯
- 基于i.MX233的UART测试程序
- ARM 裸机程序学习 03 - 发送SOS信号(汇编 + C)
- 一灯大师之点亮OK6410开发板上4个LED裸机程序---嵌入式回归第十篇
- 在没有仿真器的情况下调试ok6410裸机程序