首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

用软件实现的异步串行口源程序代码

用软件实现的异步串行口源程序代码

用软件实现的异步串行口源程序代码





//串口中断服务程序,仅需做简单调用即可完成串口输入输出的处理
//出入均设有缓冲区,大小可任意设置。
//*************************************************************************
#i nclude "TestSerial.h"
#define BAUDRATE0  115200  // 用户定义的UART0 波特率
#define DB_SENDMAXSIZE 0xf0
#define DB_RECMAXSIZE 0xf0
bit CommRecDataOverflowFlag,FlagRecComm,SendItComm;
extern unsigned char Count1ms;
unsigned char CommSendBufferHead, CommSendBufferTail;
unsigned char xdata CommSendBuffer[DB_SENDMAXSIZE];
unsigned char CommRecBufferHead, CommRecBufferTail;
unsigned char xdata CommRecBuffer[DB_RECMAXSIZE];
unsigned char RecDataLen=3;
void ClearCommRecBuffer(void)
{
CommRecBufferHead=CommRecBufferTail=0;
FlagRecComm=0;
}
void OpenComm(void)
{
PCON |= 0x80;  // SMOD=1 (HW_UART uses Timer 1 overflow with no divide down).
TMOD = 0x20;  // Configure Timer 1 for use by UART0
CKCON |= 0x10;  // Timer 1 derived from SYSCLK
RCAP2H=(65536-(SYSCLK/BAUDRATE0/32))/256;
RCAP2L=(65536-(SYSCLK/BAUDRATE0/32))%256;
TH2=RCAP2H;TL2=RCAP2L;
CT2=0;    //T2:timer mode
TR2=1;
TCLK=1;RCLK=1;  //说明:52,对于SIO0,可选择T1(TCLK=0,RCLK=0)或T2(TCLK=1,RCLK=1)作为波特率发生器
         //            SIO1只能用T1作为波特率发生器
         //baud=OSC/(32*(65536-[RCAP2H,RCAP2L])
CommSendBufferHead=CommSendBufferTail=0; // set the head and tail to the base of the ring buffer
CommRecBufferHead=CommRecBufferTail=0;
FlagRecComm=0;
RI0=0;     // Clear HW_UART receive and transmit
TI0=0;     // complete indicators.
SCON0 = 0x50;   // Configure UART0 for mode 1, receiver enabled.
ES0=1;      // allow the serial interrupt
SendItComm=1;
}
void SendCommChar(char ch)
{
CommSendBuffer[CommSendBufferTail]=ch;
CommSendBufferTail++;
if (CommSendBufferTail==DB_SENDMAXSIZE)
{  
  CommSendBufferTail=0;
}
if (SendItComm)
{  
  TB80=1;SBUF0=CommSendBuffer[CommSendBufferHead];
}
return ;
}
void SendCommString(unsigned char *base)
{
unsigned char i=0;
if (base[0]==0) return;
for (;;)
{
  if (base==0) break;
  CommSendBuffer[CommSendBufferTail]=base;
  CommSendBufferTail++;
  if (CommSendBufferTail==DB_SENDMAXSIZE)
  {      
   CommSendBufferTail=0;
  }
  i++;
}
if (SendItComm)
{        
  SBUF0=CommSendBuffer[CommSendBufferHead];
}
}
void SendCommBuffer(unsigned char *base, unsigned char size)
{
unsigned char i=0;
if (!size) { return; }
while (i<size)
{  
  CommSendBuffer[CommSendBufferTail]=base;
  i++;
  CommSendBufferTail++;
  if (CommSendBufferTail==DB_SENDMAXSIZE)
  {
   CommSendBufferTail=0;
  }
}
if (SendItComm)
{  
  SBUF0=CommSendBuffer[CommSendBufferHead];
}
}
void CommISR(void) interrupt 4
{
if (_testbit_(TI0))
{
  TI0=0;
  CommSendBufferHead++;  
  if (CommSendBufferHead==DB_SENDMAXSIZE)
  {  
   CommSendBufferHead=0;
  }
  if (CommSendBufferHead!=CommSendBufferTail)
  {  
   SBUF0=CommSendBuffer[CommSendBufferHead]; // send the next byte
   SendItComm=0;
  }
  else
  {
   SendItComm=1;
  }
}
if (_testbit_(RI0))
{  
  RI0=0;
  if (CommRecBufferTail==CommRecBufferHead)
  {
   CommRecDataOverflowFlag=1;    //接收缓冲区溢出
  }
  CommRecBuffer[CommRecBufferTail]=SBUF0;     //receive data           
     CommRecBufferTail++;
     if (CommRecBufferTail==DB_RECMAXSIZE)
     {
      CommRecBufferTail=0;
     }
  FlagRecComm=1;
    }
}
//从接收缓冲区读数据 ,无数据返回0,有数据返回1
bit GetCommChar(unsigned char idata *ch)      
{
if (CommRecBufferTail==CommRecBufferHead) return 0;     
*ch=CommRecBuffer[CommRecBufferHead];
CommRecBufferHead++;
if (CommRecBufferHead==DB_RECMAXSIZE)
{
  CommRecBufferHead=0;
}
if (CommRecBufferTail==CommRecBufferHead) FlagRecComm=0;
return 1;
}
//在T(0-255)毫秒内从接收缓冲区读数据 ,无数据返回0,有数据返回1
bit GetCommCharWait(unsigned char idata *ch,unsigned char T)  //T ms   
{
Count1ms=T;*ch=0;
while (Count1ms)
{
  if (CommRecBufferTail!=CommRecBufferHead) break;
}
if (Count1ms==0) return 0;
*ch=CommRecBuffer[CommRecBufferHead];
CommRecBufferHead++;
if (CommRecBufferHead==DB_RECMAXSIZE)
{
  CommRecBufferHead=0;
}
return 1;
}
返回列表