📄 slave.c
字号:
//*****************************************
//slave1
//!@#$
//2006.5.15-
//*******************************************
#include <ADuC7020.H>
//#include "others.h"
#include "my_type.h"
#include "interrupt.h"
#include "slave.h"
#include "math.h"
//#include <intrins.h>
extern double Z_w_result;
extern uint16 A_value[2];
extern uint16 A_S_value[2][30];
struct datapackage_r z_global_receive_bufn[3];
struct datapackage_s z_global_send_bufn[16];
/////////////////new
//struct datapackage z_global_receive_buf; //全局接收数据的缓存
struct datapackage *z_globalp; //
//
struct datapackage z_global_receive_data; //接收到的数据的结构体
struct datapackage z_global_send_buf[8]; //发送数据的结构体
struct datapackage_s zero={8}; //用于赋结构体初值的结构体
unsigned char slavecode[9][3]= { /*把sslave改为slavedata[3]*/
{'b','a','d'},
{'1','a','b'},
{'2','c','d'},
{'3','e','f'},
{'4','g','h'},
{'5','i','g'},
{'6','k','l'},
{'7','m','n'},
{'8','o','p'}
};
unsigned char z_flag_keyframe; //key frame 关键帧发送的标志
/*z_flag_locaddr 改为z_flag_chosen*/
unsigned char z_flag_chosen; //本机地址选中标志
unsigned char z_flag_newins; //新任务标志。当有新的指令时,此标志置1;主程序中一旦执行新任务,此标志清零
unsigned char z_counter; //用于接收数据时的计数,计为0时表示接收结束,当置为0xFF时表示接收的是数据包首字节
unsigned char z_globalcheck_sum; //全局校验(和),收和发均用这个变量
unsigned char z_instruction; //接收到的指令
unsigned char z_checksum; //校验和
unsigned char z_flag_newframe;
unsigned char z_recnum;
unsigned char cont;
unsigned char shakenum;
unsigned char blocknum;
unsigned char priority;
unsigned char flag_pri;
unsigned char flag_pri_temp;
unsigned char flag_pri_tim;
struct datapackage_r z_global_receive_bufn[3];
struct bigpackage bigp[8];
/************************************
通讯初始化,从机在初始化时吊用
*************************************/
void Z_COMMUNI_INIT(void)
{
OFF_TXD(); // z_enable_TXD = 0; //491芯片发送数据的使能关闭
z_flag_keyframe = 0; //关键帧真发送置0
z_flag_chosen = 0; //本地地址选中置0
z_flag_newins = 0; //有新任务标志置0
z_recnum = 0;
z_counter = 0xFF; //开始接受第一位标志
z_flag_newframe = 1;
z_global_send_bufn[0] = zero; //以下8行为结构体清0
z_global_send_bufn[1] = zero;
z_global_send_bufn[2] = zero;
z_global_send_bufn[3] = zero;
z_global_send_bufn[4] = zero;
z_global_send_bufn[5] = zero;
z_global_send_bufn[6] = zero;
z_global_send_bufn[7] = zero;
z_global_send_bufn[8] = zero; //以下8行为结构体清0
z_global_send_bufn[9] = zero;
z_global_send_bufn[10] = zero;
z_global_send_bufn[11] = zero;
z_global_send_bufn[12] = zero;
z_global_send_bufn[13] = zero;
z_global_send_bufn[14] = zero;
z_global_send_bufn[15] = zero;
shakenum = 0;
flag_pri = 0;
}
/*函数体*/
/************************************
发送数据的底层函数
输入数据类型为无符号整型,无返回值
函数将要发送的数据置入SBUF发送出去
*************************************/
void Z_TXD(unsigned char tosend)
{
COMTX=tosend;
while(!(COMSTA0 & 0x40)); //等待发送完毕
}
/********************************************/
/********************************************/
unsigned char Z_GETYOU(void)
{
unsigned char x = 0x80;
flag_pri_temp = flag_pri;
flag_pri_tim = 7;
if(!flag_pri_temp)
{
return(0);
}
else
{
while(flag_pri_temp<0x80)
{
flag_pri_temp<<=1;
flag_pri_tim--;
x=x>>1;
}
flag_pri = flag_pri-x;
return(1);
}
}
/*************************************
从机向主机返回握手信号的函数
无输入,无返回值
返回给主机的值已预设,不能更改
*************************************/
void Z_RESPOND_BAD(void)
{
ON_TXD();
Z_TXD(0x02); //发送握手信号的首字节,与HOST程序段相对应,不能更改
Z_TXD('B'); //发送数据'A'
Z_TXD('A'); //发送数据'B'
Z_TXD('D'); //发送数据'C'
OFF_TXD();
}
/************************************/
void Z_RESPOND_HEAD(void)
{
ON_TXD();
Z_TXD(0x02); //发送握手信号的首字节,与HOST程序段相对应,不能更改
Z_TXD('H'); //发送数据'A'
Z_TXD('E'); //发送数据'B'
Z_TXD('D'); //发送数据'C'
OFF_TXD();
}
/*************************************
从机向主机返回握手信号的函数
无输入,无返回值
返回给主机的值已预设,不能更改
*************************************/
void Z_RESPOND_OKAY(void)
{
ON_TXD();
Z_TXD(0x02); //发送握手信号的首字节,与HOST程序段相对应,不能更改
Z_TXD('O'); //发送数据'A'
Z_TXD('K'); //发送数据'B'
Z_TXD('Y'); //发送数据'C'
OFF_TXD();
}
/************************************
从机向主机返回握手信号的函数
无输入,无返回值
返回给主机的值已预设,不能更改
*************************************/
void Z_RESPOND_SHAKEHANDn(void)
{
ON_TXD();
Z_TXD(0x02); //发送握手信号的首字节,与HOST程序段相对应,不能更改
Z_TXD(slavecode[Local][0]); //发送数据'A'
Z_TXD(slavecode[Local][1]); //发送数据'B'
Z_TXD(slavecode[Local][2]); //发送数据'C'
OFF_TXD();
}
/************************************
串行通信发送数据包的函数
输入数据类型为指向结构体datapackage的指针
无返回值
将结构体中的数据依次发次给主机
调用函数 void Z_TXD(unsigned char tosend)
*************************************/
void Z_UART_SEND(struct datapackage_s *p)
{
// unsigned char z_checksum; //校验和,放在这里有问题
unsigned char datanum; //数据数量
unsigned char i; //用于循环
ON_TXD();
// z_enable_TXD=1; //491芯片发送数据使能
// ES=0; //关串口中断,不接收数据
Z_TXD(p->head); //发送 关键帧/地址 指令 长度 复用字节
z_checksum=p->head; //校验和赋初值
datanum=(p->head)&0x07; //取数据首字节的后三位即为数据包长度值
for(i=0;i<datanum;i++) //根据数据包长度,依次发送数据
{
Z_TXD(p->dat[i]); //发送字节
z_checksum+=p->dat[i]; //校验和累加
}
Z_TXD(z_checksum); //发送校验和
// ES=1; //开串口中断,接收数据使能
OFF_TXD();
// z_enable_TXD=0; //491芯片发送数据禁止
}
/************************************
发送普通数据包的函数
输入参数类型为指向结构体datapackage的指针
无返回值
调用函数 void Z_UART_SEND(struct datapackage *p)
*************************************/
void Z_INFO_SEND(struct datapackage_s *p)
{
if(0 != (p->head)&0x08) //若数据包首字节的第3位为1,则置关键帧标志
{
z_flag_keyframe=1;
}
Z_UART_SEND(p); //发送数据包
z_counter=0xff; //置下次接收数据为数据包首字节的标志
}
/************************************
串口通信中断函数
接收中断
调用函数 void Z_RESPOND_SHAKEHAND(void)
*************************************/
void UART_R_ISR(void)
{
unsigned char buf; //接收数据的缓存
buf=COMRX;
if(0xFF == z_counter) //发送完数据后的第一次接收
{
z_flag_chosen=0; //本机地址选中标志清零,等数据比较完以后再置位
z_counter=(0x07&buf); //读取缓存中的字符,默认其为地址值,求出数据包的长度
cont = z_counter;
if( ((0xE0)&buf) == LOCAL_ADDRESS) //缓存的最高两位表示地址值,取出,比较
{
z_instruction=0x18&buf; //缓存第3~5位的指令值
// z_global_receive_buf.head=buf; //缓存赋给接收数据包的首字节
z_flag_chosen=1; //本机地址选中标志置1
z_globalcheck_sum=buf; //校验和赋初值
}
}
else //如果不是第一次接收
{
if(z_flag_chosen == 0) //如果本机未被选中,则不赋值
{
z_counter--; //默认接收到数据,数据长度减一
}
else //如果本机被中
{
if(z_counter!=0) //判断是否已经接收完毕,如果未接收完
{
z_global_receive_bufn[z_recnum].dat[cont-z_counter]=buf;
// z_global_receive_buf.dat[z_counter-1]=buf; //把当前接收到的数据赋给接收用的结构体evalue the struct
z_globalcheck_sum=z_globalcheck_sum+buf; //校验和累加
z_counter--; //需要接收的数据减一
}
else
{
z_counter--; //接收完毕,z_counter减一,变成0xFF,进入下一次的接收准备
// ES=0; //接收中断关,准备发送数据
// Z_TXD(0xdd);
// Z_TXD(z_globalcheck_sum) ;
// Z_TXD(buf) ;
//bigp[priority].instruction]);
if(z_globalcheck_sum==buf) //比较校验和,如果数据正确,则执行主机发来的指令
{
z_instruction=z_instruction&0x18; //取出指令
z_instruction>>=3; //右移3位,以便可以用10进制读取
// Z_INFO_SEND(&z_global_send_bufn[1]);
if(SHAKEHAND==z_instruction) //如果是握手指令
{
Z_RESPOND_SHAKEHANDn(); //与主机握手
shakenum++;
if(shakenum == 3)
{
shakenum = 0;
z_recnum = 0;
z_flag_newframe = 1;
}
}
else //如果不是握手指令,则发送正常的数据
{
// Z_INFO_SEND(&z_global_send_bufn[1]);
shakenum = 0;
if(z_flag_newframe) //如果是新的一个大贞
{
blocknum = z_instruction; //看打针包括几快
priority = (z_global_receive_bufn[0].dat[0]&0x70)>>4;
bigp[priority].instruction = z_global_receive_bufn[0].dat[0]&0x0f;
if(!blocknum) //如果只有一快
{
while(cont>0)
{
cont--;
bigp[priority].x[cont]=z_global_receive_bufn[0].dat[cont];
} ;
flag_pri = flag_pri|(0x01<<priority);
Z_INFO_SEND(&z_global_send_bufn[bigp[priority].instruction]);
z_recnum = 3;
}
else
{
z_flag_newframe = 0;
Z_RESPOND_HEAD();
}
}
else
{
if((z_instruction+z_recnum)!=blocknum)
{
; // Z_RESPOND_BAD();
}
else
{
if((blocknum-z_instruction) == blocknum)
{
z_recnum = 3;
z_flag_newframe = 1; //next真是新真
flag_pri = flag_pri|(0x01<<priority);
Z_INFO_SEND(&z_global_send_bufn[bigp[priority].instruction]);
switch(blocknum)
{
case 2:
{
bigp[priority].x[1] =z_global_receive_bufn[0].dat[1];
bigp[priority].x[2] =z_global_receive_bufn[0].dat[2];
bigp[priority].x[3] =z_global_receive_bufn[0].dat[3];
bigp[priority].x[4] =z_global_receive_bufn[0].dat[4];
bigp[priority].x[5] =z_global_receive_bufn[0].dat[5];
bigp[priority].x[6] =z_global_receive_bufn[0].dat[6];
bigp[priority].x[7] =z_global_receive_bufn[1].dat[0];
bigp[priority].x[8] =z_global_receive_bufn[1].dat[1];
bigp[priority].x[9] =z_global_receive_bufn[1].dat[2];
bigp[priority].x[10]=z_global_receive_bufn[1].dat[3];
bigp[priority].x[11]=z_global_receive_bufn[1].dat[4];
bigp[priority].x[12]=z_global_receive_bufn[1].dat[5];
bigp[priority].x[13]=z_global_receive_bufn[1].dat[6];
do
{
cont--;
bigp[priority].x[14+cont]=z_global_receive_bufn[2].dat[cont];
}while(cont!=0);
}break;
case 1:
{
bigp[priority].x[1]=z_global_receive_bufn[0].dat[1];
bigp[priority].x[2]=z_global_receive_bufn[0].dat[2];
bigp[priority].x[3]=z_global_receive_bufn[0].dat[3];
bigp[priority].x[4]=z_global_receive_bufn[0].dat[4];
bigp[priority].x[5]=z_global_receive_bufn[0].dat[5];
bigp[priority].x[6]=z_global_receive_bufn[0].dat[6];
do
{
cont--;
bigp[priority].x[7+cont]=z_global_receive_bufn[1].dat[cont];
}while(cont!=0);
}break;
};
}
else
{
// Z_RESPOND_OKAY();
}
}
}
z_recnum++;
if(z_recnum>2)
{
z_recnum = 0;
}
// Z_INFO_SEND(&z_global_send_buf[z_instruction]); //把已准备好的数据发送出去
// z_global_receive_data=z_global_receive_buf; //把接收到的数据转移到接收数据的结构体中
z_flag_newins=1; //置新任务标志
}
}
else //如果接收到的数据不正确
{
}
// ES=1; //打开串口中断,准备下一次接收数据
}
}
}
// }
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -