⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uart.c

📁 MIPS架构下串口API函数集合,包括getcharputcharscanfprintf
💻 C
字号:
/*********************************************************************************************************//*/*  程序名称: uart_cmd.c /*/*  程序用途:Pmon平台下串口格式输入,格式输出命令函数/*  编写日期:2005.11.05/*  编写人员:凯达电子南京研发部    董亮   /*  联系方式:support@kd-soc.com/*  程序原理:输出命令通过物理地址调出串口线路状态寄存器(line status register)中第五位状态并进行比较操作/*           输入命令通过物理地址调出串口线路状态寄存器(line status register)中第二位状态并进行比较操作          ***********************************************************************************************************//*调用常规函数库,使用va_arg,va_start,va_end等函数*/#include<stdarg.h>#include<string.h>#include<ctype.h>#include<stdlib.h>#include<rtc.h>/*调用uart口初始化文件*/#include<uart.h>/****************************************************************************************************//*  uart初始化/****************************************************************************************************/void uart_Init(void){	        r16550LCTRL=0x00;              r16550INTEN=0x00;              r16550IIFIFO=0x07;     //00000111        r16550LCTRL=0x80;      //10000000	r16550DLL = 0x18;      //00011000  300 baud [5 MHz crystal:(5M/2)/(6*16*BAUD_DATA)=300 baud]	r16550DLM = 0x00;      // set divisor 12 	r16550LCTRL = 0x03;    //00000011 (8-bit data;1 stop bit;no parity)     		r16550MCTRL = 0x01|0x02|8; //00111011        /* Clear interrupt bits */	r16550INTEN = 0x00;}	/****************************************************************************************************//* test_sendc函数:单个字符输出*****************************************************************************************************/void test_sendchar(char tdata){	//该判断语句也可写为:while((r16550LSTAT & 0x20));	while(!(r16550LSTAT & (0x01<<5))); //等待THR寄存器为空	r16550RXTX = tdata;	}/***************************************************************************************************/ /*  函数名称: test_sendch/*      /*  函数目的:如字符串结束,则回车换行,符合书写规范****************************************************************************************************/void test_SendCh(char tdata){        if(tdata == '\n')        {                test_sendchar('\r');        }        test_sendchar(tdata);}/***************************************************************************************************/ /*  函数名称: test_printf/*      /*  函数目的:利用指针实现简单的字符串输出/*     ****************************************************************************************************/void test_printf(char *pbstring){        while(*pbstring)        test_SendCh(*pbstring++);}/***************************************************************************************************/ /*  结构体名称: printnum/*      /*  结构体目的:作为数字输出专用,在printf函数中调用,用于输出各种格式数字/*      ****************************************************************************************************/static unsigned charprintnum(long unsigned int num,int base,int sign,int maxwidth,int lead)                     //结构体定义{	long unsigned int n;	int count;	char toprint[1024];		if((sign==1)&&((long)num<0)){		test_SendCh('-');		num=-num;		if (maxwidth)maxwidth--;	}	count=0;	while((n=num/base)>0){		toprint[count++]=(num -(n*base));		num=n;	}	toprint[count++]=num;	if (maxwidth && count<maxwidth){		for(n=maxwidth-count;n;n--)		test_SendCh(lead);	}	for(n=0;n<count;n++){		test_SendCh("0123456789ABCDEF"[(int)(toprint[count-(n+1)])]);	}}/*******************************************************************************************************/ /*  函数名称: printf/*      /*  函数目的:实现字符串内格式打印功能/*      说明:test_sendchar函数已经实现单个字符输出的操作,此函数只需要调用常规函数库中va_start与va_end/*            函数来测量字符串长度并做相应的头尾标记,利用循环依次判断每一个字符并输出,参考consol中/*            _doprntx函数原理编写,但将数字格式输出另做结构体调用,避免冗长的代码造成后期修改麻烦。/*/*********************************************************************************************************/void printf(char *fmt,...){	va_list ap;	char c,*str;	int lflag,base,sign,width,lead;	va_start(ap,fmt);	for(;*fmt!='\0';fmt++)                                                           //循环开始	{					if(*fmt=='%')                                                            //判断是否为格式输出规则		{			lflag=0;base=0;sign=0;width=0;lead=' ';                          //初始化相关参数			fmt++;			if(*fmt=='0')			{				lead='0';				fmt++;			}			while(*fmt>='0'&&*fmt<='9')			{				width*=10;				width+=(*fmt-'0');				fmt++;			}			if ((c=*fmt)=='1') 			{				lflag=1;				c=*++fmt;			}			switch(c)                                                      //不同格式输出定义 			{				case'b':case'B':base=2;sign=0;break;                   //二进制格式输出				case'o':case'O':base=8;sign=0;break;                   //八进制格式输出				case'd':case'D':base=10;sign=1;break;                  //十进制格式输出				case'u':case'U':base=10;sign=0;break;                  //无符号十进制格式输出				case'x':case'X':base=16;sign=0;break;                  //十六进制格式输出				case's':				case'S':for(str=va_arg(ap,char*);*str;str++)           //字符串输出					test_SendCh(*str);					break;				case'c':				case'C':test_SendCh(va_arg(ap,char));                  //单个字符格式					break;				default:test_SendCh(c);					break;			}						if(base)                                                       //各种格式数字输出			printnum(lflag ? va_arg(ap,long int):(long int)va_arg(ap,int),				base,sign,width,lead);		}		else  		test_SendCh(*fmt);	}	va_end(ap);}		/***************************************************************************************************//* test_getch函数:单个字符输入函数   *****************************************************************************************************/char test_getchar(void){        while(!(r16550LSTAT & (0x01<<0)));        return r16550RXTX;}/***************************************************************************************************/ /*  函数名称: test_getstring/*      /*  函数目的:使用指针实现简单的字符串输入****************************************************************************************************/void test_getstring(char *pbstring){        char *pbstring2=pbstring;        char bC;        while((bC=test_getchar())!='\r')              {                if(bC=='\b')                                                               //退格处理                {                        if((int)pbstring2<(int)pbstring){test_printf("\b \b");pbstring--;}                }                else                {                        *pbstring++=bC;test_sendchar(bC);                }        }        *pbstring='\0';                                                test_sendchar('\n');}/***************************************************************************************************/ /*  结构体名称: GetIntNum/*      /*  结构体目的:作为数字读入专用,在scanf函数中调用,用于读入不同格式数字/*      ****************************************************************************************************//*for getintnum--atoi*/int atoi(char *s){  return (int) strtol (s, (char **) 0, 10);}/*strtol函数中使用到的toupper函数*/int toupper(int c){	if (islower(c))		return c - ('a' - 'A'); else		return c;} /*strtol函数中使用到的定义 */#define	 max_allowable(A) 	 (MAXINT(sizeof(int))/A - 1)#define MAXINT(w)	(\		((w) == sizeof(signed char))  ? 0x7F :\		((w) == sizeof(short int)) ? 0x7FFF :\		((w) == sizeof(int)) ? 0x7FFFFFFF : 0\		        )#define	ERANGE		34			        int errno;		       /*atoi函数下使用到的strtol函数*/ //自定义判断函数,用来判断输入字符,只允许数字输入int pan(unsigned char c){   if (c > '9' || c< '0') return(0);	}long strtol(	const 	char 	*str, 		char 	**endptr, 		int 	base){	long  	i = 0;	int   	s = 1;	int 	c;		// 空格 	while((!isspace(*str))) {		str++;	                       }		// sign flag check 	if (*str == '+') str++;	else if (*str == '-') {		s = -1;		str++;			      }	if (*str == '0') {		if (toupper(*++str) == 'X')	base = 16,str++;		else if (base == 0)		base = 8;		}	if (base == 0) base = 10;		if (base <= 10)	// str to number 		for (; pan(*str); str++) {			if (i < max_allowable(base))				i = i * base + (*str - '0');			else {				i = MAXINT(sizeof(int));				errno = ERANGE;			}		}	else if (base > 10) {		for (; (c = *str); str++) {			if (pan(c))			 	c = c - '0';			else {				c = toupper(c);				if (c >= 'A' && c < ('A' - 10 + base))				 	c = c - 'A' + 10;				else				 	break;			     }			if (i < max_allowable(base))			 	i = i * base + c;			else {			 	i = MAXINT(sizeof(int));				errno = ERANGE;			    }		}	}	 	else	 	return 0;		// negative base is not allowed 		if (endptr) *endptr = (char *) str;	if (s == -1)		i = -i;	return i;}/*getintnum函数中使用到的strlen函数*/int strlen(const char *s){	int	l = 0;	while (*s++) l++;	return l;}/**************************************************************************************************/#define __isalpha(c) (c >'9')#define __isupper(c) !(c & 0x20)int getintnum(void){        char abStr[30];        char *pbstring=abStr;        int wbase=10;        int wminus=0;        int wlastindex;        int wresult=0;        int wi;                test_getstring(pbstring);                if(pbstring[0]=='-'){wminus=1;pbstring++;}                                       //负数                if(pbstring[0]=='0' && (pbstring[1]=='x' || pbstring[1]=='X'))                   //输入格式为0x十六进制        {                wbase=16;                pbstring+=2;        }                wlastindex=strlen(pbstring)-1;        if( pbstring[wlastindex]=='h' || pbstring[wlastindex]=='H' )                     //输入格式为h 处理方式        {                wbase=16;                pbstring[wlastindex]=0;                wlastindex--;        }        if(wbase==10)                                                                    //十进制        {                wresult=atoi(pbstring);                                                  //atoi函数转换成整型量,相关函数上                 wresult=wminus ? (-1*wresult):wresult;        }        else        {                for(wi=0; wi<=wlastindex; wi++)                                         {                        if(__isalpha(pbstring[wi]))                        {                                if(__isupper(pbstring[wi]))                                        wresult=(wresult<<4)+pbstring[wi]-'A'+10;                                else                                        wresult=(wresult<<4)+pbstring[wi]-'a'+10;                        }                        else                        {                                wresult=(wresult<<4)+pbstring[wi]-'0';                        }                }                wresult=wminus ? (-1*wresult):wresult;        }        return wresult;}/********************************************************************************************************//*  函数名称: test_Scanf/*      /*  函数目的:实现字符串内格式读入功能/*      说明:test_getchar函数已经实现单个字符输出的操作,此函数只需要调用常规函数库中va_start与va_end/*            函数来测量字符串长度并做相应的头尾标记,利用循环依次判断每一个字符并读入/********************************************************************************************************/void test_scanf(char *fmt,...){                                 va_list ap;        char cchar;        int *pwint;        char *pbchar;                va_start(ap, fmt);        while((cchar=*fmt++) != '\0')        {                if(cchar != '%')continue;                                                    //格式输入                switch(*fmt)                {                        case 's':                                                            //字符串输入                        case 'S':                                pbchar = va_arg(ap, char *);                                test_getstring(pbchar);                                break;                        case 'i':                                                            //数值输入                        case 'I':                                pwint = va_arg(ap, int *);                                *pwint =getintnum();                                break;                         case 'c':                                                            //单个字符输入                        case 'C':                                pbchar = va_arg(ap, char *);                                *pbchar =test_getchar();                                break;                }        }        va_end(ap);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -