📄 profibus_modbus_2008.c
字号:
/*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 + -