ARM UART实验

 

UART 主要是串口通信。本实验就是通过UART0和PC通信。PC那边主要是利用建立一个超级终端实现。

下面的代码主要是实现在PC机的超级终端显示操作菜单。选择相应的菜单,实现对应的功能。

 

 

#define GLOBAL_CLK  1

#include "def.h"
#include "2440addr.h"
#include "option.h"
#include <stdarg.h>


#define LED1 (1<<5)// rGPB[5] =1 ;
#define LED2 (1<<6)// rGPB[6] =1 ;
#define LED3 (1<<7)// rGPB[7] =1 ;
#define LED4 (1<<8)// rGPB[8] =1 ;

char *CmdTip[] ={
     "Please input 1-5 to select test",
     "light led 1" ,
     "light led 2" ,
     "light led 3" ,
     "light led 4"      
       };
      
void Delay_Time(int time)
{
  unsigned int i,j;
  for(i=1;i<100;i++)
    for(j=1;j<time;j++)
    ;
}

void Uart_Initialize(int pclk,int baud)
{
  
    if(pclk == 0)
    pclk    = PCLK;
   
    rUFCON0 = 0x0;   //UART channel 0 FIFO control register, FIFO disable   
    rUMCON0 = 0x0;   //UART chaneel 0 MODEM control register, AFC disable
    rULCON0 = 0x3;   //Line control register : Normal,No parity,1 stop,8 bits
     //    [10]       [9]     [8]        [7]        [6]      [5]         [4]           [3:2]        [1:0]
     // Clock Sel,  Tx Int,  Rx Int, Rx Time Out, Rx err, Loop-back, Send break,  Transmit Mode, Receive Mode
     //     0          1       0    ,     0          1        0           0     ,       01          01
     //   PCLK       Level    Pulse    Disable    Generate  Normal      Normal        Interrupt or Polling
    rUCON0  = 0x245;   // Control register
    rUBRDIV0=((int)(pclk/16./baud+0.5)-1);   //Baud rate divisior register 0
   
    Delay_Time(2); 
}

void UART_Send(int data)
{  
    if(data=='/n')
    {
       while(!(rUTRSTAT0 & 0x2));     
       WrUTXH0('/r');
     }
     while(!(rUTRSTAT0 & 0x2)); //Wait until THR is empty.     
     WrUTXH0(data);
}

//====================================================================
void Uart_SendData(char *pt)
{
    while(*pt)
     UART_Send(*pt++);
}

//=====================================================================
//If you don't use vsprintf(), the code size is reduced very much.
void Uart_Print(char *fmt,...)
{
    va_list ap;
    char string[256];

    va_start(ap,fmt);
    vsprintf(string,fmt,ap);
    Uart_SendData(string);
    va_end(ap);
}


char UART_Receive(){
   while(!(rUTRSTAT0 & 0x1)); //Receive data ready
        return RdURXH0();
   
    return 0;
}

//*****************************************************************************
//get a number for the uart
//*****************************************************************************
int Uart_GetOption(void)
{
    char string[16] ;
    char *p_string = string ;
    char c;
    int i = 0 ;
    int data = 0 ;

    while(( c = UART_Receive()) != '/r' )
    {
  if(c=='/b')  
     p_string--;
  else
    *p_string++=c;
  
  UART_Send( c ) ;
    }

    *p_string = '/0';

 i = 0 ;
 while( string[i] != '/0' )
 {
  data = data * 10 ;
  if( string[i]<'0'||string[i]>'9' )
   return -1 ;
  data = data + ( string[i]-'0' ) ;
  i++ ;  
 } 
 
 return data ;
}

static void cal_cpu_bus_clk(void)
{
 U32 val;
 U8 m, p, s;
 
 val = rMPLLCON;
 m = (val>>12)&0xff;
 p = (val>>4)&0x3f;
 s = val&3;

 //(m+8)*FIN*2 不要超出32位数!
 FCLK = ((m+8)*(FIN/100)*2)/((p+2)*(1<<s))*100;
 
 val = rCLKDIVN;
 m = (val>>1)&3;
 p = val&1; 
 val = rCAMDIVN;
 s = val>>8;
 
 switch (m) {
 case 0:
  HCLK = FCLK;
  break;
 case 1:
  HCLK = FCLK>>1;
  break;
 case 2:
  if(s&2)
   HCLK = FCLK>>3;
  else
   HCLK = FCLK>>2;
  break;
 case 3:
  if(s&1)
   HCLK = FCLK/6;
  else
   HCLK = FCLK/3;
  break;
 }
 
 if(p)
  PCLK = HCLK>>1;
 else
  PCLK = HCLK;
}

   
void Main(void){

    int i,idx;
   
    ChangeClockDivider(3,1);//1:3:6
 ChangeMPllValue(127,2,1);//405MHZ
 cal_cpu_bus_clk(); 
 
 //*** PORT H GROUP
    //Ports  :  GPH10    GPH9  GPH8 GPH7  GPH6  GPH5 GPH4 GPH3 GPH2 GPH1  GPH0
    //Signal : CLKOUT1 CLKOUT0 UCLK nCTS1 nRTS1 RXD1 TXD1 RXD0 TXD0 nRTS0 nCTS0
    //Binary :   10   ,  10     10 , 11    11  , 10   10 , 10   10 , 10    10
    rGPHCON = 0x00faaa;
    rGPHUP  = 0x7ff;    // The pull up function is disabled GPH[10:0]
 
 rGPBCON = 0x015550;
    rGPBUP  = 0x7ff;

    Uart_Initialize(0,115200 );
   
    Uart_Print("*********UART TEST********/n");
   
    for(i=1; i<=4; i++)
  Uart_Print("%d : %s/n", i, CmdTip[i]);
  
    while(1)
 {
      idx = Uart_GetOption();
   
      switch(idx){
            case 1:rGPBDAT=~LED4;break;
            case 2:rGPBDAT= ~LED3;break;
            case 3:rGPBDAT= ~LED2;break;
            case 4:rGPBDAT= ~LED1;break;          
            
      }
      Delay_Time(2000);
      Uart_Print("/n");     
    }
 
}

 

这个实验要用到stdarg.h文件。这个是ADS自带的文件。主要是定义Uart_Print,实现字符串格式化输出。

如果发现无法在PC上输出字符串,那估计是波特率没设置对。检查PCLK是否有值。如果无法在PC的超级终端输入菜单选项,那估计是UART Status(UTRSTAT0)状态寄存器问题。实际上,每次在超级终端输入一个字符,都会马上传给开发板。

你可能感兴趣的:(ARM UART实验)