只用一個定時中斷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;
}
 

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