?? profibus_modbus_2008.c
字號:
/*e : 與cdma模塊通訊 f : 與智能表通訊
modbus: 40258:本地、遠動狀態=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 + -