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

📄 嵌入式串口驱动程序.txt

📁 嵌入式串口驱动程序
💻 TXT
字号:
#include<stdarg.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.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 char
printnum(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 + -