欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1881|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

PIC MODBUS從站程序

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:573529 發(fā)表于 2019-6-27 16:27 | 只看該作者 回帖獎勵 |倒序?yàn)g覽 |閱讀模式
"p18f46K80.h"
#include "MODBUS.h"
#include "EUSART1.h"
#include "EUSART2.h"
#include "delays.h"
#include "SPI.h"
#include "GM8141.h"
#define DE_485      (LATDbits.LATD4 ) //485發(fā)送控制腳宏定義
#define RE_485   (LATDbits.LATD5 ) //485接收控制腳宏定義
#define SLAVE_ADDRESS 0x01   //485從站地址宏定義
#define SLAVE_GXADDRESS 0x01   //光纖從站地址宏定義
#define no_error  0x00   //收到的幀中無
#define function_error 0x01   //功能碼不支持異常碼
#define regnum_error 0x03   //寄存器數(shù)量不支持異常碼   
#define addnum_error 0x02   //起始地址和寄存器數(shù)量異常碼
#define read_coil  0x01   //位數(shù)據(jù)的讀取
#define read_reg  0x03   //字?jǐn)?shù)據(jù)的讀取
#define write_reg  0x06   //寫一個字
#define write_regs  0x10   //寫多個字
/***********************************/
///////////////////////////////////////////////////////////////
//接收緩沖區(qū),發(fā)送緩沖區(qū),數(shù)據(jù)存儲區(qū)定義
///////////////////////////////////////////////////////////////
//#pragma udata bigdata   //7-10
// extern unsigned char    Buffer[1023];  //液晶顯示緩沖區(qū) 32*160
//#pragma udata
#pragma udata udata2     //該指令可以使receive_rc1放置于另一塊bank中
extern unsigned char receive_rc1[250]; //接收數(shù)據(jù)緩存區(qū)
#pragma udata udata3     //該指令可以使trans_tr1放置于另一塊bank中
extern unsigned char trans_tr1[250];  //發(fā)送數(shù)據(jù)緩存區(qū)
#pragma udata udata4     //該指令可以使receive_rc2放置于另一塊bank中
extern unsigned char receive_rc2[250]; //接收數(shù)據(jù)緩存區(qū)
#pragma udata udata5     //該指令可以使trans_tr2放置于另一塊bank中
extern unsigned char trans_tr2[250];  //發(fā)送數(shù)據(jù)緩存區(qū)
#pragma udata udata1
extern unsigned char  * HOLD_REG;// = &Buffer[0];//1024個字節(jié)的寄存器存儲區(qū)
extern unsigned char recdata;  //接收數(shù)據(jù)寄存器
extern unsigned char *receive_485; //485幀接收指針,指向存儲數(shù)組
extern unsigned char *receive_p;  //接收數(shù)據(jù)處理指針,指向接收數(shù)組,crc校驗(yàn)用
unsigned short crc;
extern unsigned char receive_num,trans_num;//接收到的數(shù)據(jù)個數(shù),發(fā)送數(shù)據(jù)個數(shù)
unsigned char    delet_rc1,delet_rc2; //清除幀接收緩存器時用的計數(shù)單元
extern unsigned char *receive_p;
unsigned char error_kind;      //檢測錯誤碼的類型,get_frame_error()程序中用
unsigned int  start_addr,reg_num;    //收到的幀中的寄存器地址和寄存器數(shù)目存儲單元。兩個字節(jié)int型
unsigned char trans_frame_num;    //發(fā)送幀中的個數(shù)
unsigned int   heart_beat,heart_beat2,heart_beat3;   //每收到一次指令 heart_beat+1  在00 01和02 03字節(jié)上顯示出來
//////////////光纖MODBUS用數(shù)據(jù)//////////////////////////////////////////////////
extern unsigned char gxreceive_num,gxtrans_num;//接收到的數(shù)據(jù)個數(shù),發(fā)送數(shù)據(jù)個數(shù)
extern unsigned char *receive_gx;
unsigned char  GXtrans_frame_num;
extern unsigned int read_int;
////////////////////////////////////////////////////////////////////////////////
extern struct {
  unsigned  CAN_FLAG:    1; //CAN標(biāo)志位
  unsigned  RXB0_FLAG:     1;
  unsigned  RXB1_FLAG:     1;
  unsigned  TX1_FLAG:      1; //EUSART標(biāo)志位
  unsigned  RX1_FLAG:      1;
  unsigned  parity_FLAG:   1;//偶校驗(yàn)標(biāo)志位
  unsigned  MOD485_FLAG: 1;//485端口的MODBUS幀接收完成標(biāo)志位,主程序和定時0中斷處理
  unsigned  MOD485_ERROR: 1;//485端口幀偶校驗(yàn)或crc校驗(yàn)錯誤
} FLAG1bits;//定義
extern struct {
  unsigned  RX2:    1;//EUSART2 RECEIVE   INTERRUPT FLAG
  unsigned  TX2:     1;//EUSART2 TRANSLATE INTERRUPT FLAG
  unsigned  TIME2:     1;//
  unsigned  MODGX_ERROR:      1;//
  unsigned  FLAG4:      1;//
  unsigned  FLAG5:   1;//
  unsigned  FLAG6:  1;//
  unsigned  FLAG7:  1;//
} FLAG3bits;//定義
/* CRC 高位字節(jié)值表 */   
   rom unsigned char auchCRCHi[256] = {  
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,   
    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,   
    0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,   
    0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,   
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,   
    0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,   
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,   
    0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,   
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,   
    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,   
    0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,   
    0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,   
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,   
    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,   
    0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,   
    0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,   
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,   
    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,   
    0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,   
    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,   
    0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,   
    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,   
    0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,   
    0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,   
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,   
    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40  
    };   
      
  rom  unsigned char auchCRCLo[256] = {  
    0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,   
    0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,   
    0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,   
    0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,   
    0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,   
    0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,   
    0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,   
    0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,   
    0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,   
    0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,   
    0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,   
    0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,   
    0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,   
    0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,   
    0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,   
    0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,   
    0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,   
    0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,   
    0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,   
    0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,   
    0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,   
    0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,   
    0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,   
    0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,   
    0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,   
    0x43, 0x83, 0x41, 0x81, 0x80, 0x40  
    };  
