F103 modbus TCP

Dependencies:   BufferedSerial BufferedSoftSerial CRC16 Nucleo_F103RB_W5500HelloWorld MessageQueue WIZnet_Library Watchdog eeprom mbed-rtos mbed

Fork of Nucleo_F103RB_W5500HelloWorld by WIZnet

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "WIZnetInterface.h"
00003 #include <string>
00004 #include "Serial.h"
00005 #include "eeprom.h"
00006 #include "CRC16.h"
00007 #include "Watchdog.h"
00008 #include "rtos.h"
00009 //Serial mdb232(PA_9,PA_10);
00010 //Serial mdb485(PA_2,PA_3);
00011 Serial *pc;//
00012 DigitalOut pcSendRev(PB_0);//0 rev  1 send
00013 Watchdog wd;
00014 bool reset_soft = false;// 控制停止喂狗使设备复位
00015 struct CONFIG{
00016     char ipAddr[16];
00017     char ipSubnet[16];
00018     char ipGateway[16];
00019     int16_t port;
00020     unsigned char MAC_Addr[6] ;
00021     
00022     int8_t RTUChoice;       //1:RTU模式 0:ascii
00023     int8_t bits;            //5-8bit
00024     SerialBase::Parity parity;        //  SerialBase::Odd , SerialBase::Even  SerialBase::None    分别用int 1,2,3代表
00025     int8_t stop_bits;       //1-2bit
00026     int16_t baud;
00027     int16_t frameTimeOut;
00028     int16_t timeOut;
00029     int16_t RS  ;              //485 232
00030     }Config_t = {             //默认值
00031         "192.168.31.3",
00032         "255.255.255.0",
00033         "192.168.31.1",
00034         (int16_t)502,       //port
00035         {0x00,0x08,0xDC,0x12,0x34,0x56},//mac地址
00036         1,                  //choice RTU mode
00037         8,                  //数据位8位
00038         SerialBase::None,
00039         1,                  //stop
00040         (int16_t)19200,      //baud
00041         7 ,                  //帧超时7ms
00042         1500  ,                 //等待超时1500ms
00043         485
00044         }; 
00045 CONFIG Config = Config_t;//备份一个配置信息。         
00046 static  char buffer[256] ;           //接收或者发送用的临时buffer
00047 uint16_t buffer_num = 6;
00048 struct TCP_BUFFER{          //
00049     char xid[2];
00050     char pid[2];
00051     int16_t length;
00052     char serialAddr;
00053     char data[255];
00054     }tcp_buffer;
00055     
00056 struct SERIAL_BUFFER{
00057     char serialAddr;        //地址
00058     char funCode;           //功能码
00059     char data[252];
00060     char crc[2];            //低位前高位后
00061     }serial_buffer;
00062     
00063 enum flagThread1{
00064     waitThead1,
00065     connectedThead1,
00066     tcpRecvThead1,
00067     serialRecvThead1,
00068     tcpSendThead1
00069     }flagThread1;            //状态机标识  thread1
00070     
00071 enum FlagThead2{
00072      waitThead2,
00073      connectedThead2,
00074      handleDataThead2,
00075      getReguestThead2,
00076      postReguestThead2
00077      }flagThread2;           //状态机标识 thread2
00078 char readline[200];    //解析提交的表单 读取一行数据 再存在这 
00079 SPI spi(PA_7, PA_6, PA_5); // mosi, miso, sclk
00080 WIZnetInterface ethernet(&spi, PB_6, PB_7);//scs(PB_6), nRESET(PB_7); // reset pin is dummy, don't affect any pin of WIZ550io
00081 EEPROM memory(I2C_SDA,I2C_SCL,0,EEPROM::T24C02);     
00082    
00083 TCPSocketServer webserver;
00084 TCPSocketConnection webclient;
00085 TCPSocketServer server;
00086 TCPSocketConnection client;  
00087 int rev_num;//tcp收到的直接数     
00088   
00089 /*****************************计算超时用到的函数及变量*************************************************/
00090 bool flagT35 = false; //是否接受了串口数据标志  ture 接收到串口数据
00091 Timer timeout; //1s 超时
00092 Timer timeoutT35;//t3.5超时
00093 void timeoutTest();    //串口中断服务程序
00094 
00095 /*********************状态机处理函数*************************************/
00096 
00097 void InitDefault(void);
00098 void InitEEprom(void);
00099 
00100 
00101 void TcpRecvThead1(void);
00102 void SerialRecvThead1(void);
00103 void TcpSendThead1(void);
00104 
00105 int webclientReadline();
00106 int readSubmit( char *d,char a);
00107 void webServerHandleData (void const *args)
00108 {
00109     string sbuffer;
00110     char *cbuffer = new char[100];
00111     int numRev;
00112     string sget = "GET";
00113     string spost = "POST";
00114     while(true) {
00115         Thread::signal_wait(0x2);
00116         if ( flagThread2 ==  handleDataThead2 ) {
00117             sbuffer.clear();
00118             numRev= webclient.receive(cbuffer,3);
00119             if (numRev == 3) {
00120                 sbuffer.append(cbuffer,3);
00121                 if (sbuffer == sget) {
00122                     printf("get\r\n");
00123                     flagThread2 = getReguestThead2;
00124                     do {
00125                         numRev = webclient.receive(cbuffer,100);
00126                     } while(numRev == 100) ;
00127                 }//清空rev buffer
00128                 else {
00129                     webclient.receive(cbuffer,1);
00130                     sbuffer.append(cbuffer,1);
00131                     if(sbuffer == spost) {
00132                         printf("post\r\n");
00133                         flagThread2 = postReguestThead2;
00134                     } else {
00135                         printf("no\r\n");
00136                         flagThread2 = waitThead2;
00137                         webclient.close();
00138                     }
00139                 }
00140             } else
00141                 flagThread2 = waitThead2;
00142         }
00143     }
00144 }
00145 
00146 void webServerGetReguest(void const *args)
00147 {
00148     string sbuffer;
00149     char str[10];
00150     sbuffer.assign("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n");
00151     sbuffer.append("Connection: close\r\n\r\n<!DOCTYPE HTML>\r\n");
00152     sbuffer.append("<html>\r\n<form id = \"muForm\"action=\"/config\"method=\"post\">\r\n");
00153     sbuffer.append("<table id=\"attfile\">\r\n<tr><td>NETWORK</td></tr>");
00154 
00155     sbuffer.append("<tr><td>IP</td>\r\n<td><input type=\"text\"name=\"IP\"size=\"20\"value=\"");
00156     sbuffer.append(ethernet.getIPAddress());
00157     sbuffer.append("\"></td><td> e.g. 192.168.1.55</td></tr>");
00158 
00159     sbuffer.append("<tr><td>MASK</td><td><input type=\"text\" name=\"MASK\" size=\"20\"value=\"");
00160     sbuffer.append(Config.ipSubnet);
00161     sbuffer.append("\"></td><td> e.g. 255.255.255.0</td></tr>");
00162 
00163     sbuffer.append("<tr><td>gateway</td> <td><input type=\"text\" name=\"gateway\" size=\"20\"value=\"");
00164     sbuffer.append(Config.ipGateway);
00165     sbuffer.append("\"></td><td> e.g. 192.168.1.1</td></tr>");
00166 
00167     sbuffer.append("<tr><td>PORT</td> <td><input type=\"text\" name=\"PORT\" size=\"20\"value=\"");
00168     sprintf(str,"%d",Config.port);
00169     sbuffer.append(str);
00170     sbuffer.append("\"></td><td> e.g. 502</td></tr>");
00171 
00172     sprintf(str,"%d",Config.baud);
00173     sbuffer.append("<tr><td>Serial</td> </tr><tr><td>baud</td> <td><input type=\"text\" name=\"baud\"size=\"20\"value=\"");
00174     sbuffer.append(str);
00175     sbuffer.append("\"></td><td> e.g. 115200 19200 9600</td> </tr>");
00176 
00177 
00178     sbuffer.append("<tr><td>parity</td> <td><input type=\"text\"name=\"parity\"size=\"20\"value=\"");
00179     switch(Config.parity) {
00180         case SerialBase::Odd:
00181             sbuffer.append("odd");
00182             break;
00183         case SerialBase::Even:
00184             sbuffer.append("even");
00185             break;
00186         case SerialBase::None:
00187             sbuffer.append("none");
00188             break;
00189     }
00190 
00191     sbuffer.append("\"></td><td> e.g. none even odd</td> </tr>");
00192 
00193     sbuffer.append("<tr><td>bits</td> <td><input type=\"text\"name=\"bits\"size=\"20\"value=\"");
00194     int t;
00195     if(Config.parity != SerialBase::None)
00196        t = Config.bits -1;
00197     else 
00198         t=Config.bits;
00199     sprintf(str,"%d",t);
00200     sbuffer.append(str);
00201     sbuffer.append("\"></td><td> e.g. 7-8</td> </tr>");
00202     
00203     
00204     sbuffer.append("<tr><td>stop_bits</td> <td><input type=\"text\"name=\"stop_bits\"size=\"20\"value=\"");
00205     sprintf(str,"%d",Config.stop_bits);
00206     sbuffer.append(str);
00207     sbuffer.append("\"></td><td> e.g. 1-2</td> </tr>");
00208 
00209     sbuffer.append("<tr><td>The frame timeout</td> <td><input type=\"text\"name=\"t35\"size=\"20\"value=\"");
00210     sprintf(str,"%d",Config.frameTimeOut);
00211     sbuffer.append(str);
00212     sbuffer.append("\"></td><td> ms</td> </tr>");
00213 
00214     sbuffer.append("<tr><td>timeout</td> <td><input type=\"text\"name=\"timeout\"size=\"20\"value=\"");
00215     sprintf(str,"%d",Config.timeOut);
00216     sbuffer.append(str);
00217     sbuffer.append("\"></td><td> ms</td></tr>");
00218 
00219     sbuffer.append("<tr><td>232 or 485</td> <td><input type=\"text\" name=\"232or485\" size=\"20\"value=\"");
00220     sprintf(str,"%d",Config.RS);
00221     sbuffer.append(str);
00222     sbuffer.append("\"></td><td> e.g. 232 485</td> </tr>");
00223 
00224     sbuffer.append("</table><input type = \"button\"onclick= \"formSubmit()\" value=\"submit\">");
00225     sbuffer.append("</form><script type=\"text/javascript\">");
00226 
00227     sbuffer.append("function formSubmit()");
00228     sbuffer.append("{document.getElementById(\"muForm\").submit()}");
00229     sbuffer.append("</script></html>");
00230 
00231     while(true) {
00232         Thread::signal_wait(0x3);
00233         if(flagThread2 == getReguestThead2 ) {
00234             webclient.send_all((char *)sbuffer.c_str(),sbuffer.length());
00235             webclient.close();
00236             flagThread2 = waitThead2;
00237         }
00238     }
00239 }
00240 
00241 
00242 void modbus_tcp_rs(void const *args)
00243 {
00244     while(true) {
00245 
00246        if(flagThread1 == connectedThead1) {
00247             
00248 
00249           
00250             pcSendRev = 1;//send
00251             rev_num = client.receive(buffer,6);
00252           
00253             if(rev_num == 6) {
00254                 //   client.send_all("connectedThead1",15);
00255                 tcp_buffer.xid[0] =  buffer[0];
00256                 tcp_buffer.xid[1] =  buffer[1];
00257                 tcp_buffer.pid[0] =  buffer[2];
00258                 tcp_buffer.pid[1] =  buffer[3];
00259                 tcp_buffer.length =  buffer[4];
00260                 tcp_buffer.length =  tcp_buffer.length <<8;
00261                 tcp_buffer.length =  tcp_buffer.length | buffer[5];
00262                 rev_num = client.receive(buffer,tcp_buffer.length);
00263                 tcp_buffer.serialAddr =  buffer[0];
00264                 if (rev_num == tcp_buffer.length){
00265                     TcpRecvThead1(); //处理tcp接收到的数据包 串口发送出去
00266                     SerialRecvThead1();//等待接收串口数据
00267                     if(flagThread1 == tcpSendThead1){
00268                         tcp_buffer.length = buffer_num-8;//前面空了6个 后面2个crc去掉
00269                         buffer[0] = tcp_buffer.xid[0];
00270                         buffer[1] = tcp_buffer.xid[1];
00271                         buffer[2] = tcp_buffer.pid[0];
00272                         buffer[3] = tcp_buffer.pid[1];
00273                         buffer[4] = tcp_buffer.length>>8 & 0xff;
00274                         buffer[5] = tcp_buffer.length & 0xff;
00275                         client.send_all(buffer,buffer_num-2);//打包发送 mdb tcp
00276                         flagThread1 = connectedThead1;
00277                     }  
00278                 }
00279             }
00280        }
00281      Thread::wait(200);
00282     }
00283 }
00284 
00285 
00286 void webServerPost(void const *args)
00287 {   string spost;
00288     char str[10];
00289     spost.assign("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n");
00290     spost.append("Connection: close\r\n\r\n<!DOCTYPE HTML>\r\n");
00291     spost.append("<html>reset now!! Remember !!! IP:");
00292     
00293     while(1) {
00294         Thread::signal_wait(0x05);
00295         if(flagThread2 == postReguestThead2) {
00296          //-----------读取表单参数--------------------------   
00297            
00298             while(webclientReadline());//返回 0 结束  后面的就是提交的表单内容 ip=192.168.1.3....
00299             
00300             readSubmit(readline,'=');//"IP"之类的  
00301                   
00302             readSubmit(Config.ipAddr,'&');                                                                                    
00303             readSubmit(readline,'=');//"mask"之类的            
00304             readSubmit(Config.ipSubnet,'&');
00305             readSubmit(readline,'=');//"gateway"之类的          
00306             readSubmit(Config.ipGateway,'&');
00307             readSubmit(readline,'=');//"PORT"
00308             readSubmit(readline,'&');           
00309             Config.port= (int16_t)atoi(readline);            
00310             readSubmit(readline,'=');//"baud"
00311             readSubmit(readline,'&');
00312             Config.baud= (int16_t)atoi(readline);    
00313             readSubmit(readline,'=');//"parity"           
00314             readSubmit(readline,'&');
00315             string s = readline;            
00316             if(s == "none" )
00317             Config.parity= SerialBase::None;
00318             if(s == "even" )
00319             Config.parity= SerialBase::Even;
00320             if(s == "odd" )
00321             Config.parity= SerialBase::Odd;
00322             readSubmit(readline,'=');//"bits"
00323             readSubmit(readline,'&');    
00324             Config.bits= (int8_t)atoi(readline);
00325             readSubmit(readline,'=');//"stop_bits"
00326             readSubmit(readline,'&');    
00327             Config.stop_bits= (int8_t)atoi(readline);   
00328             readSubmit(readline,'=');//"T35"
00329             readSubmit(readline,'&');     
00330             Config.frameTimeOut= (int16_t)atoi(readline);  
00331             readSubmit(readline,'=');//"timeout"
00332             readSubmit(readline,'&');     
00333             Config.timeOut= (int16_t)atoi(readline); 
00334             readSubmit(readline,'=');//"232or485"
00335             readSubmit(readline,'&');     
00336             Config.RS= (int16_t)atoi(readline); 
00337     
00338 
00339 //--------------------发送更新后的 页面 ip port-----------------            
00340             spost.append(Config.ipAddr);            
00341             spost.append("    PORT:");
00342             sprintf(str,"%d",Config.port);
00343             spost.append(str);
00344             spost.append("</html>");
00345             webclient.send_all((char *)spost.c_str(),spost.length());
00346             webclient.close();
00347             
00348        //---------- 存进eeprom 参数-----------------------
00349           
00350           memory.write(1,0xaa);
00351           wait_ms(2);
00352           memory.write(32,Config.ipAddr,8);
00353           
00354           wait_ms(2);
00355           memory.write(40,Config.ipAddr+8,8);
00356           wait_ms(2);
00357           memory.write(48,Config.ipSubnet,8);
00358           wait_ms(2);
00359           memory.write(56,Config.ipSubnet+8,8);
00360           wait_ms(2);
00361           memory.write(64,Config.ipGateway,8);
00362           wait_ms(2);
00363           memory.write(72,Config.ipGateway+8,8);
00364           wait_ms(2);          
00365           memory.write(80,Config.MAC_Addr,6);
00366           wait_ms(2);
00367           memory.write(2,Config.port);
00368           wait_ms(2);
00369          
00370           memory.write(7,Config.bits);
00371           wait_ms(2);
00372           if(Config.parity == SerialBase::Odd)           
00373           memory.write(4,int8_t(1));
00374           if(Config.parity == SerialBase::Even)
00375           memory.write(4,int8_t(2));
00376           if(Config.parity == SerialBase::None)
00377           memory.write(4,int8_t(3)); 
00378           wait_ms(2);        
00379           memory.write(8,Config.stop_bits);
00380           wait_ms(2);
00381           memory.write(5,Config.baud); 
00382           wait_ms(2);
00383           memory.write(10,Config.RS); 
00384           wait_ms(2);
00385           //memory.write(12,Config.frameTimeOut); 
00386          // wait_ms(2);
00387           memory.write(14,Config.timeOut);          
00388           flagThread2 = waitThead2;         
00389           reset_soft = true; //复位
00390                
00391 
00392        } 
00393     }
00394 }
00395 
00396 //----------------- 以特殊字符结尾的字符串-----------
00397 int readSubmit(char *d,char a)
00398 {
00399     int num = 0;
00400     while(1) {
00401         //截取 等号 & 前的字符串
00402 
00403         if(-1 == webclient.receive(&d[num],1)) {
00404             d[num] = '\0';
00405             return num;
00406         }
00407         if(d[num] != a)
00408             num++;
00409         else {
00410             d[num] = '\0';
00411             return num;
00412         }
00413 
00414     }
00415 }
00416 
00417 
00418 
00419 
00420 
00421 
00422 
00423 
00424 //----------返回一行的字节数--------------
00425 int webclientReadline()
00426 {
00427     int num=0;
00428     while(1) {
00429         if( -1 == webclient.receive(&readline[num],1))
00430             return -1;
00431         if (readline[num] != '\r') 
00432         num++;
00433         else {
00434             if(-1 == webclient.receive(&readline[num],1))
00435                 return -1;
00436             if (readline[num] == '\n') ;
00437             return num;
00438         }
00439     }
00440 }
00441 
00442 
00443 
00444 
00445 //--------------喂狗-----------------------
00446 
00447 void wd_server(void const *args) {   
00448     while(true){
00449     if (!reset_soft)
00450             wd.Service();
00451      Thread::wait(2000);       
00452             }
00453 }
00454 
00455 
00456 int main() {
00457     int16_t t232or485 =0;
00458     memory.read(10,t232or485);
00459     wait_ms(1);
00460     
00461     if ((uint16_t)t232or485 == (uint16_t)232)
00462         pc = new Serial(PA_9,PA_10);//232
00463     else 
00464         pc = new Serial(PA_2,PA_3); //485
00465         
00466     pcSendRev = 1;//send
00467     if(wd.WatchdogCausedReset())
00468         printf("Watchdog caused reset.\r\n");
00469     int8_t initChoice;
00470     memory.read(1,initChoice); //查看一下eeprom是否初始化
00471     wait_ms(1);
00472     printf("%d",t232or485);
00473     printf("int:%c\r\n",initChoice);
00474     if( 0xAA == (uint8_t)initChoice )//已经初始化
00475         {printf("aa\r\n");
00476         InitEEprom();}
00477     else
00478         InitDefault();  
00479     
00480  //------------listen 502  80  -----------
00481     
00482     server.bind(Config.port);   //502
00483     server.listen();
00484     server.set_blocking(false, 0);
00485     webserver.bind(80);
00486     webserver.listen();
00487     webserver.set_blocking(false, 0);
00488     client.set_blocking(false, 0); // Timeout=0.
00489     webclient.set_blocking(false, 0);
00490     flagThread1 = waitThead1;   //状态机 初状态
00491     flagThread2 = waitThead2;
00492     wd.Configure(4);       // sets the timeout interval 大约6.1s    
00493     //Thread thread1(wd_server) ;
00494     
00495     //---------------thread 开启 -----------------
00496     Thread thread2(webServerHandleData,(void *)"2",osPriorityHigh );
00497     Thread thread3(webServerGetReguest,(void *)"3",osPriorityHigh );
00498     Thread thread4(modbus_tcp_rs,(void *)"4",osPriorityAboveNormal);
00499     Thread thread5(webServerPost,(void *)"5",osPriorityRealtime );
00500     
00501      //-----------对线程管理----------socket accept-----
00502     while(1) {
00503         if (client.is_fin_received()) {
00504             client.close();
00505             flagThread1 = waitThead1;
00506         }
00507         if(flagThread1 == waitThead1) {
00508             server.accept(client);
00509             if((client.is_connected() == true)  ) {
00510                 flagThread1 = connectedThead1;
00511             }
00512         }
00513         if (!reset_soft)
00514             wd.Service();
00515         Thread::wait(50);
00516         if(webclient.is_fin_received()) {
00517             webclient.close();
00518             flagThread2 = waitThead2;
00519         }
00520 
00521         if(flagThread2 == waitThead2) {
00522             webserver.accept(webclient);
00523             if((webclient.is_connected() == true)  ) {
00524                 flagThread2 = handleDataThead2;
00525                 thread2.signal_set(0x2);      //启动线程2 给他一个signal
00526             }
00527         }
00528 
00529         if (flagThread2 == getReguestThead2)
00530             thread3.signal_set(0x3);          //启动线程3 给他一个signal
00531         if(flagThread2 == postReguestThead2)
00532             thread5.signal_set(0x5);
00533         if (!reset_soft)
00534             wd.Service();   
00535         Thread::wait(50);
00536 
00537 
00538    
00539     }
00540 }
00541 
00542 void InitDefault(void)
00543 {   pc->format(Config.bits,Config.parity,Config.stop_bits);
00544     pc->baud(Config.baud);
00545     int ret = ethernet.init(Config.MAC_Addr,Config.ipAddr,Config.ipSubnet,Config.ipGateway);
00546     if (!ret) {
00547         printf("Initialized, MAC: %s\r\n", ethernet.getMACAddress());
00548         ret = ethernet.connect();
00549         if (!ret) {
00550             printf("IP: %s, MASK: %s, GW: %s\r\n",
00551             ethernet.getIPAddress(), ethernet.getNetworkMask(), ethernet.getGateway());
00552             } else {
00553                 printf("Error ethernet.connect() - ret = %d\r\n", ret);
00554                 exit(0);
00555             }
00556         } else {
00557             printf("Error ethernet.init() - ret = %d\r\n", ret);
00558             exit(0);
00559         }
00560 
00561     pc->attach(&timeoutTest);
00562     }
00563 
00564 
00565 void InitEEprom(void)
00566 {
00567   
00568   int8_t t;
00569   memory.read(32,Config.ipAddr,16);
00570   wait_ms(2);
00571   memory.read(48,Config.ipSubnet,16);
00572   wait_ms(2);
00573   memory.read(64,Config.ipGateway,16);
00574   wait_ms(2);
00575   memory.read(80,Config.MAC_Addr,6);
00576   wait_ms(2);
00577   memory.read(2,Config.port);
00578   wait_ms(2);
00579   memory.read(7,Config.bits);
00580   wait_ms(2);
00581   memory.read(4,t);
00582     if( t==1 )
00583         Config.parity = SerialBase::Odd;
00584     if( t==2 )
00585         Config.parity = SerialBase::Even;
00586     if(t == 3)
00587         Config.parity = SerialBase::None;
00588     wait_ms(2);
00589   memory.read(8,Config.stop_bits);
00590   wait_ms(2);
00591   memory.read(5,Config.baud);
00592   wait_ms(2);
00593   memory.read(10,Config.RS);
00594   wait_ms(2);
00595  // memory.read(12,Config.frameTimeOut);
00596  // wait_ms(2);
00597   memory.read(14,Config.timeOut);
00598   wait_ms(2);
00599   InitDefault();
00600     }
00601 
00602     
00603 
00604 void TcpRecvThead1(void)
00605 {
00606     static CRC16 crc16;
00607     int16_t crc;
00608     crc = crc16.calculateCRC16(buffer,tcp_buffer.length);
00609     buffer[tcp_buffer.length+1] = crc & 0xff;
00610     buffer[tcp_buffer.length] = (crc >> 8) & 0xff;
00611 
00612    for (crc =0 ; crc<tcp_buffer.length+2;crc++)
00613         pc->putc(buffer[crc]);
00614  
00615    
00616     
00617     flagThread1 = serialRecvThead1;
00618     buffer_num = 6;
00619     timeout.start();        //开启1s 超时
00620     
00621     timeoutT35.start();
00622     wait_ms(3);
00623     }
00624 
00625 void SerialRecvThead1(void)
00626 {
00627     static int j = 0;
00628     //char t;
00629     static CRC16 crc16;
00630     int16_t crc;
00631     pcSendRev = 0;//Rev
00632     while(flagThread1 == serialRecvThead1) {
00633         if( Config.timeOut < timeout.read_ms() ) {
00634             pcSendRev = 1;//Send
00635             timeout.reset();
00636             timeout.stop();
00637             timeoutT35.reset();
00638             timeoutT35.stop();
00639             flagThread1 =  connectedThead1;
00640           /*  buffer[7] = buffer[1]|0x80;   //存的功能码 上一步
00641             buffer[0] = tcp_buffer.xid[0];
00642             buffer[1] = tcp_buffer.xid[1];
00643             buffer[2] = tcp_buffer.pid[0];
00644             buffer[3] = tcp_buffer.pid[1];
00645             buffer[4] = 0x0;
00646             buffer[5] = 0x3;
00647             buffer[6] = tcp_buffer.serialAddr;
00648             buffer[8] = 0x4;
00649             client.send_all(buffer,9);//报错
00650             */
00651         }
00652         if( Config.frameTimeOut < timeoutT35.read_ms() && flagT35 ) { // 一帧数据结束 7ms超时
00653             timeoutT35.reset();
00654             timeoutT35.stop();
00655             flagT35 = false;
00656             //      t = buffer[buffer_num-1];buffer[buffer_num-1]=buffer[buffer_num-2];buffer[buffer_num-2]=t;
00657             crc = crc16.calculateCRC16(buffer+6,buffer_num-6) ;  //为0没有crc错误
00658             if (!crc ) {    //无crc 提取mdb帧数据
00659                 serial_buffer.serialAddr = buffer[6];
00660                 serial_buffer.funCode = buffer[7];
00661                 for(j = 0; j < buffer_num-4 ; j++)
00662                     serial_buffer.data[j] = buffer[j+8];
00663                 serial_buffer.crc[0] = buffer[buffer_num-2];
00664                 serial_buffer.crc[1] = buffer[buffer_num-1];
00665                 //   buffer_num = 0;//提取完一帧数据 计数清零
00666                 flagThread1 =  tcpSendThead1;   //进入下一个状态
00667             } else          //有crc 错误
00668                 flagThread1 =  connectedThead1;
00669         }
00670     }
00671 }
00672 
00673 void timeoutTest()  //串口中断
00674 {
00675     if(flagThread1 !=serialRecvThead1)
00676         buffer[245]=pc->getc();//丢弃串口数据包
00677     else {
00678         buffer[buffer_num++] = pc->getc();
00679         flagT35  = true ;      //标志已经接收到串口数据
00680         timeoutT35.reset();  //重新及时只看最后一个接受的字符之后的时间 总线空闲检测
00681         timeout.stop();
00682     }     //1s接受超时停止计时
00683 
00684 }