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

📄 send_485.c

📁 基于ATmega8开发的关于医疗康复的机器人
💻 C
字号:
/*****************************************************
* File name      : Send_485.C
* Description    : Header file of  main_H.H
* Platform       : ICCAVR 
* Author         : xiao xue      
* Email          : ay1509@yahoo.com
* Date           : 2008-03-13
* Description    :485 Communications
/********************头文件*************************/
#include"main_H.h"
#define fosc 8000000
#define baud 9600
/***************************485初始化***************************/
void RS485_init(void)  
 {
    UCSRB=(1<<RXCIE)|(1<<RXEN)|(1<<TXEN); 	//接收完成中断使能
											//充许发送、充许接收 
    UBRRL=(fosc/16/(baud+1))%256; 		  	//波特率为9600
    UBRRH=(fosc/16/(baud+1))/256;
    UCSRC=(1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);   
    PORTD&=~0x04;  						  	//允许接收数据
    DDRD|=0x04;    							//数据方向
} 
/******************485发送一个字节子程序************************/   
void  RS485_out_byte(uchar data )  
{

  while(!(UCSRA & (1<<UDRE)) );				//等待数据寄存器不为空
     UDR=data;
  while(!(UCSRA & (BIT(TXC))));  			//等待USART发送完成
     UCSRA|=BIT(TXC);			 
}

/**************************一次发送6个字节*********************/

void  RS485_out_6byte(uchar *datas )  
{  
	uint i=0;
 	CLI();							//关中断
  	PORTD|=0x04;   					//允许发送
 	while(i<6 ){
  		RS485_out_byte(*(datas+i));	//发送1个字节
 		i++;
  	} 
 	delay_nms(5);					//延时
 	PORTD&=~0x04;  				 	//允许接收
	SEI();
} 
/**************************485发送数据函数*****************/
void Send_485(void)
{ 	
	RS485_out_6byte(moto1);			//给节点1发送数据
   	RS485_out_6byte(moto2);			//给节点2发送数据
    RS485_out_6byte(moto3);
 	RS485_out_6byte(moto4);
}
/***************************中断接收服务子程序*******************/
#pragma interrupt_handler RS485_ISR:iv_USART_RX
void RS485_ISR(void)
 {
 CLI(); 							//关中断
 PORTD&=~0x04; 						//允许接收
 getchar[RS_i]=UDR; 				//存储数据寄存器的值
 RS_i++;							//预备存储下一个
 if(RS_i==6) 						//接收6个后清零
 	{RS_i=0;flag=3;}		
 SEI();								//开中断
 }
 
 /**********************接收数组判断存储子程序************************/
void data_decide(void)
{
	uchar RS_j=0;
	if(getchar[0]==0xaa){
		switch(getchar[1]){
			case 0x1e:				//节点1
				while(RS_j<6){  
  					get[0+RS_j]=getchar[RS_j];
    				RS_j++;
				}
				break;
			case 0x2d:				//节点2
				while(RS_j<6){  
  					get[6+RS_j]=getchar[RS_j];
        			RS_j++;
				}
				break;
			case 0x3c:				//节点3
				while(RS_j<6){  
  					get[12+RS_j]=getchar[RS_j];
        			RS_j++; 
				}
				break;
			case 0x4b:				//节点4
				while(RS_j<6){  
  					get[18+RS_j]=getchar[RS_j];
        			RS_j++;    
     			}//end while
				break;
		}//end switch
	}//end if
}

/***************************各电机停止函数,相关变量清零***********/
void moto_stop(void)
{
	moto1[2]=0xb4;      //向各节点停止命令
   	moto2[2]=0xb4;     
   	moto3[2]=0xb4;	 	
   	moto4[2]=0xb4;   	  
    
   	get[2]=0x00;		//接收控制指令数组清零
   	get[8]=0x00;
   	get[14]=0x00;
   	get[20]=0x00;
   
  	status[2]=0;   		//状态数组之时间清0
   	TIMSK=0x00;    		//定时器关闭 	
   	page=4;        		//显示第四页停止页面 
   	flag=2; 			//flag标志清零
}
 /**************运动到达指定循环步数之前***********/
void step_for(void)
{
  	moto1[4]=p[++i];	//存储各节点的运动速度(时间)
  	moto2[4]=p[i];
  	moto3[4]=p[i];
  	moto4[4]=p[i];   
  	i++;
  	moto1[3]=p[i++];	//存储各节点的运动位置
  	moto2[3]=p[i++];
  	moto3[3]=p[i++];
  	moto4[3]=p[i];
 	flag=2;  			//主函数flag标志置数
}
/***************运动到达指定循环步数之后***********/
void step_back(void)
{
  	moto1[4]=p[i];					//存储各节点运动速度(时间)
  	moto2[4]=p[i];
  	moto3[4]=p[i];
  	moto4[4]=p[i]; 
  
  	i++;							//变量加1,准备执行下一步
  
  	moto1[3]=p[i++]*status[1]/0x64; //运动位置转换后存储
  	moto2[3]=p[i++]*status[1]/0x64;  
  	moto3[3]=p[i++]*status[1]/0x64; 
  	moto4[3]=p[i++]*status[1]/0x64; 
    
 	flag=2;							//主函数flag标志置数
}
/***************************接收数据决断子程序*******************/
void RS485_getchar(void)
{
  	
  	data_decide();					//接收数组判断存储子程序
   
	while(1){
	 	if(second==status[2]){ 		//运动时间到  
    		moto_stop();			//电机停止函数
			break;
  		}//end if
		if((get[2]==0xff)&&(get[8]==0xff)&&	//各节点电机都已停止
			(get[14]==0xff)&&(get[20]==0xff)){
     		
			get[2]=0x00;					//各节点控制指令清零
     		get[8]=0x00;
     		get[14]=0x00;
     		get[20]=0x00;		
  			
			if(i<((p[1]-1)*5+1)){		  	//未到达设定的循环开始步数
  				step_for();					//相应处理函数
  			}//end if  	
 			else if((i>(p[1]-1)*5+1)&&(j==1)){ 	//已经到达设定的运动步数
 				step_back(); 				//相应处理函数
  			}//end else if
  			else{ 							//是否到达运动循环开始的第一步
				j=1;							
				i=((p[1]-1)*5+2);			//准备执行下一步
			}//end else
			if(i==(p[0]*5+2)){				//是否到达最后一步
				i=(p[1]-1)*5+2;				//重新从第一条指令开始执行
			}//end if
  		}//end if		 
	}//end while
}

⌨️ 快捷键说明

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