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

📄 modbus.c

📁 基于TMS320F2812的电动机控制源码(使用C语言)
💻 C
📖 第 1 页 / 共 2 页
字号:
/*=====================================================================================
 File name:        Modbus.C  (28x version)                  
                    
 Originator:	   R&D Group
	           		NIE

 Dsscription:     communication  base on Modbus                 
 
=====================================================================================
 History:
-------------------------------------------------------------------------------------
 03-17-2005	Release	Rev 1.0
 
 08-13-2005 Release Rev 1.02
 	: 修改了汉字传输的顺序,参数表可以直接输入汉字
-------------------------------------------------------------------------------------*/
#include "DSP281x_Device.h"
#include "DSP281x_Sci.h"
#include "Modbus.h"         // Include header for Mudbus library
#include "fault_log.h"
extern FAULTLOG faultlog;
//#define FAULT_LOG_MAX  1

#define	WAIT_DATA_HEAD  0	//等待报头
#define READ_DATA		1	//接受数据
#define PROCESSING_DATA 2   //处理数据
#define SEND_DATA		3	//发送响应报文

#define PARA_MAX_NUM    50
#define PARA_MAX_TBL_A	180
extern int Parameter0;

////////////rs485端口///////////////////////
void CommA(MODBUS *v)
{
	int	TempA,TempB,TempC;
	long * TablePoint;
	int * DataPoint;	

	//通讯帧故障清除
	if(SciaRegs.SCIRXST.bit.RXERROR)
	{
	SciaRegs.SCICTL1.bit.SWRESET=0;
	SciaRegs.SCICTL1.bit.SWRESET=1;
	}

	switch(v->CommFlag)	
	{
	//接受报头
	case WAIT_DATA_HEAD:	
		{
		while((SciaRegs.SCIFFRX.bit.RXFIFST!=0)&&(v->CommFlag==0))
			{
			TempA=(SciaRegs.SCIRXBUF.all&0x00ff);
			if((TempA==0x00ff)||(TempA==v->Slave_Address))
				{
				v->CommData[0]=TempA;
		
		{		v->Index=1;
				v->CommFlag=READ_DATA;		//跳出本循环
				v->CommCount=0;
				}
			}
		}	
		break;
	//接受数据		
	case READ_DATA:
		v->CommCount++;
		while(SciaRegs.SCIFFRX.bit.RXFIFST!=0)
			{
			v->CommData[v->Index]=(SciaRegs.SCIRXBUF.all&0x00ff);	//
			//if((v->CommData[v->Index]&0x0ff00)==0)
				{		//数据必须正确
				v->Index++;
				if(v->Index>=PARANUMMAX)
					{
					v->Index=0;
					v->CommFlag = WAIT_DATA_HEAD;
					}
				v->CommCount=0;	
				}
			}	
		if(v->CommCount>=DELAYCOUNT)
			{
			v->CommFlag = PROCESSING_DATA;	
			}
		}	
		break;
	//处理报文,产生响应报文
	case PROCESSING_DATA:
		{
		if(CRC_cal(v->CommData,v->Index)==0)   //if1
			{
			switch(v->CommData[1])
				{	//switch2
				//MODBUS功能3
				case 3:				
					{
					TempA=(v->CommData[2]<<8)|(v->CommData[3]);		//参数起始地址
					switch(TempA)
						{	//switch3
						//菜单页参数读命令
						case 919:			
							{
							//固定长度响应报文
							v->CommData[2]=32;
							DataPoint=&ParaTblA[v->ParaNum][0] ;
							//读取PARA_TAB中的数据
							TempA=3;
			  				while(TempA<(16*2+3))
			  					{
		  						v->CommData[TempA++]= ((*DataPoint)>>8)&0x00ff;
			  					v->CommData[TempA++]= (*DataPoint)&0x00ff;
			  					DataPoint++;
			  					}
			  				//写入实际数据
			  				TablePoint=MenuInfo;
			  				DataPoint=(int *)TablePoint[v->ParaNum];		
							v->CommData[29]=(*DataPoint>>8)&0xff;    //写入报文地址 
							v->CommData[30]=(*DataPoint)&0x0ff;    //写入报文地址 
							TempA=CRC_cal(v->CommData,35);   //固定长度
							v->CommData[35]=(TempA>>8)&0x00ff;		//写入CRC校验位
							v->CommData[36]=TempA&0x00ff;

							v->Index = 36;			//共计发送36个数据
							v->CommCount = 0;
							v->CommFlag = SEND_DATA;  //转入发送
							}
						break;
						//故障页读取
						case 900:			
							{
							v->CommData[2]=9*2;			//固定报文格式
							TempA=faultlog.log[v->FaultNum][0];
							DataPoint=&FaultTabA[TempA][0]; 			
							//读取PARA_TAB中的数据
							v->CommData[3]=(faultlog.log[v->FaultNum][1])>>8;	//hour hi8
							v->CommData[4]=faultlog.log[v->FaultNum][1];	//hour low8
							v->CommData[5]=(faultlog.log[v->FaultNum][2])>>8;	//minute
							v->CommData[6]=faultlog.log[v->FaultNum][2];	//secend
							v->CommData[7]=(faultlog.log[v->FaultNum][3])>>8;	//ms	hi8
							v->CommData[8]=(faultlog.log[v->FaultNum][3]);	//ms	low8
							TempA=9;
			  				while(TempA<(9*2+9))
			  					{
			  					v->CommData[TempA++]= ((*DataPoint)>>8)&0x00ff;
			  					v->CommData[TempA++]= (*DataPoint)&0x00ff;
			  					DataPoint++;
			  					}
			  				//写入实际数据
							TempA=CRC_cal(v->CommData,27);   		//固定长度
							v->CommData[27]=(TempA>>8)&0x00ff;		//写入CRC校验位
							v->CommData[28]=TempA&0x00ff;

							v->Index = 28;			//共计发送29个数据
							v->CommCount = 0;
							v->CommFlag = SEND_DATA;  //转入发送
							}
						break;
						//其他,状态页读取
						default:			
							{
							if(TempA<100)//  操作盘数据读取
								{
								v->CommFlag = WAIT_DATA_HEAD;
								}
							else if(TempA<899)	//参数读取
								{
								TablePoint=MenuInfo1;	
								TempA=TempA-100;		//相对参数页首的偏移
								if(TempA<PARA_MAX_TBL_A)
									{
									TempB=(v->CommData[4]<<8)|(v->CommData[5])-1;	//数据个数
									TempC=TempB+TempA;	//
									v->CommData[2]=TempB*2+2;
									v->Index=TempB*2+4+1;
									for(;TempB>=0;TempB--,TempC--)
										{
										DataPoint=(int *)TablePoint[TempC];
										TempA = TempB*2+4;
										v->CommData[TempA]=(*DataPoint)&0x0ff;
										TempA--;
										v->CommData[TempA]=(*DataPoint>>8)&0x0ff;
										}
									TempB=CRC_cal(v->CommData,v->Index);   //个数=标号+1;
							
									v->CommData[v->Index]=(TempB>>8)&0xff;
									v->Index++;
									v->CommData[v->Index]=TempB&0xff;
									v->CommCount = 0;
									v->CommFlag = SEND_DATA;  //转入发送
									}
								else
									{
									v->CommFlag = WAIT_DATA_HEAD;
									}	
								}
							else if(TempA<2000) //事件读取
								{
								v->CommFlag = WAIT_DATA_HEAD; 
								}	
							else if(TempA<8031) //波形记录读取
								{
								DataPoint=(int*)(0x10bbcc);
								//DataPoint[21]=1;
								//DataPoint[22]=0;

								TempA-=2001;
								TempB=(v->CommData[4]<<8)|(v->CommData[5])-1;	//数据个数
								TempC=TempB+TempA;	//
								v->CommData[2]=TempB*2+2;
								v->Index=TempB*2+4+1;
								for(;TempB>=0;TempB--,TempC--)
									{
									TempA = TempB*2+4;
									v->CommData[TempA]=DataPoint[TempC]&0x0ff;
									TempA--;
									v->CommData[TempA]=(DataPoint[TempC]>>8)&0x0ff;
									}
								TempB=CRC_cal(v->CommData,v->Index);   //个数=标号+1;
							
								v->CommData[v->Index]=(TempB>>8)&0xff;
								v->Index++;
								v->CommData[v->Index]=TempB&0xff;
								v->CommCount = 0;
								v->CommFlag = SEND_DATA;  //转入发送
								}
							else	//异常数据处理	 
								{
								v->CommFlag = WAIT_DATA_HEAD;
								}	
							}
							 	
						} //end switch3	
					}	//end switch2 case3
				break;
				//MODBUS功能16  写数据
				case 16:			
					{
					TempA=(v->CommData[2]<<8)|(v->CommData[3]);		//参数起始地址
					switch(TempA)
						{	//switch16
						case 932:
							{
							TablePoint=MenuInfo;
							DataPoint=(int *)TablePoint[v->ParaNum];	//数据地址

							*DataPoint=(v->CommData[7]<<8)+(v->CommData[8]); 

							TempB=CRC_cal(v->CommData,6);   //个数=标号+1;
							
							v->CommData[6]=(TempB>>8)&0xff;
							v->CommData[7]=TempB&0xff;
							v->Index = 7;
							v->CommCount = 0;
							v->CommFlag = SEND_DATA;  //转入发送
							}
							break;
						case 918:	//参数翻页信息处理
							{
							TempB=(v->CommData[7]<<8)+(v->CommData[8]);  
							if(TempB==2)
								{
								v->ParaNum--; 
								if(v->ParaNum < 0 )
									v->ParaNum = MENU_MAX_NUMBER_TBLA -1;
								}
							else if(TempB==1)
								{
								v->ParaNum++;
								if(v->ParaNum >= MENU_MAX_NUMBER_TBLA)
									v->ParaNum = 0;
								}
							
								TempB=CRC_cal(v->CommData,6);   //个数=标号+1;
						
								v->CommData[6]=(TempB>>8)&0xff;
								v->CommData[7]=TempB&0xff;
								v->Index = 7;
								v->CommCount = 0;
								v->CommFlag = SEND_DATA;  //转入发送
							}
						break;
						case 912:		//故障翻页信息
							{
							TempB=(v->CommData[7]<<8)+(v->CommData[8]);  
							if(TempB==2)
								{
								v->FaultNum--; 
								if(v->FaultNum < 0 )
									v->FaultNum = FAULT_LOG_MAX -1;
								}
							else if(TempB==1)
								{
								v->FaultNum++;
								if(v->FaultNum >= FAULT_LOG_MAX)
									v->FaultNum = 0;
								}
							
								TempB=CRC_cal(v->CommData,6);   //个数=标号+1;
						
								v->CommData[6]=(TempB>>8)&0xff;
								v->CommData[7]=TempB&0xff;
								v->Index = 7;
								v->CommCount = 0;
								v->CommFlag = SEND_DATA;  //转入发送
							}
						break;
						default:
							{

							if(TempA < 100)		//操作盘参数更新
								{
								v->Index = 0;
								}
							else if(TempA<900)  //参数列表内参数数据更新
								{
								TablePoint=MenuInfo1;	
//								TablePoint=MenuInfo91;
								
								TempA=TempA-100;		//相对参数页首的偏移

								TempB=(v->CommData[4]<<8)|(v->CommData[5])-1;	//数据个数
								TempC=TempB+TempA;	//数据地址
								v->Index=TempB*2+4+1;
								for(;TempB>=0;TempB--,TempC--)
									{
									DataPoint=(int *)TablePoint[TempC];
									TempA = TempB*2+7;
									//增加权限控制
									*DataPoint=(v->CommData[TempA]<<8)+v->CommData[TempA+1] ;
									}
								TempB=CRC_cal(v->CommData,6);   //个数=标号+1;
						
								v->CommData[6]=(TempB>>8)&0xff;
								v->CommData[7]=TempB&0xff;
								v->Index = 7;
								v->CommCount = 0;
								v->CommFlag = SEND_DATA;  //转入发送
							  }
							else if(TempA<=2000)
								{
								v->Index = 0;			//对事件记录部分修改无效
								}
							else if(TempA<=2021)			//
								{
								TempA=TempA-2001;		//相对页首的偏移
								TempB=(v->CommData[4]<<8)|(v->CommData[5])-1;	//数据个数
								DataPoint=(int *)(0x10bbcc+TempA);
								TempC=TempB+TempA;	//数据地址
								DataPoint=(int *)(0x10bbcc+TempC);
								v->Index=TempB*2+4+1;
								for(;TempB>=0;TempB--)
									{
									TempA = TempB*2+7;
									//增加权限控制
									*(DataPoint--)=(v->CommData[TempA]<<8)+v->CommData[TempA+1] ;
									}

								TempB=CRC_cal(v->CommData,6);   //个数=标号+1;
								v->CommData[6]=(TempB>>8)&0xff;
								v->CommData[7]=TempB&0xff;
								v->Index = 7;
								v->CommCount = 0;
								v->CommFlag = SEND_DATA;  //转入发送
								}
							else

⌨️ 快捷键说明

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