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

📄 receivetest.c~

📁 关于rs485通信及iic通信的程序
💻 C~
📖 第 1 页 / 共 4 页
字号:
             RS485_Answer=1;
            }
            
            else
            {   
               RS485_Answer_Set();
               RS485_Answer_Subprogram();            // 调用发送点对点回复包子程序 
               led2=!led2;
               Check_Receive_Data_Flag=1;
            }
         }
         else if( (Address_Flag==RS485_Address_Broad)||( Address_Flag==( RS485_Address_Self & 0xF0)))
         {           
             // 广播类型数据包回复标志
             RS485_Answer_Set();
             // 发送回复包标志清0
             RS485_Answer_Broad_Subprogram();               // 调用发送点对广播回复包子程序              
            //RS485_Answer_Subprogram();    
            led2=!led2;
            Check_Receive_Data_Flag=1;
         }                                                                                
            
      }
      
  }
  
}


    

//----------------------------------------------------------------------------------------------  
//
//串行接收处理函数
void RS485_Receive_Process(INT8U RecData)
{
 
  Receive_Status=GetCurrentRS485RxStatus();
  
  switch(Receive_Status)
  {
    case RS485_Receive_IDLE:
     
      if(RecData==Data_Head)                                // 在空闲状态下接收到数据,判断是否数据包起始字节
      {        
        SetCurrentRS485RxStatus(RS485_Receive_RECEIVE);     // RS485总线状态改为接收状态              
        Receive_Count=0;                                    // 接收计数器清0
  //      Receive_CheckHead=0;                                // 准备进行对接收到的数据头进行和校验,简单累加和
   //     Receive_CheckData=0;                                // 准备进行对接收到的数据进行和校验,简单累加和
        RS485_Bus_Status = RS485_Bus_BUSY;                  // 接收到0x7E时总线状态为忙,不能发送数据   
      }
      break;
   
   case  RS485_Receive_RECEIVE:
      if(RecData==Data_Change)
      {
     
         SetCurrentRS485RxStatus(RS485_Receive_CHANGE);     // RS485总线状态改为转移状态                
         break;
      }  
      if(RecData==Data_Head)
      {
         if(Receive_Count>0)                                // 当接收到0x7E且接收计数器大于0,接收结束
         {          
            RS485_Data_Handle();                      // 调用数据处理程序     
            SetCurrentRS485RxStatus(RS485_Receive_IDLE);       // 将485接收状态改为空闲状态
            RS485_Bus_Status=RS485_Bus_IDLE;  
            //RS485_Receive_Save_Data();  
            RS485_Receive_End=1;
           // RS485_Receive_Save_Data();          
            Receive_Count=0;                                   // 接收完毕,将接收数据计数器清0
         } 
//          else
//          {
//             SetCurrentRS485RxStatus(RS485_Receive_IDLE);       // 将485接收状态改为空闲状态      
//             RS485_Bus_Status=RS485_Bus_IDLE;                   // 接收完毕(无论正确与否,无论数据还是回复包)485总线状态设置为空闲状态, 
//          }
         break;  
      
      }
      
      RS485_Receive_Buff[Receive_Count]= RecData; 
//       if(Receive_Count<7)
//       {
//          Receive_CheckHead += RS485_Receive_Buff[Receive_Count];       // 更新累加数据头和校验信息
//       }
//       
//       else if(Receive_Count>7)
//       {
//          Receive_CheckData += RS485_Receive_Buff[Receive_Count];       // 更新累加数据和校验信息
//       }                                                                      
      Receive_Count++;                                                 // 接收计数器加1
      break;  
     
   case  RS485_Receive_CHANGE:       
      
      RS485_Receive_Buff[Receive_Count]= RecData^0x20;
//       if(Receive_Count<7)
//       {
//         Receive_CheckHead += RS485_Receive_Buff[Receive_Count];       // 更新累加数据头和校验信息
//       }
//       else if(Receive_Count>7)
//       {
//         Receive_CheckData += RS485_Receive_Buff[Receive_Count];       // 更新累加数据和校验信息
//       }
     
      SetCurrentRS485RxStatus(RS485_Receive_RECEIVE);                 // 转换之后将485改为接收状态,接收下一字节数据
      Receive_Count++;                                                //  接收计数器加1
      break; 
   
   default:
     break;       
  }

}
 


//----------------------------------------------------------------------------------------------   
//
//接收中断程序
interrupt [USART_RXC] void usart_rx_isr(void)
{
//  INT8U  Receive_Data;
  led=!led;
  
  Receive_Data=UDR;
  RS485_Receive_Process(Receive_Data);
}


