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

📄 profibus_modbus_2008.c

📁 SPC3 PROGRAMS SP C3 PROGRAMS
💻 C
📖 第 1 页 / 共 2 页
字号:
/*e : 与cdma模块通讯  f  : 与智能表通讯
modbus: 40258:本地、远动状态=0远动!=0本地
        rec[107](profibus702)=40258
如果处于远动可以写第2和第3页,否则只写第一页。
当modbus执行16命令时需要知道写的页号。执行相应的写命令。
第二页:寄存器40051至400100
第三页:寄存器40226至400250。
处于本地状态时不可以执行16命令。
profibus: send[1]=send[102]=rec[1]时发送下一页
rec[1]:高4位=发送的页号 低4位=接收的页号 */

#memmap xmem
const int num_of_mbus = 1; //定义热表数 0,1,2,3,4
const int num_of_pulse = 0; //定义水表数 0,1,2,3,4,5,6
const int num_of_energy = 1; //定义电能表数 0,1,2,3,4
//多任务定义
#define OS_MAX_TASKS       8  	// Maximum number of tasks system can create (less stat and idle tasks)
#define STACK_CNT_512		8
#define OS_TICKS_PER_SEC 	128

#define INTERFACE_RES  4 //PE4
#define INTERFACE_S_RTS  0 //PE0
#define INTERFACE_REQ_IT  1 //PE1
//串口缓冲区定义
#define DINBUFSIZE  	255
#define DOUTBUFSIZE 	255

unsigned char write_page_num;
unsigned int profibus_register[257];
unsigned int modbus_register[300];
const unsigned char comm_order[]={1,4,1,4,};
int initFlag;
unsigned char buf[112];
#use "ucos2.lib"
#use packet.lib

unsigned short CRC16(unsigned char *,unsigned short);
long SwapL1(long w1);
void pktFrx();   void pktFtx();
void pktErx();   void pktEtx();
//全局变量定义

unsigned char init_profibus_interface1(void)
{
	unsigned char i,j,sum; static unsigned char inBuf[112];
   //RABBIT先向接口板发送49个字节
	serDwrFlush();//clear Tx data buffers
   serDwrite(buf, 49);
   while(serDwrFree()<DOUTBUFSIZE);
   OSTimeDly(OS_TICKS_PER_SEC/5); //200ms
   //然后RABBIT接收接口板发送来的49个字节
   memset(inBuf,0,sizeof(inBuf));
   i=serDread(inBuf,112,1000);
	if(i==49){
  	   sum=inBuf[0];
 	   for(i=1;i<48;i++)sum+=inBuf[i];
	   printf("\nsum=%d\n",sum);
	   if(inBuf[48]==sum)
		{
		  	printf("\nRs-485 Received 49Bytes, Sum OK!\n");
		   if((inBuf[1]==0)&&(inBuf[2]==0xaa))
 		   {
			   printf("\nInit OK!\n");
			   return 1;
		   }
      }
   }
   else if(i>49)
	{
		printf("\nRs-485 Receive too much data,i=%d Error! 1:\n",i);
   }
	else
		printf("\nInit Error!\n");
   serDrdFlush();//clear Rx data buffers
	return 0;
}

