这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » AVR用定时器模拟串口

共1条 1/1 1 跳转至

AVR用定时器模拟串口

助工
2014-10-05 22:24:43     打赏

void INT_timer0(void)                            
{//Timer0用于模拟串口收发,每139us中断一次
unsigned char i,j,bitStatu;    
//unsigned char SimComOutputTemp;
   TCNT0 = 0x7a;//0x75;// //reload counter value
   PORTA = SimComOutputA;//发送
//    PORTB = SimComOutputB;//发送
   SimComBuf = PINC;//接收
      
   ++SimComTxSampleCycle;
   if(SimComTxSampleCycle>=3)
   {
       SimComTxSampleCycle=0;
   }       
      
//------接受-------------------------
   bitStatu=1;
   for(j=0;j<dTotalChannel;j++)
   {
//------SimCom RX-------
       if(((bSimComTxing & bitStatu) == 0)
       && ((bSimComWaitCheck & bitStatu) == 0))
       {
           if((bSimComRxLoadBit & bitStatu) == 0)
           {//检测开始位
               if((bSimComRxDropEdge & bitStatu) == 0)//未检测到下降缘,继续检测
               {
                   if((SimComBuf & bitStatu) == 0)//采样为底电平
                   {
                       SimComRxBitCount[j]=0;
                       bSimComRxDropEdge |= bitStatu;
                       SimComRxSampleCycle[j]=1;
                       SimComRxBit[j]=0xff;
                   }
               }
               else//已检测到下降缘,检查是否为引导位
               {
                   SimComRxSampleCycle[j]++;
                   if(SimComRxSampleCycle[j]==2)
                   {
                       if((SimComBuf & bitStatu)==0)//采样为底电平
                       {
                           SimComRxBit[j]=0;
                       }
                       else
                       {
                           SimComRxBit[j]=0x80;
                       }
                   }
                   else if(SimComRxSampleCycle[j]>=3)//已采样3个周期--1位采样结束
                   {
                       if(SimComRxBit[j]==0)
                       {
                           bSimComRxLoadBit |= bitStatu;//==‘0’
                       }
                       bSimComRxDropEdge &= ~bitStatu;
                       SimComRxSampleCycle[j]=0;
                       SimComRxBitCount[j]=0;
                   }
               }
           }
           else
           {//数据位和停止位
               //-----采样1位-----
               SimComRxSampleCycle[j]++;
               if(SimComRxSampleCycle[j]==1)
                       SimComRxBit[j]=0xff;
               if(SimComRxSampleCycle[j]==2)
               {
                   if((SimComBuf & bitStatu)==0)//采样为底电平
                       SimComRxBit[j] = 0;
                   else
                       SimComRxBit[j] = 0x80;
               }
               else if(SimComRxSampleCycle[j] >= 3)//每位采样3个周期
               {
                   SimComRxSampleCycle[j] = 0;
               //-----
                   ++SimComRxBitCount[j];
                   if(SimComRxBitCount[j]<=8)
                   {
                       SimComRxSampleBuf[j] >>= 1;
                       SimComRxSampleBuf[j] |= SimComRxBit[j];
                   }
                   else
                   {
                       bSimComRxLoadBit &= ~bitStatu;
                       bSimComRxDropEdge &= ~bitStatu;                
                       if(SimComRxBit[j]==0x80)
                       {//正确的停止位
                           SimComSBuf[j]=SimComRxSampleBuf[j];
                           bSimComByteWaitCheck |= bitStatu;
                       }
                   }
               }
           }    
       }
       bitStatu <<= 1;    
   }
//------发送下一位    ------------------
   if(SimComTxSampleCycle == 0)
   {
       SimComOutputA = 0xff;    
       if(bSimComTxing > 0)
       {
           SimComSendBitCount++;
           if(SimComSendBitCount == 1)//引导位                
           {
               SimComOutputA &= ~bSimComTxing; 
               SimComSendBuf = *ptSimComTxBuf;
           }
           
           else if(SimComSendBitCount < 10)//8个数据位
           {
               i=SimComSendBuf;
               SimComSendBuf >>= 1;
               if((i & 0x01) == 0)
                   SimComOutputA &= ~bSimComTxing;
           }
           else if(SimComSendBitCount == 10)//停止位
           {
               ptSimComTxBuf++;
           }
           else if(SimComSendBitCount >= 11)//休止位
           {
               SimComSendBitCount = 0;
               if(SimComSendByteCount > 0)    
               {
                   SimComSendByteCount--;
               }
               if(SimComSendByteCount == 0)    
               {
                   _EnableSimCom1RX();
                   _EnableSimCom2RX();
                   _EnableSimCom3RX();
                   bSimComTxing = 0;                    
               }
           }
       }
   }    
   //SimComOutputA &=0x0f;
   SEI();
}

 

此程序曾用于模拟8的串口,也用以产品中.稳定性及其高.

模拟串口接收、发送


共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]