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

📄 receivetest.c

📁 关于rs485通信及iic通信的程序
💻 C
📖 第 1 页 / 共 4 页
字号:
#include <mega8.h>        
#include <delay.h>    
#include <string.h>    

#define led PORTD.5
#define led1 PORTD.6
#define led2 PORTD.7
#define led3 PORTB.0


#define RXB8 1
#define TXB8 0
#define UPE 2
#define OVR 3
#define FE 4
#define UDRE 5
#define RXC 7

#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<OVR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)

#define DRE PORTD.2   
#define DB_SENDMAXSIZE 7     


#define Send_Buff_Size 128 
#define Receive_Buff_Size  128
#define FunctionCode  2
#define Data_Head   0x7E
#define Data_Change 0x7D      


//定义RS485总线状态,当状态为0时才允许发送数据
#define RS485_Bus_IDLE 0
#define RS485_Bus_BUSY 1  

#define RS485_Receive_IDLE 0
#define RS485_Receive_RECEIVE 1
#define RS485_Receive_CHANGE 3

#define Answer_Size 8                            // 定义回复包数据长度为八个字节

#define RS485_Address_Self  0x21                 // 本机自己的地址 
#define RS485_Address_Broad 0x00                 // 广播地址

// #define Address_Broad 0x00                       // 接收到的为广播地址时回复0
// #define Address_Self  0x01                       // 接收到的为本机自己的地址时回复1
// #define Address_Rong  0x02                       // 接收到不为本机地址也不为广播地址时回复2

#define Repeat_Send_Count 0x0A                   // 重发延时机制的延时时间,定为10ms
#define Check_Count       0xC8                   // 检测回复包延时计数器,一次为50ms,延时200ms计数4次
#define Long_Wait_Count   0xF0                   // 超时等待计数器,一次为1ms,延时250MS计数250次

#define Repeat_Send_Delay 0x01                   // 重发延时状态
#define Long_Wait_Delay   0x02                   // 超时等待状态
#define Send_Broad_Delay  0x03                   // 回复广播包延时状态
#define Check_Delay       0x04                   // 检测回复包延时状态
#define Other_Delay       0x00                   // 其他中断延时状态
#define Start_Send        0x66   

#define Order_Attribute 16


typedef unsigned char  INT8U;
typedef char           INT8S;
typedef unsigned short INT16U;

// This flag is set on USART Receiver buffer overflow

//定义RS485总线接收状态
INT8U   RS485_Receive_Status;

INT8U   ReSendFlag;                              // 重发数据标志位
INT8U   ReSendCount;                             // 重发数据计数器
INT8U   *P_RS485_Send_Buff;                      // 定义发送缓冲区指针
INT8U   RS485_Send_Buff[Send_Buff_Size]={0x00,0x21,0x10,0x00,0x00,0x02,0x00,0x44};         // 定义待发送数据缓冲区
INT8U   RS485_Receive_Buff[Receive_Buff_Size];   // 定义接收数据缓冲区
INT8U   RS485_Receive_Save[128];                 // 保存接收到的数据缓冲区
INT8U   RS485_Answer_Buff[8];                    // 回复包接收缓冲区,回复包只为8个字节
INT8U   RS485_Answer_Send_Buff[8];               // 回复数据包的发送缓冲区  

INT8U   Tx_Count;                                // 定义发送数据计数器
INT8U   Receive_Count;                           // 定义接收数据计数器
INT8U   Answer_Data_Count;                       // 回复包接收计数器
INT8U   Tx_Send_End;                             // 发送完一帧数据标志位

INT8U   Send_Broad_Delay_Flag;                   // 发送广播回复包延时标志
INT8U   Repeat_Send_Data_Flag;                   // 重发第二次数据包标志
INT8U   Send_Data_Flag;                          // 发送数据包(包括首发和重发标志),通过此标志去检验是否有回复包
INT8U   RS485_Send_Flag;                         // 发送标志位
INT8U   Send_Answer_Flag;                        // 发送回复包标志
INT8U   Send_Broad_Flag;                         // 发送广播回复包标志
INT8U   Add_Time_Flag;                           // 重发延时首次检测到总线不空间,对延时加3ms标志
INT8U   RS485_Answer;                            // 回复包标志位

INT8U   Send_Size;                               // 待发送数据的长度
INT8U   Byte_Len;                                // 接收字节的长度,8;40;128;0

INT8U  Receive_Data;                             // 接收的一个字节的数据
INT8U  Receive_Status;                            // 接收数据时的状态

