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

📄 fbserial.c

📁 使用方便的串口通信模块 功 能: 串口中断服务程序
💻 C
字号:
使用方便的串口通信模块
/************************************************************************ 
;*  名 称:  FBserial.c 
;*  功 能:  串口中断服务程序,仅需做简单调用即可完成串口输入输出的处理; 
;*          出入均设有缓冲区,大小可任意设置 
;*  说 明:  未利用串口发送硬件BUFF 
***********************************************************************/ 


/************************************************************************ 
可供使用的函数名: 
extern void PutByte(byte c);                 //放入一个字节到发送缓冲区 
extern void PutString(byte  *puts);            //发送一个定义在程序存储区的字符串到串口 
extern void PutBytes(byte *outplace,byte j);   //发送一串数据 
extern void PutHEX(byte c);                    //发送一个字节的hex码,分成两个字节发 
extern byte GetByte (void);                    //从接收缓冲区取一个byte 
extern void SerialInit (word baud);            //串口初始化 

extern byte inbufsign;                      //接收缓冲区数据,有数据=1。 

#define CR PutString("\r\n")               //发送一个回车换行 
#define NUL putstring("\0")                   //发送一个空格 
*************************************************************************/ 

#include <iom16V.h>  
#include <macros.h>  

#define byte unsigned char 
#define word unsigned int 

#define     OLEN 20             //串口发送缓冲大小 
#define     ILEN 20             //串口接收缓冲大小 

byte    outbuf[OLEN];           //发送缓冲 
byte    inbuf[ILEN];            //接收数据缓冲 
byte    *outlast=outbuf;        //最后由中断传输出去的字节位置 
byte    *putlast=outbuf;        //最后放入发送缓冲区的字节位置 
byte    *inlast=inbuf;          //最后接收到接收缓冲区的字节位置 
byte    *getlast=inbuf;         //最后从发送缓冲区取走的字节位置 

struct data                     //位定义 
{ 
    unsigned bit0:1; 
    unsigned bit1:1; 
    unsigned bit2:1; 
    unsigned bit3:1; 
    unsigned bit4:1; 
    unsigned bit5:1; 
    unsigned bit6:1; 
    unsigned bit7:1; 
}bit_flag; 
#define outbufsign0 bit_flag.bit0   //缓冲区数据发完标志   发完=0 
#define outbufsign bit_flag.bit1    //发送缓冲区非空标志   有=1 
#define inbufful bit_flag.bit2      //接收缓冲区满标志     满=1 

//#define inbufsign bit_flag.bit3   //接收缓冲区非空标志   有=1 
//byte outbufsign0;                //缓冲区数据发完标志   发完=0 
//byte outbufsign;                //发送缓冲区非空标志   有=1 
//byte inbufful;                  //接收缓冲区满标志     满=1 

byte inbufsign;                  //接收缓冲区非空标志   有=1 


#define CR PutString("\r\n")        //CR=回车换行 
#define SPACE PutByte(0x20)         //发送一个空格。 

#pragma interrupt_handler   SerialIncept_handler:12     //串口接收中断函数 
#pragma interrupt_handler   SerialSend_handler:14       //串口发送中断函数 
//********************************************************************** 
//函 数 名:   void PutByte(byte c) 
//功    能:   放入一个字节到发送缓冲区 
//说    明: 
//参    数: 
//返 回 值: 
//示    范:   PutByte(0x00); 
//*********************************************************************** 
    void PutByte(byte c) 
    { 
       CLI();              //暂停串行中断,以免数据比较时出错 
       while((((outlast-putlast)==2)&&(outlast > putlast ))||((outlast < putlast)&&(OLEN-(putlast-outlast)==2))) 
       { 
          SEI(); 
          c++;c--; 
          CLI(); 
       } 
       *putlast=c;         //放字节进入缓冲区 
       putlast++;          //发送缓冲区指针加1 
       if (putlast==outbuf+OLEN) putlast=outbuf;  //指针到了顶部换到底部 
       outbufsign=1; 
       if (!outbufsign0)                       //缓冲区无数据 
       { 
          outbufsign0=1; 

          UDR=*outlast;                        //未发送完继续发送 
         outlast++;                          //最后传出去的字节位置加1 
         if (outlast==outbuf+OLEN) outlast=outbuf;//地址到顶部回到底部 
         if (putlast==outlast) outbufsign=0;     //数据发送完置发送缓冲区空标志 
       }                                           //缓冲区开始为空置为有,启动发送 
       SEI(); 
    } 

