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

📄 slave_spi._c

📁 mega8 对电机控制。采用mega8对电机控制。然后再用mega16 来控制mega8
💻 _C
字号:
/*		Mega8  Slave_SPI.c	*/
unsigned char  rev_buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};	   //接收数据缓存数组
unsigned char  send_buf[10] = {1, 2, 3, 4, 5, 6, 7, 9, 0, 0};	   //反馈回主机数据缓存数组

//SPI initialisation
// clock rate: 62500hz
void spi_init(void)
{	
	 PORTB |= 0X3C;		//SPI初始化
	 DDRB &= 0xC3;		//MOSI,SCK,SS为输入,
	 DDRB |= (1 << 4);	//MISO 输出
	
	/* 使能SPI 主机模式,设置时钟速率为fck/128 */
	SPCR = ((1<<SPIE) | (1<<SPE) |(1<<SPR1) | (1<<SPR0));
	SPSR = 0x00; //setup SPI
}

/* ******************************************************************
/**********************************************************************/
#define CMD_START 0X40   		  //发送数据之前先发送起动命令字	

#define RISEGO 0x88
#define RISEBACK 0x89
#define PUSH2GO 0x8A
#define PUSH2BACK 0x8B
#define PUSH1GO 0x87

#define PID_RESET 0XA4		//复位指令(0数据指令)
#define FREE_STOP 0X81		//自由停机指令(0数据指令)
#define SPEED_SET 0X80		//速度设定(双数据指令)
#define DISTANCE_SET 0X90	//位置设定(四数据指令)
/**********************************************************************/

/**********************************************************************/
//被传输数据前加的命令字

/**********************************************************************/
#pragma interrupt_handler spi_stc_isr:11
void spi_stc_isr(void)
{
	static unsigned char i = 0;
	static unsigned char start_trans_flag = 0;	//接收开始标志
	static unsigned char com_flag = 0;	//命令类型标志,
	static unsigned char data_long = 0;	//数据传送长度
		
	unsigned char temp_char = 0x00; //传送数据
	signed int temp_int = 0x00;
	signed long temp_long = 0x00;	
	
	temp_char = SPDR;
	
	if (start_trans_flag == 0)		//
	{	/*主机向从机传送的第一个字节数据为启动字节数据,包含三部分信息,1:启动命令字0x40。2:命令类型信息,第四位为1时,表从机向主机传送数据,否则为主机向从机传送数据。3:被传送,数据流长度信息,为低四位所表之数值.*/
		if ((temp_char & 0xE0) == CMD_START)	//判断是否启动传送 1111 0000
		{
			data_long = (temp_char & 0x0f);	//0000 1111
			com_flag = (temp_char & 0x10);	//0x00->主机向从机传送,0x10->从机向主机传送
			start_trans_flag = 1;//从机开始送(标志位)
			
			if (com_flag)	//将需返回给主机的第一个字节放入SPDR,等待主机接收
			{	
				SPDR = send_buf[0]; 
				i = i+1;	//传送数据指针指向下一数据
			}
		}
	}
	else 
	{
		if (com_flag == 0x00)	//从机接收数据
		{
			rev_buf[i] = temp_char;
			
			i++;
			
			if (i >= data_long)
			{
				i = 0;
				start_trans_flag = 0;
				data_long = 0;
				com_flag = 0x00;
				
				switch (rev_buf[0])//首位设为标志位
				{
				 	case RISEGO :
						 	   	{				   
									 risemotor('g');
  									 delay_ms(2300);
  									 risemotor('s');
  									 
									 
  									/* pushmotor1('g');   //推块电机上
  									 delay_ms(1500);
  									 pushmotor1('s');*/
									 		 
												   
								}break;
					case RISEBACK:
						 		  {
								     risemotor('b'); 
  									 delay_ms(1700);
  									 risemotor('s');
								  
								  }break;			
					case PUSH2GO:
						 		  {
								     pushmotor2('g');   //推块电机下
  									 delay_ms(2000);
  									 pushmotor2('s');
								  }break;	      						     
					case PUSH2BACK:
						 		  {
								     pushmotor2('b');   //推块电机下
  									 delay_ms(2000);
  									 pushmotor2('s');
								  }break;					 	
					case PUSH1GO:
						 		 {
								     pushmotor1('g');   //推块电机上
  									 delay_ms(1500);
  									 pushmotor1('s');
								  
								  }break;		 
					
					
					case PID_RESET :	 // 系统复位(RESET) 
                                					{
                                					 	L_PIDInit ();
                                						TCNT0 = 0;
                                						num_H = 0;
                                						Num_Speed = 0;
														//write7279(DECODE1+0,5);
                                					}break;
					case FREE_STOP:
                                					{
                                    					TCCR2 = 0x00; //start计数器2不工作
                                    					PID_choice = 0xff;
														//write7279(DECODE1+7,1);
                                    					free_stop ( );	
                                    				}break;	
					case SPEED_SET :
                                					{
                                    					temp_int = rev_buf[1];
                                    					temp_int <<= 8;
                                    					temp_int += rev_buf[2];                       								
                                    					L_sPID.vi_Ref = temp_int; 
														//dis_data(0, 7,L_sPID.vi_Ref);
                                    					PID_choice = SPEED_SET;				
                                    					TCCR2 = 0x07; //start选择分频源1024
                                					}break;
					case DISTANCE_SET :
                                					{														
                                    					temp_long = rev_buf[1];
                                                        temp_long <<= 8;
														
                                                    	temp_long +=  rev_buf[2];
                                                    	temp_long <<= 8;
														
                                                    	temp_long += rev_buf[3];
                                                    	temp_long <<= 8;
														
                                                    	temp_long += rev_buf[4];

                                    					L_sPID.si_Ref = temp_long;
                                    					
														//dis_data(0, 7, temp_long);
		
                                                		//dis_data(0, 7,L_sPID.si_Ref);
														
                                    					PID_choice = DISTANCE_SET;
                                    					
                                    					TCCR2 = 0x07; //start选择分频源1024
                                    				}break;		
					default:break;
    						
				}//end switch
				
			}//end if
		}
		else				//从机发送数据
		{
			if (i < data_long)
			{
				SPDR = send_buf[i];
				i++;
			}
			else 
			{
				i = 0;
				start_trans_flag = 0;
				data_long = 0;
				com_flag = 0x00;
				
				/*send_buf[0] = 8;
				send_buf[1] = 7;
				send_buf[2] = 6;
				send_buf[3] = 5;
				send_buf[4] = 4;
				send_buf[5] = 3;
				send_buf[6] = 2;
				send_buf[7] = 1;*/
			}//end if 		
				
		}
		
	}
	
}

 void risemotor(unsigned char m)
{
      switch(m)
   {case 'g':PORTD&=~0x40;PORTD|=0x80;break;
    case 'b':PORTD|=0x40;PORTD|=0x80;break;
    case 's': PORTD&=~0x40;PORTD&=~0x80;break;
    default:break;
   }  
 }

