TQ2440裸机上的UART程序分析
来源:互联网 发布:淘宝妞妞药妆店 编辑:程序博客网 时间:2024/05/20 08:42
此程序是从天嵌提供的测试程序中裁剪出来的,这样看起来会比较简洁
程序到这边下载:http://download.csdn.net/detail/lufeiop02/4127780
一,首先是主程序:
int Main (){ U8 key; U32 mpll_val = 0; Port_Init(); //端口初始化 key = 14; //这5行是关于cpu频率的设置,可以看另一篇文章: mpll_val = (92<<12)|(1<<4)|(1); ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3); ChangeClockDivider(key, 12); cal_cpu_bus_clk(); //这一段代码,选择了串口波特率为 115200。 consoleNum = 0; // s3c2440有三个UART,这里选择UART0 Uart_Init( 0,115200 ); //初始化UART Uart_Select( consoleNum ); //选择UART0 Uart_Printf(" TQ2440 Test Program\n"); //打印字符串,一般就是用这个函数来打印一些信息 return 0;}下面这一大堆函数就是2440lib.c文件中关于UART 的所有函数,当然我们一般只用到其中小部分,我尽量都分析一下
//***************************[ UART ]******************************static int whichUart=0;void Uart_Init(int pclk,int baud){ int i; if(pclk == 0) pclk = PCLK; //如果参数为0,就用系统的PCLK,这个PCLK就APH设备所有的时钟频率,APH设备是指那些比较低速的外围设备
rUFCON0 = 0x0; //UART channel 0 FIFO control register, FIFO disable rUFCON1 = 0x0; //UART channel 1 FIFO control register, FIFO disable rUFCON2 = 0x0; //UART channel 2 FIFO control register, FIFO disable rUMCON0 = 0x0; //UART chaneel 0 MODEM control register, AFC disable rUMCON1 = 0x0; //UART chaneel 1 MODEM control register, AFC disable
//UART0 这个三个串口的配置都是一样的 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 这个寄存器有16位需要配置,12-15位为零,所以禁止FCLK/n时钟(这里可以不理会) 11-10位如下图所示
所以只要第10位为0就选择PCLK给UART波特率 rUBRDIV0=( (int)(pclk/16./baud+0.5) -1 ); //Baud rate divisior register 0 这句话也对应着上图 下图是对上面 《配置功能列表》的详细说明吧
//UART1 rULCON1 = 0x3; rUCON1 = 0x245; rUBRDIV1=( (int)(pclk/16./baud+0.5) -1 );//UART2 rULCON2 = 0x3; rUCON2 = 0x245; rUBRDIV2=( (int)(pclk/16./baud+0.5) -1 ); for(i=0;i<100;i++);}//关于rUBRDIV可以再看看下图
//===================================================================void Uart_Select(int ch) //s3c2440有三个UART,这个函数用来指定用哪个UART{ whichUart = ch; }//=====================================================================//If you don't use vsprintf(), the code size is reduced very much.void Uart_Printf(char *fmt,...) //这个函数用到了可变参数,详细分析请看这篇文章:Uart_Printf()函数学习报告
{va_list ap; char string[256];va_start(ap,fmt);vsprintf(string,fmt,ap); //简单来说,上面这四行代码把参数中的那些字符串都整合在了string数组里了 Uart_SendString(string); //string里其实就是我们要打印到串口的内容了va_end(ap);}//====================================================================void Uart_SendString(char *pt) //打印pt指向的字符串{ while(*pt) //化整为零,逐个字符打印 Uart_SendByte(*pt++); //以字节为单位打印,对应ULCON中设置的“每帧用于发送或接收的数据位的个数”(8位)}//=====================================================================void Uart_SendByte(int data) //重头戏来了,这个函数就是真正在发送数据了{//这边的三个分支对应三个UARTif(whichUart==0) //我们执行的是这个分支{if(data=='\n')//因为在WIN下,'\n'表示回车,换行两个意思,而在别的系统下,它只表示回车,所以最后得给它来个换行,也就是: '\r '{ //遇到'\n'时,实际发送的是'\r\n'while(!(rUTRSTAT0 & 0x2));// Delay(1); //because the slow response of hyper_terminal WrUTXH0('\r');}//下图为UTRSTAT寄存器第1位的功能描述while(!(rUTRSTAT0 & 0x2)); //Wait until THR is empty. 等待发送缓冲器空// Delay(1);WrUTXH0(data);//2440addr.h中:#define WrUTXH0(ch) (*(volatile unsigned char *)0x50000020)=(unsigned char)(ch)}else if(whichUart==1) //同上{if(data=='\n'){while(!(rUTRSTAT1 & 0x2));//Delay(1); //because the slow response of hyper_terminal rUTXH1 = '\r';}while(!(rUTRSTAT1 & 0x2)); //Wait until THR is empty.//Delay(1);rUTXH1 = data;} else if(whichUart==2) //同上{if(data=='\n'){while(!(rUTRSTAT2 & 0x2));//Delay(1); //because the slow response of hyper_terminal rUTXH2 = '\r';}while(!(rUTRSTAT2 & 0x2)); //Wait until THR is empty.//Delay(1);rUTXH2 = data;} }//===================================================================void Uart_TxEmpty(int ch) //判断发送移位寄存器是否为空{if(ch==0) while(!(rUTRSTAT0 & 0x4)); //Wait until tx shifter is empty. else if(ch==1) while(!(rUTRSTAT1 & 0x4)); //Wait until tx shifter is empty. else if(ch==2) while(!(rUTRSTAT2 & 0x4)); //Wait until tx shifter is empty.}***********************************************************************上面是有关发送的函数,下面是有关接收的函数,待以后分析//=====================================================================char Uart_Getch(void){ if(whichUart==0) { while(!(rUTRSTAT0 & 0x1)); //Receive data ready return RdURXH0(); } else if(whichUart==1) { while(!(rUTRSTAT1 & 0x1)); //Receive data ready return RdURXH1(); } else if(whichUart==2) { while(!(rUTRSTAT2 & 0x1)); //Receive data ready return RdURXH2(); } return 0 ;}//====================================================================char Uart_GetKey(void){ if(whichUart==0) { if(rUTRSTAT0 & 0x1) //Receive data ready return RdURXH0(); else return 0; } else if(whichUart==1) { if(rUTRSTAT1 & 0x1) //Receive data ready return RdURXH1(); else return 0; } else if(whichUart==2) { if(rUTRSTAT2 & 0x1) //Receive data ready return RdURXH2(); else return 0; } return 0 ;}//====================================================================void Uart_GetString(char *string){ char *string2 = string; char c; while((c = Uart_Getch())!='\r') { if(c=='\b') { if( (int)string2 < (int)string ) { Uart_Printf("\b \b"); string--; } } else { *string++ = c; Uart_SendByte(c); } } *string='\0'; Uart_SendByte('\n');}//=====================================================================int Uart_GetIntNum(void){ char str[30]; char *string = str; int base = 10; int minus = 0; int result = 0; int lastIndex; int i; Uart_GetString(string); if(string[0]=='-') { minus = 1; string++; } if(string[0]=='0' && (string[1]=='x' || string[1]=='X')) { base = 16; string += 2; } lastIndex = strlen(string) - 1; if(lastIndex<0) return -1; if(string[lastIndex]=='h' || string[lastIndex]=='H' ) { base = 16; string[lastIndex] = 0; lastIndex--; } if(base==10) { result = atoi(string); result = minus ? (-1*result):result; } else { for(i=0;i<=lastIndex;i++) { if(isalpha(string[i])) { if(isupper(string[i])) result = (result<<4) + string[i] - 'A' + 10; else result = (result<<4) + string[i] - 'a' + 10; } else result = (result<<4) + string[i] - '0'; } result = minus ? (-1*result):result; } return result;}//*****************************************************************************//get a number for the uart//*****************************************************************************int Uart_GetIntNum_GJ(void){char string[16] ;char *p_string = string ;char c;int i = 0 ;int data = 0 ;while( ( c = Uart_Getch()) != '\r' ){if(c=='\b')p_string--;else*p_string++=c;Uart_SendByte( 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 ;}//*****************************************************************************
- TQ2440裸机上的UART程序分析
- TQ2440上的PWM实验(裸机)
- ARM裸机实验 UART串口(S3C2440A) TQ2440
- ARM9裸机的UART程序测试
- TX2440裸机程序-uart
- TQ2440裸机启动代码分析
- FriendlyARM UART裸机程序源码
- tq2440 的dma裸机驱动
- TQ2440 Uart的基本应用
- S3C2440裸机程序【2】串口uart程序
- TQ2440裸奔程序>>串口UART的PC机按键测试程序
- Tiny4412裸机程序之UART收发数据
- 4412裸机程序之UART串口
- Eclipse + JLink 编译和调试TQ2440裸机程序【我使用的是win64版本的eclipse】
- 裸机程序在mini2440上的运行
- TQ2440裸奔程序>>串口UART打印printf测试程序
- nandflash裸机程序分析
- 用Keil-MDK开发TQ2440裸机程序入门教程
- 《Computer Networks (fifth edition)》第四章学习小结
- struts2注解详解
- 把HTML表单提交的数据转化成XML文件-XML+Ajax教程
- 表达式树 (rec) => new ParadigmSearchListData { Number = rec.NUMBER, Name = rec.RES_NAME };
- spring注解详解(二)
- TQ2440裸机上的UART程序分析
- linux查看与开启ssh
- 函数模版、类模版、类模版和宏
- 2 CPU 性能监控
- 求一个数组的最长递减子序列
- 链表拷贝的一种算法
- Java多线程之ThreadLocal
- Struts中时间标签s:date
- android 屏幕设置相关