//********************************************************************** 
//函 数 名:     void PutString(byte  *puts) 
//功    能:   发送字符串到串口 
//说    明:      
//参    数:     发送的字符串 
//返 回 值: 
//示    范:   putstring("\r\n") 
//*********************************************************************** 
    void PutString(byte  *puts) 
   { 
       for(;*puts!=0;puts++)   //遇到停止符0结束 
      PutByte(*puts); 
   } 

//********************************************************************** 
//函 数 名:     void PutBytes(byte *outplace,byte j) 
//功    能:   放一串数据到发送缓冲区,需要定义发送的字节数 
//说    明:      
//参    数:     *outplace:发送的字节数据首地址指针 j:发送的字节数量 
//返 回 值: 
//*********************************************************************** 
    void PutBytes(byte *outplace,byte j) 
    {    int i; 
       for(i=0;i<j;i++) 
       { 
          PutByte(*outplace); 
          outplace++; 
       } 
    } 

//********************************************************************** 
//函 数 名:   PutHEX(unsigned char c) 
//功    能:   发送一个字节的hex码,分成两个字节发。 
//说    明:   发送ASSIC码 
//参    数:   发送的数据 
//返 回 值:   无 
//示    范:   PutHEX(i); 
//*********************************************************************** 
   const byte hex_[]={"0123456789ABCDEF"}; 
    void PutHEX(byte c) 
    { 
       word ch; 
       ch=(c>>4)&0x0f; 
       PutByte(hex_[ch]); 
       ch=c&0x0f; 
       PutByte(hex_[ch]); 
        SPACE; 
    } 

//********************************************************************** 
//函 数 名:   byte GetByte (void) 
//功    能:   从接收缓冲区取一个byte 
//说    明:   如不想等待则在调用前检测inbufsign是否为1 
//参    数:   无 
//返 回 值:   接收到的数据 
//示    范:   i=GetByte(); 
//*********************************************************************** 
    byte GetByte (void) 
    { 
       char c ; 
       while (!inbufsign);    //缓冲区空等待 
      CLI(); 
       c=*getlast;            //取数据 
       getlast++;             //最后取走的数据位置加1 
       inbufful=0;            //输入缓冲区的满标志清零 
       if (getlast==inbuf+ILEN) getlast=inbuf; //地址到顶部回到底部 
       if (getlast==inlast) inbufsign=0;       //地址相等置接收缓冲区空空标志,再取数前要检该标志 
       SEI(); 
       return (c);        //取回数据 
    } 

//********************************************************************** 
//函 数 名:   void SerialSend_handler (void) 
//功    能:   串口发送中断处理 
//说    明: 
//参    数: 
//返 回 值: 
//*********************************************************************** 
    void SerialSend_handler (void) 
    { 
       UCSRA|=(1<<TXC);                       //清发送中断标志 
        if (outbufsign) 
      { 
          UDR=*outlast;                        //未发送完继续发送 
         outlast++;                          //最后传出去的字节位置加1 
         if (outlast==outbuf+OLEN) outlast=outbuf;//地址到顶部回到底部 
         if (putlast==outlast) outbufsign=0;     //数据发送完置发送缓冲区空标志 
        } 
      else 
      { 
          outbufsign0=0; 
      } 
   } 


//********************************************************************** 
//函 数 名:   void SerialIncept_handler (void) 
//功    能:   串口接收中断处理 
//说    明: 
//参    数: 
//返 回 值: 
//***********************************************************************       
    void SerialIncept_handler (void) 
    { 
        if(!inbufful)                          //接收缓冲区未满 
        { 
            *inlast= UDR;                        //放入数据 
            inlast++;                             //最后放入的位置加1 
            inbufsign=1; 
            if (inlast==inbuf+ILEN) inlast=inbuf;   //地址到顶部回到底部 
            if (inlast==getlast)   inbufful=1;     //接收缓冲区满置满标志 
        } 
    } 

/********************************************************************** 
函 数 名:   void SerialInit (unsigned long) 
功    能:   串口初始化 
说    明:   串口初始化成指定波特率,开接收,发送并开相应中断 
参    数:   需要初始化的波特率 
返 回 值:   无 
示    范:   SerialInit (38400); 
***********************************************************************/ 
    void SerialInit (word baud) 
    { 
       CLI(); 
       UCSRC&=(~(1<<URSEL)); 
        UBRRH=(byte)(baud>>8); 
      UBRRL=(byte)baud; 
       
      UCSRB=(1<<RXCIE)|(1<<TXCIE)|(1<<RXEN)|(1<<TXEN);              
                                     //接收中断使能,发送中断使能,接收器与发送器使能 
      UCSRC=(1<<URSEL)|(3<<UCSZ0);    //设置帧格式: 8 个数据位, 1 个停止位*/ 
      SEI();                     //开全局中断 
    } 

⌨️ 快捷键说明

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