猫尾巴怎么变粗:S3C2440之UART

来源:百度文库 编辑:偶看新闻 时间:2024/05/04 17:45:30

UART(Universal Asynchronous Receiver/Transmitter,通用异步接收/发送装置)用于异步通信,可以实现全双工发送和接收。s3c2440提供了三个UART端口,它们都可以通过查询、中断和DMA方式传输数据。下面通过超级终端发送字符到2440,2440返回该字符的例子来简要介绍一下s3c2440中UART的用法:

用到的寄存器:

                      GPHCON :端口配置引脚寄存器

                      GPHUP:使能上拉禁止寄存器

                      ULCON0:线路控制寄存器

                      UCON0:通道控制寄存器

                      UTRSTAT0:发送/接收状态寄存器

                      UBRDIV0:波特率分频寄存器

                      UTXTH0:通道0发送缓冲寄存器

                      URXTH0:通道0接收缓冲寄存器

编程流程如下:

1,UART的初始化:包括串口的选择,IO口的初始化,UART的UFCONn,

     UMCONn,ULCONn,UCONn及波特率的初始化

其中波特率的具体计算公式为:时钟源频率÷(波特率×16)-1。

如图:


具体相关寄存器的配置如下:

view plaincopy to clipboardprint?
  1. rGPHCONrGPHCON = rGPHCON & (~(0xffff)) ;  
  2. rGPHCONrGPHCON = rGPHCON | (0xaaa0) ;//除GPH0,GPH1以外的脚都是第二功能,urt0的9个脚  
  3.     rGPHUP  = 0x0;  // 使用内部上拉电阻。  
  4.   
  5. rUFCON0=0x00;   //不使用FIFO  
  6.       rUMCON0=0x00;   //不使用自动流控制  
  7.       rULCON0=0x03;   //不采用红外线传输模式,无奇偶校验位,1个停止位,8个数据位  
  8.       rUCON0=0x245;   //发送中断为电平方式,接收中断为边沿方式,禁止超时中断,允许产生错误状态中断,禁止回送模式,禁止中止  
  9.                       //信号,传输模式为中断请求模式,接收模式也为中断请求模式。  
  10.       rUBRDIV0=( (int)(PCLK/16./baud+0.5) -1 );//?为什么要加0.5?  

2,要发送数据时,等待直到发送缓冲区UTRSTAT0[1]为空.再把数据放入发送缓存器UTXHn中。

要发送的数据,首先被写入FIFO,然后拷贝到发送移位寄存器,接着它从数据输出端(TxDn)依次被移位输出

view plaincopy to clipboardprint?
  1. while(!(rUTRSTAT0 & 0x2));  //等待,直到发送缓冲区为空  
  2. Delay(100);  
  3. WrUTXH0(ch);    //串口0发送字符  
3,要接收数据时,检查串口状态寄存器0,是否有数据到来,然后启动接收,接收到的数据是放到接收缓存器URXHn中。

UART的接收数据:被接收的数据也同样从数据接口RxDn移位输入到移位寄存器,然后拷贝到FIFO中

view plaincopy to clipboardprint?
  1. while(!(rUTRSTAT0 & 0x1));  //检查串口状态寄存器0,是否有数据到来,启动接收过程  
  2. return RdURXH0();  //URXH0串口接收缓存寄存器0  


uart.c

实现查询发式串口的收发功能,接收来自串口的字符,并将接收到的字符发送到超级终端:

