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

📄 slave.c

📁 基于陀螺仪原理的惯性导航程序 用于测量量角速度
💻 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 + -