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

📄 comm._c

📁 一个正在应用的步进电机控制程序,包括电机的调速,正反,细分,通讯控制
💻 _C
字号:
/*******************************************************
/*ICC-AVR application builder : 2004-3-11 12:02:11
// Target : atMega16
// Crystal: 8.0000Mhz
通讯模块  单工双向485接口
******************************************************/
#include <string.h>
#include <iom32v.h>
#include <math.h>
#include <stdlib.h>
#include <macros.h>
#include <eeprom.h>
#include "eeprom_l.h"
#include "comm.h"
#include "main.h"
#include "delay.h"
#include "key.h"
	 
#pragma data:data
unsigned char state2;
//state2.0 disable_data    //1:输入数据无效,0有效;
//state2.1 remote		   //1:遥控输入有效,0:本地输入有效
//state2.7 p99			   //P99指令使能
unsigned char state1;		   				   					  
//state1.2 PE  
//state1.3 DOR
//state1.4 FE
//state1.5 
//state1.6 
unsigned char pump_tab;		//机器号								   
extern unsigned int speed;
extern unsigned char state_other;
extern unsigned char state0;
extern unsigned char key;
extern unsigned char in_out_number;
extern unsigned char state;
//state0.5接收消息有效标志

/* 通信变量定义 */
char txd_frm[15];         //物理层发送缓冲区
char txd_frm_len;          //物理层发送数据长度
char rxd_frm[15];         //物理层接收缓冲区
char rxd_frm_len;          //物理层接收数据长度
char tx485_busy;		   //485发送工作判忙
char txd_cnt;			   //发送数据计数器
char rxd_cnt;			   //接收数据计数器
char rxd_ins_flag;		   //一帧接收数据中有E8或E9标志
char txd_ins_flag;		   //一帧发送数据中有E8或E9标志
char txd_ins_data;		   //发送数据
char rxd_data;			   //接收数据
char mac_txd_th;		   //发送状态 0发送完毕,1发送帧头,2发送中间数据
char rxd_h_ok;			   //接收开始标志
char fcs1;				   //异或校验
char rxd_mesg_addr;		   //接收地址
char rxd_mesg_len;		   //应用层接收数据长度
char rxd_mesg[15];		   //应用层接收数据缓冲区
char txd_mesg_addr;		   //发送地址
char txd_mesg_len;		   //应用层发送数据长度
char txd_mesg[15];		   //应用层发送数据缓冲区
/*********任务管理*************/
char pri[16];
char act[16];           //任务寄存器
char rxd_llc_job;       //物理层收任务寄存器
char txd_llc_job;       //物理层发任务寄存器
char rs485_app_job;     //应用层任务寄存器
char att_n_max;
extern struct cal
       {
	   unsigned  int       test_time;
	   unsigned  long int  dispvol;
	   unsigned  long int  test_dispvol;
	   float               dispk;
	   unsigned  long int  run_time;
	   };
extern struct cal cal0;
/*****************************************************************
功能: serial_int
描述: 运行串行口 FSAs.
参数: 无.
返回无.
影响无.
*****************************************************************/
#pragma interrupt_handler serialri_int:iv_USART_RX
#pragma interrupt_handler serialti_int:iv_USART_TX

/* 通信物理层发送中断程序模块 */
void serialti_int(void)
{ 
	char i;
	    UCSRA=RS485_UCSRA|0b01000000;   /*清发送完中断标志位*/
		if(mac_txd_th==1)
		{ UDR=0xe9;
		  txd_cnt=0;
		  txd_ins_flag=0;
		  tx485_busy=1;
		  mac_txd_th=2;
		}
		else
		{ if(mac_txd_th==2)
		  { if(txd_ins_flag==1)
		    { txd_ins_flag=0;
			  UDR=txd_ins_data;
			}
			else
			{ if(txd_cnt<=(txd_frm_len-1))
			  { if(txd_frm[txd_cnt]==0xe8||txd_frm[txd_cnt]==0xe9)
			    { txd_ins_flag=1;
                  txd_ins_data=txd_frm[txd_cnt]-0xe8;
                  UDR=0xe8;
				}
				else
				{ UDR=txd_frm[txd_cnt];}
				txd_cnt=txd_cnt+1;
			  }
			  else
			  { tx485_busy=0;
			    mac_txd_th=0;
				PORTC&=~(1<<DE_485);
			  }
			}
		  }
		  else
		  { tx485_busy=0;
		    mac_txd_th=0;
			PORTC&=~(1<<DE_485);
		  }
		}
}

