只用一个定时中断IO口模拟全双工串口,废话不多直接上代码中断调用收发程序 中断500us执行一次,好用点个赞

#define DATA_OUT RB1
#define DATA_IN  RB2
//发码位数
uchar SendBitNum = 0;
//每位码时间
uchar SendBitDly = 0;
//发码标志位寄存器
uchar SendFlag = 0;
//发码数据寄存器
//uint SendData = 0;
bit SendEn =0;
bit D0=0;
bit DO=0;
bit SendByteOK = 0;
uint SendValue = 0;
//uchar SendDly=0;
//uchar TX[5] ={0xAA,0xAA,0xAA,0xAA,0xAA};
//uchar TX[5] ={0};
//uchar TX[5] ={0x5A,0x5A,0x5A,0x5A,0x5A};
uchar TX[5] ={0x99,0x99,0x999,0x99,0x99};
//uchar TX[5] ={0xff,0xff,0xff,0xff,0xff};
uchar SendId=0;
uchar SendOK=0;
//中断中调用
uchar SendByte(void)
{
  if(SendEn==0)
  {
    //空闲时为1高电平
    DATA_OUT =1;
    return 0;
  } 
  //允许发送时
  if(DO) DATA_OUT =1;
  else   DATA_OUT =0;
  if(--SendBitDly>0) return 0 ;
  SendBitDly=2;
  SendValue>>=1;
  if(SendValue&0x0001) DO = 1 ;
  else                 DO = 0 ;
  if(--SendBitNum >0)  return 0;
  SendEn= 0;
  SendByteOK =1;
  return 0;
}
//循环中调用
uchar SendMSG(void)
{
   //if(SendOK==0) return 0;
   if(SendByteOK==0)  return 0;
   SendByteOK=0;
   //发送一帧数据
   //if(SendId==5)SendId=0;
   //打开发送
   if(SendId<5) 
   {
     SendValue = TX[SendId];
     //设定停止位 =1 设定起始位 = 0
     SendValue |= 0x0100;
     SendValue <<= 1;
     SendBitNum = 10 ;
     SendBitDly = 2 ;
     SendEn=1;
     SendId++;
     return 0;
   }
   SendId = 0;
   SendOK=0;
   return 0;
}
uchar SendTrig(void)
{
   SendId=0;
   //SendByteOK=0;
   SendByteOK =1;
   return 0;
}
//
bit DQ=0;
uint  R_Byte=0;
uchar RHighDly=0;
uchar ChkBitDly=0;
uchar ChkBitNum= 9;
uchar MyRead=0;
uchar RLowDly=0;
uchar Rcnt = 0;
//uchar DQH = 0;
uchar RLow = 0;
uchar ReadByte(void)
{
 //接收到高电平
 if(DATA_IN)
 {
  DQ=1;
  Rcnt++;
  RHighDly++;
  RLowDly=0;
  if(Rcnt>16)
  {
     Rcnt =16;
     RLow = 0;
     RHighDly=1;
     return 0;
  }
 }
 else
 {
   RLow++;
   RLowDly++;
   //判断
   if(DQ&&(RLow==1)) 
   {
     Rcnt=0;
     ChkBitDly=1;
     R_Byte =0;     //设定8位数据
     RLowDly=2;
     ChkBitNum=9;
     return 0;
   }
   DQ=0;
 }
 //需要校测2次
 if(--ChkBitDly!=0)    return 0;
 ChkBitDly=0;//清零位计数器
 //改变数据
 if(RHighDly>RLowDly) R_Byte |=0x100;
  //if(DQ)R_Byte |=0x100;
  R_Byte >>=1;  //右移动1位
  RHighDly=0;
  RLowDly=0;
  ChkBitDly =2;
  if(--ChkBitNum!=0)return 0;
  //接收完一个字节数据
  ChkBitNum=9;
  Rcnt=0;
  RLow =0;
  //读取数值
  MyRead=(R_Byte&0x00ff);
  return 0;
}
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章