// ****************************************************************
// 函 數(shù) 名: getparity(unchar parity_target)
// 功能描述: 對parity_target的8位依次進(jìn)行相加,考察結(jié)果的奇偶性
//    偶數(shù):FLAG1bits.parity_FLAG為0,奇數(shù):為1
//*****************************************************************
void getparity(uchar target)
{
uchar parity_i,parity_temp,parity;
parity=target;
for(parity_i=0,parity_temp=0;parity_i<8;parity_i++)
{
  if(parity & 0x01)
  parity_temp++;
  parity>>=1;
}
if(parity_temp%2==0)
  FLAG1bits.parity_FLAG=0; //偶數(shù)個“1”返回0
else
  FLAG1bits.parity_FLAG=1; //奇數(shù)個“1”返回1
}
/*********************************************************************************/  
/*函數(shù)名稱: GetCRC16()                           
*輸入?yún)?shù):  共  個參數(shù);  
*輸出參數(shù):  共  個參數(shù);  
*返回值:   
*需儲存的參數(shù): 共  個參數(shù);      
*功能介紹:(1)CRC16校驗(yàn); 返回校驗(yàn)碼;                                               
/*                                      */  
/*********************************************************************************/  
  
unsigned short GetCRC16(unsigned char *puchMsg, unsigned char usDataLen)   
{   
    unsigned char uchCRCHi = 0xFF ; /* 高CRC字節(jié)初始化 */   
    unsigned char uchCRCLo = 0xFF ; /* 低CRC 字節(jié)初始化 */   
    unsigned uIndex = 0; /* CRC循環(huán)中的索引 */   
      
    while (usDataLen--) /* 傳輸消息緩沖區(qū) */   
    {   
        uIndex = uchCRCHi ^ *puchMsg++ ; /* 計算CRC */   
        uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex] ;   
        uchCRCLo = auchCRCLo[uIndex] ;   
    }   
    return (unsigned short)((unsigned short)uchCRCHi << 8 | uchCRCLo) ;   
}   
/*****************************************************************************/
//MODBUS_RTU函數(shù),功能實(shí)現(xiàn)MODBUS——RTU協(xié)議
/*****************************************************************************/  
void MODBUS_RTU(void)
{
   
   if(FLAG1bits.MOD485_ERROR==0)   //判斷偶校驗(yàn)是否錯誤
   {
    //receive_p=&receive_rc1[0];
    crc=GetCRC16(&receive_rc1[0],receive_num);
    if(crc!=0)       //判斷crc校驗(yàn)是否錯誤
    {
     FLAG1bits.MOD485_ERROR=1;      
    }
   }
   
   if(FLAG1bits.MOD485_ERROR==0)
   {
    LATBbits.LATB4=~LATBbits.LATB4; //小燈閃爍
    if(receive_rc1[0]==SLAVE_ADDRESS) //判斷從站地址是否相符,不符合不操作
    {
     error_kind=get_frame_error();   //判斷是否有異常碼
     switch(error_kind)
     {
      case no_error:  rtu_data();//support_function(); //無異常碼情況下執(zhí)行RTU操作函數(shù)
        break;
      case function_error: unsupport_function();   //功能異常碼 執(zhí)行功能異常返回函數(shù)
        break;
      case regnum_error: unsupport_regnum();    //寄存器數(shù)量異常,執(zhí)行異常返回函數(shù)
        break;
      case addnum_error: unsupport_addnum();    //地址和數(shù)量異常,執(zhí)行異常返回函數(shù)
        break;
      default : break;
      
     }     
    }
   
   
    for(delet_rc1=0;delet_rc1<receive_num;delet_rc1++)
    {       //幀接受暫存器清零
     receive_rc1[delet_rc1]=0;
    }
    receive_num=0;    //發(fā)送完成后接受個數(shù)清零,等待下一幀
    trans_num=0;    //發(fā)送完成后發(fā)送個數(shù)清零,等待下一幀
   }
   if(FLAG1bits.MOD485_ERROR==1)   //偶校驗(yàn)錯誤或crc校驗(yàn)錯誤,清除各個數(shù)據(jù),等待下一幀
   {
    receive_num=0;
    trans_num=0;
    FLAG1bits.MOD485_ERROR=0;
    /******************************************************
     //測試用心跳函數(shù),CRC校驗(yàn)失
    /************************/
   
   }     
}
/************************************************
*****發(fā)送幀函數(shù),入口參數(shù):幀中字節(jié)數(shù)目,發(fā)送trans_tr1數(shù)組中的數(shù)據(jù)**********
************************************************/
void trans_frame(/*unsigned char *trans_frame,*/unsigned char trans_num1)
{
  RE_485=1;     //禁止485的接收功能
  DE_485=1;     //使能485的發(fā)送功能  
  
  for(trans_num=0;trans_num<trans_num1;trans_num++)
  {
   getparity(trans_tr1[trans_num]); //進(jìn)行偶校驗(yàn)
   TXSTA1bits.TX9D1=FLAG1bits.parity_FLAG;//偶校驗(yàn)結(jié)果放入第九位
   TXREG1=trans_tr1[trans_num];  //返送接收到的數(shù)據(jù)
   //receive_rc1[trans_num]=0;   // ***發(fā)送完后清零****/
            ///////////調(diào)試用/////
   while(TXSTA1bits.TRMT1==0);   //等待數(shù)據(jù)發(fā)送完畢
  }
  
  DE_485=0;  
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表