📄 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 + -