/* 通信物理层接收中断程序模块 */
void serialri_int(void)
{
	char i;
	    UCSRA=RS485_UCSRA&0b00111111;   /*清接收完中断标志位*/
		rxd_data=UDR;
		if(tx485_busy!=1)
		{ if(rxd_data==0xe9)
		  { rxd_h_ok=1;
            rxd_cnt=0;
			rxd_ins_flag=0;
			rxd_frm_len=0;
			fcs1=0;
		  }
		  else
		  { if(rxd_h_ok==1)
		    { if(rxd_data==0xe8)
			  { rxd_frm[rxd_cnt]=0xe8;
			    rxd_ins_flag=1;
			  }
			  else
			  { if(rxd_ins_flag==1)
			    { rxd_ins_flag=0;
				  rxd_frm[rxd_cnt]=rxd_frm[rxd_cnt]+rxd_data;
				}
				else
				{ rxd_frm[rxd_cnt]=rxd_data;}
				fcs1=fcs1^rxd_frm[rxd_cnt];
				if(rxd_cnt==1)
				{ rxd_frm_len=rxd_frm[rxd_cnt]+3;}
				rxd_cnt=rxd_cnt+1;
				if((rxd_cnt>1)&&(rxd_cnt>=rxd_frm_len))
				{ if(fcs1==0)
				  { 
				  act[rxd_llc_job]=1;
				  }
				}
			  }
			}
		  }
		}
}


/*********************************/
void rxd_llc_job1(void)
    { 
	char i;
	   act[rxd_llc_job]=0;
	   if((pump_tab==rxd_frm[0])||(rxd_frm[0]==BROADCAST_ADDR))  //接收指令地址等于设备或广播地址
	   { rxd_mesg_addr=rxd_frm[0];
	     rxd_mesg_len=rxd_frm[1];
		 for(i=0;i<rxd_mesg_len;i++)
		 { rxd_mesg[i]=rxd_frm[i+2];}
		 act[rs485_app_job]=1;
	   }
	}
/*********************************/
void txd_llc_job1(void)
    { 
	char i,fcs;
	   act[txd_llc_job]=0;
	   txd_frm[0]=txd_mesg_addr;
	   txd_frm[1]=txd_mesg_len;
	   fcs=txd_frm[0]^txd_frm[1];
	   for(i=0;i<txd_mesg_len;i++)
	   { txd_frm[i+2]=txd_mesg[i];
	     fcs=fcs^txd_frm[i+2];
	   }
	   txd_frm_len=txd_mesg_len+3;
	   txd_frm[txd_frm_len-1]=fcs;
	   txd_cnt=0;
	   txd_ins_flag=0;
	   tx485_busy=1;
	   mac_txd_th=2;
	   PORTC|=(1<<DE_485);
	   UDR=0xe9;
	}
	