INT8U   Receive_CheckHead;                       // 数据包头接收和校验
INT8U   Receive_CheckData;                       // 数据包数据接收和校验  
INT8U   Send_CheckHead;                          // 数据包头发送和校验
INT8U   Send_CheckData;                          // 数据包数据发送和校验  

INT8U   RS485_Bus_Status;                        // 定义485总线状态                  
INT8U   Send_Status;                             // 发送数据状态
INT8U   Delay_Status;                            // 延时中断状态

INT8U   Start_Delay;                             // 启动延时检测回复包程序

INT8U   Repeat_Send_Time;                        // 重发延时剩余时间计数器
INT8U   Long_Wait_Time;                          // 超时等待剩余时间计数器
INT8U   Com_Revert_Time;                         // 竞争回复延时剩余时间计算器
INT8U   Check_Time;                              // 检测回复包延时剩余时间计算器

INT8U   Long_Time_End;                           // 超时等待结束标志

INT8U   UpdateFlag;                              // 状态更新标志
INT8U   IICSendCount;                            // IIC发送计数器,一次通信接收8个字节
INT8U   IICReceiveCount;                         // IIC接收计数器,一次通信接收8个字节
INT8U   IICReceiveBuff[8]={0x01,0x01,0x02,0x01,0x02,0x03,0x04,0x0e};                       // IIC接收缓冲区     
INT8U   IICSendBuff[8];                          // IIC发送缓冲区
INT8U   IICChecksum;                             // IIC接收校验和
INT8U   IICCSendDataheck;                        // IIC发送数据的校验和
        
INT8U   Check_Receive_Data_Flag;

INT8U   RS485_Receive_End;                     // 485总线接收结束标志
// INT8U  Buff;
// INT8U  Length;
// INT8U  Address;  

// 竞争回复延时计数器,没计数一次延时1ms
INT8U   Delay_Time_Count[]={
 0, 0,  0,  0,   0,   0,   0,   0,   0,  0,   0,   0,   0,   0,0,0,
 0, 2,  4,  6,   64,  102, 98,  155, 0,  0,   0,   0,   0,   0,0,0,
 0, 8,  36, 60,  66,  104, 140, 142, 166,168, 170, 172, 174, 0,0,0,
 0, 10, 38, 62,  68,  84,  85,  86,  0,  0,   0,   0,   0,   0,0,0,
 0, 12, 44, 100, 139, 0,   0,   0,   0,  0,   0,   0,   0,   0,0,0,
 0, 14, 46, 98,  0,   0,   0,   0,   0,  0,   0,   0,   0,   0,0,0,
 0, 16, 96, 136, 0,   0,   0,   0,   0,  0,   0,   0,   0,   0,0,0,
 0, 18, 94, 137, 0,   0,   0,   0,   0,  0,   0,   0,   0,   0,0,0,
 0, 20, 92, 138, 0,   0,   0,   0,   0,  0,   0,   0,   0,   0,0,0,
 0, 22, 40, 42,  70,  88,  90,  106, 156,158, 160, 162, 164, 0,0,0, 
 0, 24, 48, 72,  112, 124, 144, 143, 186,0,   0,   0,   0,   0,0,0,
 0, 26, 50, 74,  114, 126, 146, 176, 188,0,   0,   0,   0,   0,0,0,
 0, 28, 52, 76,  116, 128, 148, 178, 190,0,   0,   0,   0,   0,0,0,
 0, 30, 54, 78,  118, 130, 150, 180, 191,0,   0,   0,   0,   0,0,0,
 0, 32, 56, 80,  120, 132, 152, 182, 0,  0,   0,   0,   0,   0,0,0, 
 0, 34, 58, 82,  122, 134, 154, 184, 0,  0,   0,   0,   0,   0,0,0}; 
      



//---------------------------------------------------------------------------------------
//
//获取当前485接收状态
INT8U GetCurrentRS485RxStatus(void)
{
  return   RS485_Receive_Status;
}

 

//---------------------------------------------------------------------------------------
//
//设置当前485总线接收状态
void SetCurrentRS485RxStatus(INT8U status)
{
  RS485_Receive_Status=status;
}   




//----------------------------------------------------------------------------------------------
//
//启动发送程序
void RS485_Start_Send(void)               
{
    while (!(UCSRA&(1<<UDRE)));                        // 当数据寄存器为空时
    DRE=1;                                             // 将485转换到发送状态
    UDR=0x7E;                                          // 发送一帧的数据的开头0x7E     
}