view plaincopy to clipboardprint?
  1. static int UartNum=0;   //串口选择的标志位,可以省略,只是方便多个串口选择  
  2. //===============================================================  
  3. //对Uart进行初始化,以所需要的波特率为输入参数  
  4. void myUart_Init(int whichuart, int baud)  
  5. {  
  6.    if(whichuart==0)   //判断是否选择串口0,假如选择串口1,则应该初始化串口1的寄存器  
  7.    {  
  8.         UartNum=0;   //串口选择的标志位  
  9.           
  10.         rGPHCONrGPHCON = rGPHCON & (~(0xffff)) ;  
  11.         rGPHCONrGPHCON = rGPHCON | (0xaaa0) ;//除GPH0,GPH1以外的脚都是第二功能,urt0的9个脚  
  12.         rGPHUP  = 0x0;  // 使用内部上拉电阻。  
  13.       
  14.         rUFCON0=0x00;   //不使用FIFO  
  15.         rUMCON0=0x00;   //不使用自动流控制  
  16.         rULCON0=0x03;   //不采用红外线传输模式,无奇偶校验位,1个停止位,8个数据位  
  17.         rUCON0=0x245;   //发送中断为电平方式,接收中断为边沿方式,禁止超时中断,允许产生错误状态中断,禁止回送模式,禁止中止  
  18.                           //信号,传输模式为中断请求模式,接收模式也为中断请求模式。  
  19.         rUBRDIV0=( (int)(PCLK/16./baud+0.5) -1 );//?为什么要加0.5?  
  20.         Delay(10);  
  21.     }  
  22.   
  23. }  
  24.   
  25. /*******************************************************************/  
  26. void myUart_SendByte(char ch)  
  27. {  
  28.     if (UartNum ==0)      //判断是否选择串口0,在这里也可以不用这句,  
  29.                           //只是方便多个串口选择时用  
  30.     {  
  31.         if(ch=='\n')    //判断是否是换行字符,如果是换行字符,发送一个回车符  
  32.         {  
  33.             while(!(rUTRSTAT0 & 0x2));   //等待,直到发送缓冲区为空  
  34.             //Delay(10);     //超级中断的响应速度较慢   
  35.             WrUTXH0('\r');   //发送回车符  
  36.         }  
  37.         while(!(rUTRSTAT0 & 0x2));  //等待,直到发送缓冲区为空  
  38.         Delay(100);  
  39.         WrUTXH0(ch);    //串口0发送字符  
  40.     }  
  41.       
  42. }  
  43.   
  44. /********************************************************************/  
  45. void Uart_Send (char *str)  
  46. {  
  47.     myUart_Init(0,115200);  
  48.     while (*str)  
  49.     myUart_SendByte(*str++);  
  50. }     
  51. /********************************************************************/  
  52. char myUart_ReceiveByte(void)    //接收字符函数  
  53. {  
  54.     if(UartNum==0)   //选择串口0  
  55.     {         
  56.         while(!(rUTRSTAT0 & 0x1));  //检查串口状态寄存器0,是否有数据到来,启动接收过程  
  57.         return RdURXH0();  //URXH0串口接收缓存寄存器0  
  58.     }  
  59.     return 0;  
  60. }  
  61.   
  62. /********************************************************************/  
  63. void Uart_receive(char *string)     //接收函数  
  64. {  
  65.      char *stringstring2 = string;     
  66.      char c;  
  67.      myUart_Init(0,115200);  //串口的选择与波特率的选择  
  68.      while((c = myUart_ReceiveByte())!='\n')    //循环判断接收字符函数返回的字符是不是换行字符\r是换行符?\n?  
  69.      {  
  70.         if(c=='\b')//\b回退符  
  71.         {  
  72.             if( (int)string2 < (int)string )  
  73.             {  
  74.                 Uart_Printf("\b \b");       
  75.                 string--;  
  76.             }  
  77.         }  
  78.         else   
  79.         {  
  80.             *string++ = c;  
  81.             myUart_SendByte(c);  
  82.         }  
  83.      }  
  84.      *string='\0';      //接收完毕后执行空格  
  85.      myUart_SendByte('\n');  //如果接收完毕后,补充一个回车  
  86. }  
测试用主函数:

view plaincopy to clipboardprint?
  1. int Main(void)      
  2. {  
  3.     char *str;           
  4.     char *string;  
  5.     ChangeClockDivider(3,1);        //1:3:6  
  6.     ChangeMPllValue(127,2,1);       //405MHZ  
  7.     Port_Init();  
  8.     Isr_Init();  
  9.           
  10.     Uart_Send("Please Input a string:\n");   //超级终端提示输入一串字符  
  11.     Uart_receive(string);         //2440接收字符  
  12.     *str=*string;     //发送的跟接收的字符相等  
  13.     Delay(500);           
  14.     Uart_Send(str);      //2440发送字符显示到超级终端上  
  15.     while(1);     
  16. }  

效果图:



完整工程文件可在这里下载。