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

📄 communication.c

📁 430做的一种门控系统的程序
💻 C
字号:
//20070407在此基础上进行调试
/*************************************旋转部分管理CPU********************************/
#include "communication.h"

//#define   
/*******************************************************************************
*********************************全局变量**************************************
*******************************************************************************/
UINT8 Wait_Flag = 0;                                           //等待标志
UINT8 Right_Send_Flag = 0;                                    //正确发送了一帧数据
UINT8 Send_Time_Flag = 0;                                     //发送次数标志位
UINT8 Error_Flag = 0;                                         //错误标志
UINT8 Receive_flag = 0;                                //1:接收数据;0:没有接收到数据
UINT8 Encrypt[13] = {0,0,0,0,0,0,0,};                         //用来存放一个数据帧
UINT8 R_Encrypt[13] = {0,0,0,0,0,0,0};                        //
UINT8 Lead[Lead_length] = {0xf0,0xf0,0xf0,0xf0,0xf0};          //引导码
UINT8 Parameter[8] = {0x10,0x80,0x33,0x44};                            //参数区
UINT8 order1 = 0;                                              //命令1
UINT8 order2 = 0;                                            //命令2 

/**********************************************
**函数功能:把要发送的数据编制成数据帧的格式
**入口参数:UINT8 addr命令的目的地址 UINT8 order1 要发送的命令1,UINT8 order2,命令2(参数的字节数)UINT8 ×Par:参数的内容
**出口参数:无
**调用模块:无
**备    注:修改了数组Encrypt[]的内容;
**********************************************/
void Encrypt_Rotary(UINT8 flag,UINT8 addr,UINT8 order1,UINT8 order2,UINT8 *par)
{ 
  UINT8 k=0;
  if(flag == 1)//回答头还是命令头 为1是命令头 0是回答头
  {
      Encrypt[0] = COMMAND;
  }
  else
  {
      Encrypt[0] = REPLY_TO;
  }
  Encrypt[1] = ADDR_ROTARYCON; 
  Encrypt[2] = addr;
  Encrypt[3] = order1;
  Encrypt[4] = order2;
  for(k = 1;k <= order2; k++)
  {
      Encrypt[4+k] = *par;
      par++;      
  }
   Encrypt[order2+5] = BCC_checkout(Encrypt,Encrypt[4]+6);
}
/*************************************************
**函数功能:把数据帧发送到总线上,并实现超时重传功能
**入口参数:UINT8 flag UINT8 Destination_Addr UINT8 Ord1,Ord2,*Par
**出口参数:无
**调用模块:底层的串口发送程序
**备    注:在发送有效数据之前先发送至少四个字节的引导码
**************************************************/
void Send_Rotary(UINT8 flag,UINT8 Destination_Addr,UINT8 Ord1,UINT8 Ord2,UINT8 *Par)//把数据帧发送到总线上
{
//调用一个串口发送程序,把全局变量(数组Encrpyt[])发送到总线上
    Encrypt_Rotary(flag,Destination_Addr,Ord1,Ord2,Par);
    SendUart(COM2,Lead,Lead_length);   //在发送数据帧之前先发送引导码;引导码长度由Lead_length确定
    SendUart(COM2,Encrypt,Encrypt[4]+6);//发送的数据帧长度由发送数组的第四个元素的值即order2的值加上固有部分(计6个字节)确定
}
/*************************************************
**函数功能:接收总线上的数据帧并将其存放到临时数组R_Encrypt[]中
**入口参数:无
**出口参数:无
**调用模块:USART.C中的全局变量g_aRecvBuf[];
**************************************************/
void Receive_Rotary(void)//接收总线上的数据帧
{  
    UINT8 i = 0;
    UINT8 n = 0;
   
    Stop_COM(COM2,UsartRXD);//关串口中断,
    for(i = 0 ;i <= g_aRecvBuf[4]+6 ;i++)//for(i = 0;i < 7;i++)
    {
        R_Encrypt[i] = g_aRecvBuf[i];
    }
    for(n = 0 ;n <= g_aRecvBuf[4]+6 ;n++)//for(n = 0;n < 7;n++)
    {
        g_aRecvBuf[n] = 0;
    }
    Verify_Rotary();
    Start_COM(COM2,UsartRXD);//开串口中断
   /*****************************原来的全局数组有64个字节修改后有7个字节***********************/
}
/*************************************************
**函数功能:对给的数组进行BCC校验
**入口参数:UINT *SBCC,UINT8 S_Length
**出口参数:BCC_String
**调用模块:无
**************************************************/
UINT8 BCC_checkout(UINT8 *SBCC, UINT8 S_Length)
{
    UINT8 BCC_string = 0;
    UINT8 m = 0;
    SBCC++;
    S_Length--;
    for(m = 1 ;m < S_Length ;m++)
    {
        BCC_string ^= *SBCC;
        SBCC++;
    }
    return BCC_string;
}
/*************************************************
**函数功能:校验接收到的数据的BCC码,如果BCC码正确则验证接收到的数据
            帧的目的地址是不是本地地址,如果是则说明收到的是一帧正确的数据
            无论是BCC码还是地址校验错误都将丢弃接收到的数据帧。
            注意此函数可以修改数组Encrpyt[7]的值。
**入口参数:无
**出口参数:无
**调用模块:无
**************************************************/
void Verify_Rotary(void)
{   
    UINT8 temp,i,x,temp1;
    temp = R_Encrypt[R_Encrypt[4]+5];//temp = R_Encrypt[6];
    temp1 = BCC_checkout(R_Encrypt,R_Encrypt[4]+6);
    if(temp == temp1)
    {
        if(R_Encrypt[2] == ADDR_ROTARYCON)// 验证接收到的数据帧中的目的地址是否是本机地址
        {
             for(i = 0;i < R_Encrypt[4]+6;i++)
             {
                  Encrypt[i] = R_Encrypt[i];//验证通过后,把临时数组的值给接收数组
                  Receive_flag = 1;//接收标志位置1
             }
                
         }
         else
         {
            for(x = 0;x < R_Encrypt[4]+6;x++)
            {
                R_Encrypt[x] = 0;//清空临时数组
            }
            Receive_flag = 0;//接收标志清零
         }
    }
    else
    {
        Receive_flag = 0;//接收标志清零
    }
    
}
/*************************************************
**函数功能:处理经过BCC校验和地址校验的数据帧,根据数据帧的第一个字节来判断是命令还是回复,
           如果是回复则把发送成功标志位Right_Send_Flag置位,如果是命令则提取命令并且给发送端
           回复信息
**入口参数:
**出口参数:
**调用模块:Send_Rotary()
**************************************************/
void Decipher_Rotary(void)//把接收到的帧中的命令提取出来
{ 
  UINT8 temp = 0,j = 0;
  UINT8 Read_Length = 0; 
  UINT8 r;
  UINT8 temp_BUF[8]; 
  UINT16 adr_temp;
  temp = Encrypt[0];
  if(temp == REPLY_TO)//如果收到的是回答帧则说明对方成功的收到了命令
  {
      Right_Send_Flag = 1;//成功的发送了一帧数据     
  }
  if(temp == COMMAND)//如果收到的是命令帧,则提取命令并做出答复
  {
      order1 = Encrypt[3];//取出数组中的第4个字节中的数据存放到order1中
      order2 = Encrypt[4];//数组的第5个字节为命令2,其作用是用来规定参数Parameter的字节数
      for(j = 1;j <= order2; j++)
      {
          Parameter[j-1] = Encrypt[4+j];//把数据接收到的数据帧的第6个字节起的数据给参数数组
      }
      Send_Rotary(REPLY_TO_HEAD,ADDR_FIXED,order1,order2,Parameter);
      switch(order1)
      {
          case WRITE_FLASH:
              {   
                  adr_temp = Parameter[0];
                  adr_temp = adr_temp << 8;
                  adr_temp |= Parameter[1];//参数数组的前两个字节的内容分别为地址的高8位和低8位 
                  FlashModify_N_Byte_WriteSeg( adr_temp, Parameter+2,order2);
              };break;
          case READ_FLASH:
              {   
                   adr_temp = Parameter[0];
                   adr_temp = adr_temp << 8;
                   adr_temp |= Parameter[1];//参数数组的前两个字节的内容分别为地址的高8位和低8位
                   Read_Length = Parameter[2];
                   for(r = 0 ; r < Read_Length; r++)
                   {
                   temp_BUF[r] = FlashReadByte(adr_temp+r);
                   }
 //f0 f0 f0 f0 f0 f0 f0 f0 AA 04 14 15 04 10 82 44 55 82    //写
//f0 f0 f0 f0 f0 f0 f0 f0 AA 04 14 16 03 10 80 01 94    //读一个字节
//f0 f0 f0 f0 f0 f0 f0 f0 AA 04 14 16 03 10 80 04 91  //Read 4个字节                  
          Send_Rotary(REPLY_TO_HEAD,ADDR_FIXED,order1,Read_Length,temp_BUF);
              };break;
          default:break;
      }    
  }
 }

/*************************************************
**函数功能:命令解释程序,根据命令完成规定好的动作
**入口参数:
**出口参数:
**调用模块:
**************************************************/
/*void Unpuzzle_Rotary()
{
    switch(order1)
    {
        case READ_FLASH:
     
   ...
  }
}*/
/***************************************************
****************此主函数仅供测试用*******************
****************************************************/

void main(void)
{   InitSys();
    Open_All_Int();//打开全局中断
    InitCom(COM2,BPS9600);//串口初始化
    RS485_Set(ConstManageIC, RS485_REC);//485设置 为接收
    Send_Rotary(COMMAND_HEAD,ADDR_FIXED,0x15,0x04,Parameter);
     while(1)
     {   
         if(COM2_R_flag)
         {
             Receive_Rotary();//接受收到的数据
             if(Receive_flag)
             {
                 Decipher_Rotary();                
             }
             COM2_R_flag = 0;
          }
    }
}

⌨️ 快捷键说明

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