//---------------------------------------------------------------------------------------
//
// 重发延时函数
void Repeat_Delay_Program(void)
{
 //Long_Time_End=0;
 Repeat_Send_Time=Repeat_Send_Count;            // 延时10ms
 Delay_Status=Repeat_Send_Delay;                // 进入重发延时中断状态
//  //开中断,启动发送延时机制                            
//  TCNT0=0xFC;                                    // 定时1ms  
//  TCCR0=0x05;                                    // 1024分频,计数39.0625次就为10ms                                           
}



//---------------------------------------------------------------------------------------
//
//发送数据,包括首发和重发  执行这程序之前需将485引脚定义为发送状态
void RS485_Send_Subprogram(void)
{ 
   if(ReSendFlag==1)                                        // 判断是否为重发数据
   {  
        ReSendFlag=0;                                       // 重发标志清0
        //将数据第二字节功能代码的第七位置位,表示为重发数据
      
        RS485_Send_Buff[7]= RS485_Send_Buff[7] - RS485_Send_Buff[FunctionCode];
        RS485_Send_Buff[FunctionCode]=RS485_Send_Buff[FunctionCode]|0x40;  
        RS485_Send_Buff[7]= RS485_Send_Buff[7] + RS485_Send_Buff[FunctionCode];
        
               
        if(ReSendCount==1)                                  // 第一次同第二次重发之间的超时等待
        {                                        
           Long_Wait_Time=Long_Wait_Count;
           Delay_Status=Long_Wait_Delay;                    // 进入超时等待延时中断状态
           
//            Repeat_Send_Data_Flag=1;
           
//            //启动定时器T00                                    // 超时等待350ms                    
//            TCNT0=0x3D;                                      // 定时50ms      
//            TCCR0=0x05;  
                                                            // 超时等待未结束,执行其他程序
                                                            // 超时等待350ms结束,再执行重发延时
//            while(Repeat_Send_Data_Flag==1)
//            { 
//               if(Long_Time_End==0)
//               {
//                 // Place your code here
//               }
//               else                                             // 超时等待350ms结束,再执行重发延时
//               {                 
//                 Long_Time_End=0;
//                 Repeat_Send_Data_Flag=0;
//                 Repeat_Delay_Program();           
//               }                                                                          
//            }                                                
        }
        else                                                
        {             
           Repeat_Delay_Program();
        }
   
   }                                                        // 首发数据不用延时,直接发送
   else
   {      
        ///
        Delay_Status=Start_Send;
        ///
       // RS485_Start_Send();                                 // 启动发送,即将0x7E发送到数据寄存器
   }                             
}                                 



//----------------------------------------------------------------------------------------------
//
// 发送点对点回复包子程序
void RS485_Answer_Subprogram(void)
{  
  Send_Size=8;                                         // 发送回复包数据,固定为8个字节
  P_RS485_Send_Buff=RS485_Answer_Send_Buff;            // 将指针P_RS485_Send_Buff指向发送缓冲区RS485_Answer_Send_Buff首地址
  
  Delay_Status=Start_Send;
  //RS485_Start_Send();                                  // 启动发送
}


//----------------------------------------------------------------------------------------------
//
// 发送点对类,广播回复包子程序
void RS485_Answer_Broad_Subprogram(void)
{
 Send_Size=8;                                                      // 发送回复包数据,固定为8个字节
 P_RS485_Send_Buff=RS485_Answer_Send_Buff;                         // 将指针P_RS485_Send_Buff指向发送缓冲区RS485_Answer_Send_Buff首地址
 Com_Revert_Time=Delay_Time_Count[RS485_Answer_Send_Buff[0]];
 Delay_Status=Send_Broad_Delay;                                    // 进入发送广播回复包延时中断状态
//  Send_Broad_Delay_Flag=1;
//  // 开定时中断
//  TCNT0=0xFC;                                                       // 定时1ms      
//  TCCR0=0x05;                                                       // 1024分频,约计数4次为1ms     
//  while(Send_Broad_Delay_Flag==1)
//  {
//   ;// Place your code here
//   
//   //led3=!led3;
// 
//  }  
//  led3=0;
//  
//  Delay_Status=Start_Send;
//  //RS485_Start_Send();                                               // 启动发送
}


//----------------------------------------------------------------------------------------------
//发送中断程序
interrupt [USART_TXC] void usart_tx_isr(void)
{ 
  led3=!led3;
  if(Tx_Send_End==0)                                         // 一帧数据尚未发完
  { 
    

⌨️ 快捷键说明

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