久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1765|回復: 0
打印 上一主題 下一主題
收起左側

PIC MODBUS從站程序

[復制鏈接]
跳轉到指定樓層
樓主
ID:573529 發表于 2019-6-27 16:27 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
"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發送控制腳宏定義
#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   //寄存器數量不支持異常碼   
#define addnum_error 0x02   //起始地址和寄存器數量異常碼
#define read_coil  0x01   //位數據的讀取
#define read_reg  0x03   //字數據的讀取
#define write_reg  0x06   //寫一個字
#define write_regs  0x10   //寫多個字
/***********************************/
///////////////////////////////////////////////////////////////
//接收緩沖區,發送緩沖區,數據存儲區定義
///////////////////////////////////////////////////////////////
//#pragma udata bigdata   //7-10
// extern unsigned char    Buffer[1023];  //液晶顯示緩沖區 32*160
//#pragma udata
#pragma udata udata2     //該指令可以使receive_rc1放置于另一塊bank中
extern unsigned char receive_rc1[250]; //接收數據緩存區
#pragma udata udata3     //該指令可以使trans_tr1放置于另一塊bank中
extern unsigned char trans_tr1[250];  //發送數據緩存區
#pragma udata udata4     //該指令可以使receive_rc2放置于另一塊bank中
extern unsigned char receive_rc2[250]; //接收數據緩存區
#pragma udata udata5     //該指令可以使trans_tr2放置于另一塊bank中
extern unsigned char trans_tr2[250];  //發送數據緩存區
#pragma udata udata1
extern unsigned char  * HOLD_REG;// = &Buffer[0];//1024個字節的寄存器存儲區
extern unsigned char recdata;  //接收數據寄存器
extern unsigned char *receive_485; //485幀接收指針,指向存儲數組
extern unsigned char *receive_p;  //接收數據處理指針,指向接收數組,crc校驗用
unsigned short crc;
extern unsigned char receive_num,trans_num;//接收到的數據個數,發送數據個數
unsigned char    delet_rc1,delet_rc2; //清除幀接收緩存器時用的計數單元
extern unsigned char *receive_p;
unsigned char error_kind;      //檢測錯誤碼的類型,get_frame_error()程序中用
unsigned int  start_addr,reg_num;    //收到的幀中的寄存器地址和寄存器數目存儲單元。兩個字節int型
unsigned char trans_frame_num;    //發送幀中的個數
unsigned int   heart_beat,heart_beat2,heart_beat3;   //每收到一次指令 heart_beat+1  在00 01和02 03字節上顯示出來
//////////////光纖MODBUS用數據//////////////////////////////////////////////////
extern unsigned char gxreceive_num,gxtrans_num;//接收到的數據個數,發送數據個數
extern unsigned char *receive_gx;
unsigned char  GXtrans_frame_num;
extern unsigned int read_int;
////////////////////////////////////////////////////////////////////////////////
extern struct {
  unsigned  CAN_FLAG:    1; //CAN標志位
  unsigned  RXB0_FLAG:     1;
  unsigned  RXB1_FLAG:     1;
  unsigned  TX1_FLAG:      1; //EUSART標志位
  unsigned  RX1_FLAG:      1;
  unsigned  parity_FLAG:   1;//偶校驗標志位
  unsigned  MOD485_FLAG: 1;//485端口的MODBUS幀接收完成標志位,主程序和定時0中斷處理
  unsigned  MOD485_ERROR: 1;//485端口幀偶校驗或crc校驗錯誤
} 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 高位字節值表 */   
   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  
    };  
// ****************************************************************
// 函 數 名: getparity(unchar parity_target)
// 功能描述: 對parity_target的8位依次進行相加,考察結果的奇偶性
//    偶數:FLAG1bits.parity_FLAG為0,奇數:為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; //偶數個“1”返回0
else
  FLAG1bits.parity_FLAG=1; //奇數個“1”返回1
}
/*********************************************************************************/  
/*函數名稱: GetCRC16()                           
*輸入參數:  共  個參數;  
*輸出參數:  共  個參數;  
*返回值:   
*需儲存的參數: 共  個參數;      
*功能介紹:(1)CRC16校驗; 返回校驗碼;                                               
/*                                      */  
/*********************************************************************************/  
  