void pushmotor2(unsigned char m)
{
    switch(m)
   {case 'g':PORTD|=0x40;PORTD|=0x80;break;
    case 'b':PORTD&=~0x40;PORTD|=0x80;break;
    case 's': PORTD&=~0x40;PORTD&=~0x80;break;
    default:break;
   }  
 }
 
 
 void pushmotor1(unsigned char m)
{
      switch(m)
   {case 'g':PORTC|=0x20;break;
    case 's': PORTC&=~0x20;break;
    default:break;
   }  
 }
/*void disp(signed int num1)//
{
	if (num1 < 0)
		num1 = -num1;
		
	send_buf[0] = num1%10;
	send_buf[1] = (num1/10) %10;
	send_buf[2] = (num1/100) %10;
	send_buf[3] = (num1/1000) % 10;
	
	send_buf[4] =  (num1/10000);
	send_buf[5] = 0;
	send_buf[6] = 0;
	send_buf[7] = 0;
}*/

/*void disp(signed int num1,  signed int num2)	//
{
	if (num1 < 0)
		num1 = -num1;
	if (num2 < 0 )
		num2 = -num2;
		
	send_buf[0] = num1%10;
	send_buf[1] = (num1/10) %10;
	send_buf[2] = (num1/100) %10;
	send_buf[3] = (num1/1000) % 10;
	
	send_buf[4] =  num2% 10;
	send_buf[5] = (num2/10) %10;
	send_buf[6] = (num2/100) %10;
	send_buf[7] = (num2/1000) % 10;
}*/

/*void send_counter (signed int num_counter )
{
	unsigned char buf[3];
	buf[0] = Counter_SET;
	
	buf[1] = (unsigned char)num_counter;
	num_counter >>= 8;
	buf[2] = (unsigned char)num_counter;
	
	MasterTransmit(buf, 3);
}

void send_control (signed int num_control )
{
	unsigned char buf[3];
	buf[0] = Control_SET;
	
	buf[1] = (unsigned char) num_control;
	 num_control >>= 8;
	buf[2] = (unsigned char) num_control;
	
	MasterTransmit(buf, 3);
}*/

⌨️ 快捷键说明

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