历史上的今天
返回首页

历史上的今天

今天是: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,即空操作),停止发送字符

推荐阅读

史海拾趣

Comair Rotron公司的发展小趣事

1987年,为了更好地适应市场变化和拓展国际业务,Comair决定进行品牌重塑,将公司名称更改为“Comair Rotron”。同时,公司还在墨西哥建立了新的制造工厂,并在圣地亚哥设立了销售和工程中心,以支持其在北美地区的业务发展。这一举措不仅提升了Comair Rotron的品牌形象,也为其在全球范围内的市场拓展奠定了坚实基础。

天钰(FITIPOWER)公司的发展小趣事

随着电子行业的竞争加剧,Comair Rotron意识到单打独斗已难以满足市场需求。因此,公司开始积极寻求与行业内其他企业的合作机会。通过与多家知名电子企业建立战略合作关系,Comair Rotron不仅获得了更多的业务机会,还通过与合作伙伴的技术交流和资源共享,不断提升自身的技术水平和产品质量。

Advanced Electronic Packaging公司的发展小趣事

随着国内市场的逐渐饱和,Advanced Electronic Packaging公司开始将目光投向海外市场。公司积极参与国际电子展会和技术交流活动,展示其先进的封装技术和优质产品。同时,公司还加大了对海外市场的宣传力度,通过线上线下相结合的方式提升品牌知名度和影响力。在不懈的努力下,公司的产品和服务逐渐赢得了国际市场的认可和青睐,海外市场份额逐年攀升。

Calmos Systems Inc公司的发展小趣事

Calmos Systems Inc公司创立之初,面临着资金短缺、市场竞争激烈的挑战。公司创始人凭借对电子技术的深厚理解和对市场需求的敏锐洞察,带领团队研发出了一款具有创新性的电子产品。然而,由于品牌知名度低,市场推广困难,产品销量一度不佳。为了打开市场,创始人亲自拜访潜在客户,了解他们的需求,不断优化产品功能。经过不懈的努力,产品逐渐赢得了客户的认可,为公司的发展奠定了基础。

Coherent Inc公司的发展小趣事

1966年,Coherent Inc.由一群斯坦福大学的研究人员共同创立,其中包括物理学家James Hobart。初创时期的公司致力于激光技术的研究和开发,逐渐积累起了丰富的技术底蕴。这种对技术的执着追求和不断探索,为公司的后续发展奠定了坚实的基础。

Aromat Corp公司的发展小趣事

随着产品技术的成熟,Aromat Corp开始积极拓展市场。公司加大了对营销和宣传的投入,通过参加行业展会、举办产品发布会等方式提升品牌知名度。同时,Aromat Corp还积极与合作伙伴建立战略合作关系,共同开拓市场,进一步扩大了公司的市场份额。

问答坊 | AI 解惑

cadence原理图设计详解

cadence原理图设计详解…

查看全部问答>

WinCE自带的简单数据库排序字段问题

就是用CeCreateDatabaseEx2 / CeOpenDatabaseEx2.....等API创建打开的简单数据库 现在的情况是:创建、打开、添加、删除、关闭等,统统OK 。 我的问题出现再排序字段上:   我的一条记录有5个字段,其中有两个字段(都是字符串类型) ...…

查看全部问答>

SMDK2410问题

我在我的开发板上运行CE5.0的SMDK2410(flash读写已经修改了) EBoot,运行到OEMPreDownload函数时 打印调试信息发现始终没运行到EbootInitEtherTransport这个函数中 请高人指点一下啊??…

查看全部问答>

mini2440 如何输出串口调试信息?

我用的友善的mini2440开发板,这个板子默认不输出调试信息,该怎么样才可以输出? 谢谢。 …

查看全部问答>

cc2430串口接收程序?

#define SET_MAIN_CLOCK_SOURCE(source) \\    do {                                   \\     ...…

查看全部问答>

lattice 1016

怎么大家都不用LATTICE公司的芯片的吗?怎么相关的帖子这样稀少呢?…

查看全部问答>

所有人都进来看看(我是新人)

大家好,我是一个爱好单片机的初学者。 这几天我一直在关注这个论坛,真的不错这个论坛,   学习单片机是因为我看到汽车的底盘灯很好看,自己想做一个,然后想让他呈流水状,就是流水灯,跑马灯,开始以为就是像汽车的转向器一样,结果上网 ...…

查看全部问答>

EMI与高速PCB设计

EMI与高速PCB设计…

查看全部问答>

【视频】TI制胜解决方案(二):高输入电压、低噪音电源解决方案

好东西陆续有来。 今天给大家介绍TI制胜解决方案——高输入电压、低噪音电源解决方案,该方案主要面向医疗、车载以及工业等对噪音敏感的领域。 欢迎大家评价并关注我的更新与分享哟!…

查看全部问答>

用fpga实现以太网通信,如何进行测试

手上有个spartan6的板子,自带PHY芯片和网口。设计时从XPS里面创建了microblaze软核,并向里面添加了以太网的IP核,测试的目的就是用PC机向网口发送一个数据,fpga接受到该数据并显示出来。 这里我有几点疑问:       &nbs ...…

查看全部问答>