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

📄 dsa.c

📁 这是一个成熟的DSA通讯持续,可以在单片机之间通讯用.
💻 C
字号:
/*C**************************************************************************
* NAME:         dsa_com.c
*----------------------------------------------------------------------------
* PURPOSE:
* This is the  software for A2368+DSA
*****************************************************************************/
#include<at89x52.h>
#include"dsa.h"
#include"typedefine.h"
#include"delay.h"

uchar Send_ok;
uchar Read_ok;
uchar dsa_com;
uchar dsa_data1;
uchar dsa_data2;
uchar Time_out;

/*F**************************************************************************
* NAME:    dsa_init
*----------------------------------------------------------------------------
* PURPOSE: 
*  init
*****************************************************************************/
void dsa_init()
 {
  Stb=1; 
  S_data=1;
  Ack=1; 
  }
/*F**************************************************************************
* NAME: Wr_data
*----------------------------------------------------------------------------
* PURPOSE: 
*   send word data to servo routine 
*****************************************************************************/
void Wr_data(int w_data, uchar w_ldat)   //写字节
  {
   uchar i;
   int j;
   Time_out=0;
   dsa_init();
   for(i=0;i<16;i++)
    {      
     if(w_data & 0x8000)   //!!!16位,不能用0x80
     S_data=1;
     else S_data=0;     
     w_data<<=1;
     Stb=0;
     for(j=0;j <= 300;j++)   //如果应答不为零,未读数
        {  
          if(Ack==0) break;  
          if(j==300)
            {
             Time_out=1;
             return;    //超时退出
            }
        }
     Stb=1;			
     for(j=0;j <= 300;j++)   //如果应答不为1,读数未完成
        {  
          if(Ack==1) break;  
          if(j==300) 
           {
             Time_out=1;
             return;    //超时退出
            }
        }
     
     }

	 for(i=0;i<8;i++)
	 {
     if(w_ldat & 0x80)   //
     S_data=1;
     else S_data=0;     
     w_ldat<<=1;
     Stb=0;
     for(j=0;j <= 300;j++)   //如果应答不为零,未读数
        {  
          if(Ack==0) break;  
          if(j==300)
            {
             Time_out=1;
             return;    //超时退出
            }
        }
     Stb=1;			
     for(j=0;j <= 300;j++)   //如果应答不为1,读数未完成
        {  
          if(Ack==1) break;  
          if(j==300) 
           {
             Time_out=1;
             return;    //超时退出
            }
        }
     
     }	 	 
	 
  }
/*F**************************************************************************
* NAME: Wr_command
*----------------------------------------------------------------------------
* PURPOSE: 
*   write command routine 
*****************************************************************************/

void Wr_command(uchar wdsa_c,uchar wdsa_d,uchar wdsa_l)  //写命令
  { 
    int j;  
    uchar i;
    Send_ok=0;
    for(i=0 ; i<2 ; i++)   //发2次
     {
      Time_out=0;
      dsa_init();
      S_data=0;
      if(Send_ok==0)
        {
         for(j=0;j <=8000;j++)   //如果应答不为0,未握手
          {  
           if(Ack==0) break;   //如果应答0,握手OK
           if(j==8000)return;  //超时退出
          }
         S_data=1;
         for(j=0;j <= 300;j++)   //如果应答不为1,握手未完成
          {  
           if(Ack==1) break;  //如果应答1,握手完成
           if(j==300)return;
          }
      Wr_data(( (uint)wdsa_c <<8 ) | wdsa_d,wdsa_l); //合并为16位
      if(Time_out==1) break;  //超时退出
      dsa_init();
      Ack=0;      
      for(j=0;j <= 300;j++)  
        {  
          if(Stb==0) break;  //如果选通0,应答成功
          if(j==300)return;
        }
      dsa_init();
      Send_ok=1;            //发送成功            
     }       
    if(Send_ok==1) break;
   }
 }
/*F**************************************************************************
* NAME: Rd_data
*----------------------------------------------------------------------------
* PURPOSE: 
*   read word data from servo routine 
*****************************************************************************/

 unsigned char Rd_data()    //读字节
 {
   uchar i;
   uint j;
   uchar r_data;
   Time_out=0;   
   for(i=0;i<8;i++)
   {
     for(j=0;j <= 300;j++)  //如果选通不为0,数据无效
      {  
       if(Stb==0) break;  //如果选通0,数据有效
       if(j==300) Time_out=1;
      }
     if(Time_out==1) break;  //超时退出stb
     r_data <<=1;  
     if(S_data==1) r_data |= 0x01;  //读数据
     check_count++;
     Ack=0;  //应答
     for(j=0;j <= 300;j++)  
      {  
       if(Stb==1) break;  //如果选通1,应答成功
       if(j==300) Time_out=1;
      }
     if(Time_out==1) break;  //超时退出stb   
     Ack=1;  //应答

    }   
   return(r_data);
  }
/*F**************************************************************************
* NAME: Rd_command
*----------------------------------------------------------------------------
* PURPOSE: 
*   read dsa command routine 
*****************************************************************************/
void Rd_command()  //读命令
{    
   uint  j;
   uchar i; 
   Read_ok=0;
   check_count=0;
   dsa_init();

  for(i=0;i<1;i++)
   {
     if((Ack==0) | (Stb==0 )) break;
     for(j=0;j <=300;j++)        //如果不为0,未握手,不能太长
        {  
         if(S_data==0) break;     //如果应答0,握手OK
         if(j==300)return;
        }
    Ack=0;                       //应答0
    for(j=0;j <= 300;j++)        //如果应答不为1,握手未完成
         {  
           if(S_data==1) break;  //如果应答1,握手完成
           if(j==300) return;
         }
     Ack=1;     

     dsa_com = Rd_data();
	 dsa_data1 = Rd_data();
	 dsa_data2 = Rd_data();

     if(Time_out==1)return;  //只读一次,所以超时退出
     dsa_init();      
     for(j=0;j <= 300;j++)  
        {  
          if(Ack==0) break;  //如果选通0,应答成功
          if(j==300)return;   
        }
     if(check_count==24) S_data=1;
     else S_data=0;
       Stb=0;
     for(j=0;j <= 300;j++)  //如果选通为0,数据校验
        {  
          if(Ack==1) break;  //如果选通1,应答成功
          if(j==300) return;   //超时退出
        }
     dsa_init();
     Read_ok=1;   //读数成功
    }

 }



⌨️ 快捷键说明

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