/*********************************/
void rs485_app_job1(void)
    { 
	char i,fcs;
	unsigned int temp;
	unsigned long int flow_temp;
	unsigned long int rxd_mesg_temp;
	act[rs485_app_job]=0;
	
	   if((rxd_mesg_addr!=BROADCAST_ADDR)&&(rxd_mesg[0]=='R')&&(rxd_mesg[1]=='I')&&(rxd_mesg[2]=='D'))   /* 读取设备地址命令e9 01 03 52 49 44 5d */
	   { txd_mesg_addr=pump_tab;
	     txd_mesg_len=3;
		 txd_mesg[0]='R';
		 txd_mesg[1]='I';
		 txd_mesg[2]='D';
		 act[txd_llc_job]=1;
		 goto rs485_app_ret;
	   }
	   
	   if((rxd_mesg[0]=='W')&&(rxd_mesg[1]=='I')&&(rxd_mesg[2]=='D'))   /* 设置设备地址命令e9 1f 04 57 49 44 01 40 */
	   { pump_tab=rxd_mesg[3];
		 do {temp=EEPROMwrite(pump_tab_romaddr,pump_tab);}
	     while(temp>0);
		 if(rxd_mesg_addr!=BROADCAST_ADDR)
		 { txd_mesg_addr=pump_tab;
		   txd_mesg_len=3;
		   txd_mesg[0]='W';
		   txd_mesg[1]='I';
		   txd_mesg[2]='D';
		   act[txd_llc_job]=1;
		 }
		 goto rs485_app_ret;
	   }

	   if((rxd_mesg_addr!=BROADCAST_ADDR)&&(rxd_mesg[0]=='R')&&(rxd_mesg[1]=='J'))   // 读取运行参数命令e9 01 2 52 47 16 
	   { //if(in_out_number<2)
	     //{ 
		   txd_mesg_addr=pump_tab;
		   txd_mesg_len=6;
		   txd_mesg[0]='R';
		   txd_mesg[1]='J';
		   txd_mesg[2]=(speed>>8);
		   txd_mesg[3]=speed;
		   txd_mesg[4]=0;
		   if (state&(1<<RUN_STOP))
		     {txd_mesg[4]|=0b00000001;}
		   else
		     {txd_mesg[4]&=0b11111110;}
		   txd_mesg[5]=0;
		   if (state&(1<<CW_CCW))
		     {txd_mesg[5]&=0b11111110;}
		   else
		     {txd_mesg[5]|=0b00000001;}		 
		   act[txd_llc_job]=1;
		 //}
		 //else
		 //{ act[rs485_app_job]=1;}
		 goto rs485_app_ret;
	   }
       
	   if((rxd_mesg[0]=='W')&&(rxd_mesg[1]=='J'))   // 设置运行参数命令 
	   { if(in_out_number<2)  //内控控制
	     { //delay_cortrol_job();	   
           all_stop();//停止所有运行 
		   rxd_mesg_temp=rxd_mesg[2];//必须如此,rxd_mesg[4]进行常整运算时有错
		   speed=rxd_mesg_temp*256+rxd_mesg[3];
		   if ((speed==0)||(speed>600))
		     {speed=1;}
		   cal_timer1(speed);
		   EEPROMWriteWord(speed_romaddr,&speed);
		   if (rxd_mesg[4]&0b00000001)
		     {state|=(1<<RUN_STOP);}
		   else
		     {state&=~(1<<RUN_STOP);} 
		   if (rxd_mesg[5]&0b00000001)
		     {state&=~(1<<CW_CCW);}
		   else
		     {state|=(1<<CW_CCW);}
		   do {temp=EEPROMwrite(state_romaddr,state);}
	           while(temp>0);           
		   state_init();
		   
		   if(rxd_mesg_addr!=BROADCAST_ADDR)
		   { txd_mesg_addr=pump_tab;
		     txd_mesg_len=2;
			 txd_mesg[0]='W';
			 txd_mesg[1]='J';
			 act[txd_llc_job]=1;
		   }
		 }
		 goto rs485_app_ret;
	   }        
rs485_app_ret:;
	}
/*********************************/

/* 主调度任务程序模块 */
void job_att(char step)
	{
	char i,crrt_jn;
	   if(step==0) 
	   { for(i=1;i<=31;i++)
	     { pri[i]=0;
		   act[i]=0;
		 }
		 rxd_llc_job=9;
		 pri[rxd_llc_job]=95;
		 txd_llc_job=10;
		 pri[txd_llc_job]=94;
		 rs485_app_job=11;
		 pri[rs485_app_job]=93;
		 att_n_max=12;
	   }
	   else
	   { crrt_jn=0;
		 for(i=1;i<=att_n_max;i++)
	     { if((act[i]!=0)&&(pri[i]>pri[crrt_jn]))
		   { crrt_jn=i;}
		 }
		 switch (crrt_jn)
		 { 
		   case 9: rxd_llc_job1();
		   break;
		   case 10: txd_llc_job1();
		   break;
		   case 11: rs485_app_job1();
		   break;
		   case 12: break;
		 }
	   }	
	}

/*
串口初始化   
*/         
void serial_init (void)  
{
  	  UBRRH=RS485_BAUDH;
	  UBRRL=RS485_BAUDL;
	  UCSRA=RS485_UCSRA;
	  UCSRC=RS485_UCSRC;
	  UCSRB=RS485_UCSRB;
	  UCSRB=UCSRB|0b00011000;   /* 允许接收、发送 */
      state1=0;
      DDRC|=(1<<DE_485);
      PORTC&=~(1<<DE_485);
}

⌨️ 快捷键说明

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