unsigned short GetCRC16(unsigned char *puchMsg, unsigned char usDataLen)   
{   
    unsigned char uchCRCHi = 0xFF ; /* 高CRC字節初始化 */   
    unsigned char uchCRCLo = 0xFF ; /* 低CRC 字節初始化 */   
    unsigned uIndex = 0; /* CRC循環中的索引 */   
      
    while (usDataLen--) /* 傳輸消息緩沖區 */   
    {   
        uIndex = uchCRCHi ^ *puchMsg++ ; /* 計算CRC */   
        uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex] ;   
        uchCRCLo = auchCRCLo[uIndex] ;   
    }   
    return (unsigned short)((unsigned short)uchCRCHi << 8 | uchCRCLo) ;   
}   
/*****************************************************************************/
//MODBUS_RTU函數,功能實現MODBUS——RTU協議
/*****************************************************************************/  
void MODBUS_RTU(void)
{
   
   if(FLAG1bits.MOD485_ERROR==0)   //判斷偶校驗是否錯誤
   {
    //receive_p=&receive_rc1[0];
    crc=GetCRC16(&receive_rc1[0],receive_num);
    if(crc!=0)       //判斷crc校驗是否錯誤
    {
     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(); //無異常碼情況下執行RTU操作函數
        break;
      case function_error: unsupport_function();   //功能異常碼 執行功能異常返回函數
        break;
      case regnum_error: unsupport_regnum();    //寄存器數量異常,執行異常返回函數
        break;
      case addnum_error: unsupport_addnum();    //地址和數量異常,執行異常返回函數
        break;
      default : break;
      
     }     
    }
   
   
    for(delet_rc1=0;delet_rc1<receive_num;delet_rc1++)
    {       //幀接受暫存器清零
     receive_rc1[delet_rc1]=0;
    }
    receive_num=0;    //發送完成后接受個數清零,等待下一幀
    trans_num=0;    //發送完成后發送個數清零,等待下一幀
   }
   if(FLAG1bits.MOD485_ERROR==1)   //偶校驗錯誤或crc校驗錯誤,清除各個數據,等待下一幀
   {
    receive_num=0;
    trans_num=0;
    FLAG1bits.MOD485_ERROR=0;
    /******************************************************
     //測試用心跳函數,CRC校驗失
    /************************/
   
   }     
}
/************************************************
*****發送幀函數,入口參數:幀中字節數目,發送trans_tr1數組中的數據**********
************************************************/
void trans_frame(/*unsigned char *trans_frame,*/unsigned char trans_num1)
{
  RE_485=1;     //禁止485的接收功能
  DE_485=1;     //使能485的發送功能  
  
  for(trans_num=0;trans_num<trans_num1;trans_num++)
  {
   getparity(trans_tr1[trans_num]); //進行偶校驗
   TXSTA1bits.TX9D1=FLAG1bits.parity_FLAG;//偶校驗結果放入第九位
   TXREG1=trans_tr1[trans_num];  //返送接收到的數據
   //receive_rc1[trans_num]=0;   // ***發送完后清零****/
            ///////////調試用/////
   while(TXSTA1bits.TRMT1==0);   //等待數據發送完畢
  }
  
  DE_485=0;  
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美一级视频在线观看 | 精品国产99 | 91最新在线视频 | 在线伊人| 三级黄色片在线观看 | 成人高清视频在线观看 | 狠狠狠色丁香婷婷综合久久五月 | www四虎com| 伊人狠狠 | 国产精品久久久爽爽爽麻豆色哟哟 | 欧美精品在线免费 | 国产精品a久久久久 | 精品一区二区三区电影 | 国产精品永久免费视频 | 国产婷婷精品av在线 | 日韩一区二区三区av | 国产精品久久久久久久久久 | 亚洲一区| 亚洲精精品 | 久久久91精品国产一区二区精品 | 一区二区久久电影 | 一区二区三区在线电影 | 免费观看黄 | 国产一区二区三区视频在线观看 | 999久久久久久久久 国产欧美在线观看 | 国产一区二区三区www | 91在线精品秘密一区二区 | 成人影院网站ww555久久精品 | 久热精品在线观看视频 | 久久国 | 麻豆久久久久久久久久 | jlzzjlzz欧美大全 | 国产一级片精品 | 中文字幕av在线 | 国产免费av网| 亚洲欧美综合 | 亚洲成人综合在线 | 日日干夜夜操 | 天天操 天天操 | 国产精品日韩 | 欧产日产国产精品视频 |