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)状态寄存器问题。实际上,每次在超级终端输入一个字符,都会马上传给开发板。