void profibus_task(void *data)
{
	unsigned char R_page,W_page,page,sum,mb11,temp;
	int i,overtime;//int i,p,overtime,k;
	unsigned char send[112],rec[112];
   memset(buf,0,sizeof(buf));
   buf[0]=0x13; //站号
	buf[1]=0x06; //ID高字节
	buf[2]=0xfa; //ID低字节
	buf[3]=0x08; //I/O配置数据长度
	buf[4]=0x5f; //I/O配置数据1
	buf[5]=0x6f; //I/O配置数据2
	buf[6]=0x5f; //I/O配置数据3
	buf[7]=0x6f; //I/O配置数据4
	buf[8]=0x5f; //I/O配置数据5
	buf[9]=0x6f; //I/O配置数据6
	buf[10]=0x1d; //I/O配置数据1
	buf[11]=0x2d; //I/O配置数据2
	buf[24]=0x70; //接收数据长度
	buf[25]=0x70; //发送数据长度
	buf[26]=0x0; //用户参数数据长度
	buf[48]=buf[0];
	for(i=1;i<48;i++)buf[48]+=buf[i];

   serDopen(115200L);  	serDparity(PARAM_EPARITY);  	serDdatabits(PARAM_8BIT);
	serDwrFlush();	 serDrdFlush(); //clear Rx and Tx data buffers

   OSTimeDly(OS_TICKS_PER_SEC);
   BitWrPortI(PEDR,&PEDRShadow,1,INTERFACE_RES);
	OSTimeDly(2); //10 ms
	BitWrPortI(PEDR,&PEDRShadow,0,INTERFACE_RES);
	OSTimeDly(2);
	BitWrPortI(PEDR,&PEDRShadow,1,INTERFACE_RES);
	OSTimeDly(OS_TICKS_PER_SEC);

   if((BitRdPortI(PEDR,INTERFACE_REQ_IT)==1)	&&(BitRdPortI(PEDR,INTERFACE_S_RTS)==0))
	{
		if(init_profibus_interface1())//PROFIBUS接口板初始化,初始化后,PE1=0,PE0=0。
		{
			for(i=0;i<3;i++)
			{
				BitWrPortI(PFDR,&PFDRShadow,1,3);
				OSTimeDly(OS_TICKS_PER_SEC/2);
				BitWrPortI(PFDR,&PFDRShadow,0,3);
				OSTimeDly(OS_TICKS_PER_SEC/2);
			}
		}
		else
		{
         BitWrPortI(PFDR,&PFDRShadow,1,3);
			for(overtime=0;overtime<2;overtime++)
			{
            if(init_profibus_interface1())
				{
					for(i=0;i<3;i++)
					{
						BitWrPortI(PFDR,&PFDRShadow,1,3);
						OSTimeDly(OS_TICKS_PER_SEC/2);
						BitWrPortI(PFDR,&PFDRShadow,0,3);
						OSTimeDly(OS_TICKS_PER_SEC/2);
					}
               //initFlag=0;
					break;
				}
				else
				{
               initFlag=1;
					BitWrPortI(PFDR,&PFDRShadow,1,3);
				}
			}
		}
	}
	else
	{
		BitWrPortI(PFDR,&PFDRShadow,1,3);
		printf("\nPROFIBUS Interface not ready!\n");
      initFlag=1;
	}
   if(initFlag)assert(initFlag==200);
	OSTimeDly(OS_TICKS_PER_SEC);
	write_page_num=1;


	W_page=1;   page=0; 	mb11=0x01;	temp=0x10;	send[1]=mb11|temp;
	rec[110]=send[1];  	rec[1]=send[1];

   for(;;){

  	   if((BitRdPortI(PEDR,INTERFACE_REQ_IT)==1)	&&(BitRdPortI(PEDR,INTERFACE_S_RTS)==0))
	    	init_profibus_interface1();//PROFIBUS接口板初始化,初始化后,PE1=0,PE0=0。
//准备发送数据体1
		if(send[1]==rec[1]){
				//写页的判断:
			if(!modbus_register[257]){//远动
				if(write_page_num>3)write_page_num=1;
				if(write_page_num==2||write_page_num==3)W_page=write_page_num;
				else{
					page++;		if(page>3)page=0;
					W_page=comm_order[page];
				}
			}
			else//本地
				W_page=1;
			printf("page_num=%d",W_page);
//W_page=1;
			switch(W_page){
				case 1:
//第一页(25个4字节数据)寄存器40001至40050。
					memcpy(&send[2],&profibus_register[1],100);
					break;
				case 2:
//第二页(25个4字节数据)寄存器40051至400100。
					memcpy(&send[2],&profibus_register[51],100);
					break;
				case 3:
//第三页(25个2字节数据)寄存器40226至400250。
					memcpy(&send[2],&profibus_register[226],50);
					break;
				case 4:
//第四页(25个2字节数据,时钟)寄存器40251至400256。
					memcpy(&send[2],&profibus_register[251],14);
					break;
				}
			}
//准备发送数据体1
			R_page++;
			if(R_page>4)R_page=1;
//准备发送数据头
			mb11=0x01<<(R_page-1);
			temp=0x10<<(W_page-1);
			send[0]=0x0;//发送命令
			send[1]=mb11|temp;
			send[102]=mb11|temp;
			send[103]=0;
			for(i=1;i<103;i++)send[103]+=send[i];
//准备发送数据头
			if((BitRdPortI(PEDR,INTERFACE_REQ_IT)==0)&&(BitRdPortI(PEDR,INTERFACE_S_RTS)==0))
         {
					send[111]=send[0];
					for(i=1;i<111;i++){/*111->11*/
						send[111]+=send[i];
					}
					serDwrFlush();//clear Tx data buffers
//发送数据112Bytes.
               serDwrite(send, 112);
               while(serDwrFree()<DOUTBUFSIZE);
     				OSTimeDly(25);
               for(overtime=0; overtime<50; overtime++)
               {
					   if(serDrdUsed()>111)break;
                  OSTimeDly(4);
					}
					if(overtime<50){
                  serDread(rec,112,10);
						sum=rec[0];
						for(i=1;i<111;i++)sum=sum+rec[i];

						if(rec[111]==sum){
							//写成功判断
							if((send[1]==rec[1])&&((rec[1]>>4==2)||(rec[1]>>4==4)))
								write_page_num=1;
							switch(rec[1]&0x0f){
           					case 1:
									memcpy(&profibus_register[51],&rec[5],100);
									for(i=0;i<50;i+=2){
                             modbus_register[50+i]=profibus_register[52+i];
                             modbus_register[51+i]=profibus_register[51+i];
                           }
              					break;
           					case 2:
									if(write_page_num!=2){
                               memcpy(&profibus_register[101],&rec[5],100);
									    for(i=0;i<50;i+=2){
                                 modbus_register[100+i]=profibus_register[102+i];
                                 modbus_register[101+i]=profibus_register[101+i];
                               }
									}
              					break;
           					case 4:
									memcpy(&profibus_register[151],&rec[5],100);
                           memcpy(&modbus_register[150],&rec[5],100);
              					break;

⌨️ 快捷键说明

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