基于UART实现数据的自发自收

基于UART的自发自收调试

                        

UART(Universal Asynchronous Receiver  and  Transmiter)通用异步接收/发送装置。UART提供了RS—232C数据接口。

UART是什么?UART是一种通用串行数据总线,用于异步通信,该总线双向通信,可以实现全双工传输和接受。在嵌入式设计中,UART用来与PC进行通信,包括与监控调试器和其他部件,比如EEPROM。

UART的工作原理和功能。他将由计算机内部传送过来的并行数据转化为输出的串行数据流,将计算机外部来的串行数据转换为字节,供计算机内部使用并行数据的器件使用。在输出的串行数据流中加入奇偶校验为。在输出数据流中加入启停标志,并从接受数据流中删除启停标志。处理有键盘或鼠标发出的中断信号(键盘和鼠标也是串行设备)。可以处理计算机与外部串行设备的同步管理问题。

在使用UART之前,我们需要设置波特率,传输格式(数据位个数,是否校验位,奇还是偶校验位,停止位个数,是否流量控制)。对于具体的CPU来说,例如(2410/2440)还要选择所涉及的管脚为UART功能,选择UART通道的工作模式为中断模式还是DMA模式,设置好后,往某个寄存器写入数据即可发送,读取某个寄存器即可接收到数据。可以通过轮询的方式来获知数据的收发情况。

初步了解了UART的功能和基本工作原理之后,开始今天的整理。相信在整理的过程中,自己又会有与众不同的收获。

对于UART的设置,这个需要根据电路图,设置GPHCON的对应管脚(S3C2410有3个uart接口,具体接哪个接口,需要结合电路图),我的是要求在uart0上的。

ULCONn寄存器,他包括三种寄存器UART0,UART1,UART2,通过这个寄存器可以设置FIFO的相关属性。可以设置传输数据的位数,停止位的位数,校验模式,红外模式。

UCONn寄存器,同样包括三个,UCON0,UCON1,UCON2。他可以用来设置接收数据和发送数据的模式,接收错误状态使能,接受超时使能,接收中断方式,发送中断方式,时钟选择。

UFCONn寄存器,同样有三个UFCON[0:2],共有八位,可以设置FIFO使能,设置FIFO的触发阀值。

UMCONn寄存器,同样也有三个,由八位组成,它主要用于流量控制。

UTRSTATn寄存器,他由三位构成,这个寄存器主要用来表明数据是否已经发送完毕,是否已经接收到数据。

UERSTATn寄存器,用来表示各种错误是否发生。

UFSTATn寄存器,由16位组成,主要用来设置FIFO什么时候发送和接收数据。

UTXHn寄存器,CPU写寄存器。

 URXHn寄存器,CPU读寄存器。

UBRDIVn寄存器,主要用来设置波特率,这个波特率的值的确定需要根据时钟源和公式。计算公式如下:UARDIVNn=(int)(UART时钟)/(设置的波特率*16)。

下面来说说实验程序,本次实验的程序是使用板子接收PC机上发送过来的数据,按原样进行显示。

 

汇编在此就不写了,直接写C程序,因为汇编部分还有不懂得,还得继续啃。

在ADS1.2里,建立一个头文件,在C程序中调用一下即可。

在reg2410.h中:

             #define rGPHCON      (*(volatile     unsigned*)0x56000070)

             #define  rUBRDIV0     (*(volatile     unsigned*)0x56000028)

             #define  rULCON0      (*(volatile    unsigned *)0x50000000)

#define  rUCON0        (*(volatile    unsigned *)0x56000004)

#define rUTRSTAT0   (*(volatile   unsigned *)0x50000010)

#define rUTXH0               (*(volatile   unsigned *)0x50000020)

#define rURXH0               (*(volatile   unsigned *)0x50000024)

在reg2410.h这个文件里,设置了控制UART的相关寄存器的地址,这些地址都是固定的,在文档查找即可,他们分别是什么寄存器以及各自的功能上面有描述,就不再赘述。

Reg2410.c文件如下:

             #include“reg2410.h”          //上面所建立的头文件

             #define  TXD0READY (1<<2)   //(1<<2)=4

             #define  RXD0READY        (1)   

             #define  PCLK  50700000

             #defineUART_CLK     PCLK     //设置UART的时钟为pclk

             #define  UART_BPS    115200   //设置串口的波特率为115200

             #defineUART_BRD (int)(UART_PCLK/(UART_BPS)*16)-1//设置UART的波特率

             Void       SendByte(char dat)    //发送的字节

             {

                    While(!(UTRSTAT0&TXD0READY));//缓存寄存器中和发送移位寄存器中没有有效值,会被自动置壹,UTRSTAT为0100与TXD0READY(0100)相与,[3]位为1,也就是数据传完了,然后非一下为假,则不执行分号,意思为等待,直接进行下一句;如果UTRSTAT0&TXD0READY的结果为0,则说明数据还没有完全从缓存寄存器传输到uart读写状态寄存器中,则等待。

                    UTXH0=dat;

}

char       RecByte(void)

{

       While(!(UTRSTAT0&RXD0READY));// RXD0READY接受到数据,只要接受缓存寄存器保留通过RXDn端口接受的有效值,其值自动为1,URSTAT0&RXD0READY与的结果为1,非后的结果为假,则不执行分号;若没有接收到数据,则(!(UTRSTAT0&RXD0READY))为真,执行分号,一直等待接收到为止。

       Return   URXH0;

}

             Intmain()

             {

                    rGPHCON=(rGPHCON&~(0xf<<4)|(0xa<<4));//设置GPFCON的2,3引脚,因为UART0的输入输出引脚是通过他们完成的

                    rUBRDIV0=UART_BRD;//设置UART的波特率

                    rULCON0=3;//表明数据传输时的位数,是否有校验位,有几个停止位,是否运用FIFO

                    rUCON0 =(1<<2)|1;//设置数据发送和接受的查询方式,为循环查询

                    for(;;)//轮询接受数据和发送数据

                    {

                           SendByte(RecByte());

}

}

            

 

有点抽象,有点难度,理解最重要!

你可能感兴趣的:(UART,ULCON,UCON,UFCON,UTRSTAT,UBRDIV)