//----------------------------------------------------------------------------------------------
//
// 定时器0中断程序
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{  
  switch(Delay_Status)
   { 
     case  Start_Send:
     {
        Delay_Status=Other_Delay;                    // 中断延时结束,返回其他状态
        RS485_Start_Send();     
     }
     break;
      

    case  Repeat_Send_Delay:                                // 重发延时10ms,1ms中断一次  
    if(Repeat_Send_Time>0)                           // 延时尚未结束   
    {  

         
               if(RS485_Bus_Status == RS485_Bus_BUSY)       // 检测到总线为不空闲, 
               {
                  if(Add_Time_Flag==1)                      // 首次不空闲时将加3ms延时
                  {
                     Repeat_Send_Time=Repeat_Send_Time+3;
                     Add_Time_Flag=0;            
                  }  
                  break;
               }  
               else                                         // 总线状态为空闲时,将延时计数器减1 
               {
                  Repeat_Send_Time=Repeat_Send_Time-1;
                  Add_Time_Flag=1;
               }
               break;                                
    }      
    else                                             // 延时结束,    
    {
        if(RS485_Bus_Status == RS485_Bus_BUSY)       // 延时结束,发送前检测到总线不为空闲,重新执行延时程序
        {
                     Repeat_Delay_Program();                // 调用重发延时函数,继续执行重发延时

                     break;      
        }                                          
        else                                         // 总线为空闲,即开始发送数据
        {  
   
                  ReSendCount++;                            // 重发计数器加1       
                  Delay_Status=Start_Send;

               }
           }        
           break;  
          
  
  case Long_Wait_Delay:                                  // 重发之间的超时等待延时350ms,50ms中断一次        
  if(Long_Wait_Time>0)
  {
 
    Long_Wait_Time=Long_Wait_Time-1; 

    break;
 }
 else
 { 
    Delay_Status=Repeat_Send_Delay;

 }  
  break;
  
  
  case Send_Broad_Delay:                                 // 对广播包竞争回复延时,1ms中断一次
   
          if(Com_Revert_Time>0)                             // 延时未结束 
          {
               if(RS485_Bus_Status == RS485_Bus_BUSY)       // 检测到总线为不空闲, 
               {
                  if(Add_Time_Flag==1)                      // 首次不空闲时将加3ms延时
                  {
                      Com_Revert_Time=Com_Revert_Time+3;   
                       Add_Time_Flag=0;

                  }  
                  break;
               }
               else                                         // 检测到总线为空闲 
               {                                            
                  Add_Time_Flag=1;
                  if(RS485_Answer==0)                       // 还没有收到回复包,计数器将减1
                  {
                      Com_Revert_Time=Com_Revert_Time-1;                      
                      break;      
                  }
                  else                                      // 已经收到回复包,放弃对广播包的回复
                  {
                      Delay_Status=Other_Delay;             // 中断延时结束,返回其他状态                     
                      break;
                  }
                                 
               }          
          }
       
          else                                              // 表示竞争回复延时结束
          {
               if(RS485_Bus_Status == RS485_Bus_BUSY)       // 延时结束,发送前检测到总线不为空闲,重新执行延时程序
               {
                  Com_Revert_Time=Delay_Time_Count[ RS485_Answer_Send_Buff[0]];    // 竞争回复延时间计数长度                
               }                                          
               else                                         // 总线为空闲,即开始发送数据
               {  
                   Delay_Status=Start_Send;                 // 中断延时结束,返回其他状态        
                   led3=0;
               }  
          }
          break;
  
  case Check_Delay:                                      // 检测是否接收到回复包延时200ms,50ms中断一次
      
          if(Check_Time>0)                                  // 200ms延时未结束,继续延时
          {

               Check_Time=Check_Time-1;
               break;   
          }
          else                                              // 200ms延时结束
          {                   
              Send_Data_Flag=0;
               Delay_Status=Other_Delay;                    // 中断延时结束,返回其他状态
               if(RS485_Answer==0)                          // 定时中断50ms后如果没有回复包标志,将重发数据
               {
                   if(ReSendCount<2)                        // 重发数据小于2次时;
                   {
                      RS485_Send_Flag=1;                    // 启动发送标志位
                      ReSendFlag=1;                         // 启动重发标志
                      break;
                   }
                   else                                     // 重发超过两次;  
                   {
                      ReSendCount=0;                        // 重发次数计数器清0
                   }    
               }
               else
               {
                 // RS485_Answer=0;                          // 接收到回复包,将重发计数器清0
                  ReSendCount=0;                        // 重发次数计数器清0
               }
          }     
          break;                
     
     default :
//          TCCR0=0x00;                                        // 关闭定时中断
          break; 
    
    }
}
  
      
 
//----------------------------------------------------------------------------------------------
//
// 2 Wire bus interrupt service routine
interrupt [TWI] void twi_isr(void)
{
// Place your code here
    INT8U   IICStatus;    
    IICStatus = TWSR;
    IICStatus &= 0xF8;
    switch(IICStatus)
    {   
         //从机接收
        case  0x60:                   // 接收到自身SLA+W,返回ACK,并清除INT位           
        case  0x68:                   //自己作为主机的时候仲裁失败,并收到自身的SLA+W,返回ACK了。这种情况不会出现            
            IICSendCount=0;
            IICChecksum=0;
            TWCR |= 0xC0;
            break;        
        //从机发送    
         case  0xA8:                  
         case  0xB0:
         case  0xB8:     
            

⌨️ 快捷键说明

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