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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

C8051F120 MODBUS 單片機源程序,學習教程

[復制鏈接]
跳轉到指定樓層
樓主
ID:521611 發表于 2019-4-25 19:30 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
#include"C8051F120.h"
#include"VVVF.h"
#include"UART.h"
#include"DataProcess.h"
sbit S_SL=P5^5;
/*------------------------------------------------------------------------------------
函數名:Send485Data()
函數功能:發送一個字節485數據
參數:uchar dat;
返回:void
-------------------------------------------------------------------------------------*/
void Send485Data(uchar xdata dat){
    uchar  xdata old_SFRPAGE;
    old_SFRPAGE=SFRPAGE;
    SFRPAGE   = CONFIG_PAGE;
        UART0_Init(9600);
    S_SL=1;/////關閉485發送 防止在不需要的時候數據寫
        UART0SendOneByte(dat);
  //P4&=0xEF;/////關閉485發送 防止在不需要的時候數據寫,???????????影響串口中斷
    UART0_End();
        S_SL=0;
    SFRPAGE=old_SFRPAGE;
}
void SendVVVFCommand(uchar xdata comm, uint xdata StartAddr,uint xdata para){
   uchar xdata commstr[8],i;
   uint xdata CRC;
   commstr[0]=0x01;//命令機號
   commstr[1]=comm;//命令
   commstr[2]=StartAddr/256;//起始地址高在前地在后
   commstr[3]=StartAddr%256;
   commstr[4]=para/256;
   commstr[5]=para%256;//參數
   CRC=VVVF_CRC_CHK(commstr,6);
   commstr[6]=CRC%256;
   commstr[7]=CRC/256;
   for(i=0;i<8;i++){
     Send485Data(commstr[i]);
   }
}   
/*------------------------------------------------------------------------------------
函數名:MotorRun()
函數功能:啟動電機 即啟動變頻器
參數: void
返回:void
-------------------------------------------------------------------------------------*/
void MotorRun(){
    SendVVVFCommand(0x06,0x2000,0x0002);
}
/*------------------------------------------------------------------------------------
函數名:MotorStop()
函數功能:停止電機 即停止變頻器
參數: void
返回:void
-------------------------------------------------------------------------------------*/
void MotorStop(){
    SendVVVFCommand(0x06,0x2000,0x0001);
}
/*------------------------------------------------------------------------------------
函數名:MotorFWD()
函數功能:電機正轉命令
參數: void
返回:void
-------------------------------------------------------------------------------------*/
void MotorFWD(){
    SendVVVFCommand(0x06,0x2000,0x0010);
}
/*------------------------------------------------------------------------------------
函數名:MotorREV()
函數功能:電機反轉命令
參數: void
返回:void
-------------------------------------------------------------------------------------*/
void MotorREV(){
    SendVVVFCommand(0x06,0x2000,0x0020);
}
/*------------------------------------------------------------------------------------
函數名:SetFrequnce()
函數功能:設置頻率
參數: float xdata freq
返回:void
-------------------------------------------------------------------------------------*/
void SetFrequence(float xdata  freq){
    SendVVVFCommand(0x06,0x2001,freq*100);
}

// MotorStop();
/*SetFrequence(40);
   MotorFWD();
   MotorREV();
   SetFrequence(60);
    SetFrequence(50);
    SetFrequence(45);
         SetFrequence(61);
          SetFrequence(65);
           SetFrequence(66);
    SetFrequence(150);
         SetFrequence(180);*/
  // SendVVVFCommand(0x06,0x2001,5000);
   //SendVVVFCommand(0x06,0x2000,0x0002);
   //SendVVVFCommand(0x06,0x2000,0x0001);
   //Num=UART0ReceiveOneByte();

//modbus通信協議實現
//

#include <c8051f340.h>            
#include <intrins.h>
//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------
#define BaudRate       19200//9600,14400,19200,38400,56000可選        
#define SYSCLK         12000000   
//#define BAUDRATE     9600         
//#define SYSCLK       11059200     
sbit GREEN = P2^2;
sbit RED   = P2^1;
sbit PF    = P2^0;
//-----------------------------------------------------------------------------
// Function PROTOTYPES
//-----------------------------------------------------------------------------

#define u16 unsigned int
#define u8 unsigned char
#define   MAXNByte  15   //最大字節數
//#define  time0      30000
#define  MAXREG     100   //最大寄存器數量

//void SYSCLK_Init (void);
void PORT_Init (void);   //IO口初始化
void UART0_Init (void);   //uart0初始化

void readRegisters(void) ;//讀寄存器,功能碼03
void beginSend(void) ;    //發送子程序
void presetMultipleRegisters(void);//設置多個寄存器,功能碼16
void FLASH_ByteWrite(u16 addr, u8 byte);//flash寫
void FLASH_PageErase (u16 addr);        //flash頁擦寫
//void Receive_timeout(void);             //超時子程序
u16 crc_chk(u8 *dat,u8 length);         //CRC校驗
u8 FLASH_ByteRead (u16 addr);           //flash讀
//void presetSingleRegisters(void);       //設置單個寄存器,功能碼06
void send_err(u8 err,u8 err_code);       //發送錯誤
void Timer0_Init(void);                  //定時器0初始化
void PCA_Init();
u16 flag;
u8 temp;
u8 count_receiveNByte;//接收字節數
u8 mod_buf[20];       //modubs 數據接收緩沖區
u8 sendBuf[20];       //發送緩沖區
u8 sendCount;         //發送字節數
u8 localAddr = 3;     //單片機控制板的地址
//u16 Receivetimeout;    //定時初值
//bit ReceiveBit;   

//unsigned int  code  baud_code[8] = {};
/*?????*/
/*void delay(unsigned int m)
{
unsigned int n;
n=0;
while(n < m)
{n++;}
return;
}  */
//-----------------------------------------------------------------------------
// MAIN Routine
//-----------------------------------------------------------------------------

void main(void)
{
   u16 dat;
   u16 tempData;
   u16 crcData;
   PCA0MD    &= ~0x40;                    
   OSCICN    |= 0x03;

   //SYSCLK_Init ();                     
    PORT_Init ();                       
    UART0_Init ();
    PCA_Init();                    
//         Timer0_Init();
    EA=1;
    ES0=1;
        PS0=1;
        GREEN=1;     
    RED=0;
while(1){
  if (mod_buf[0]==localAddr)
  {
     if(count_receiveNByte>4)
        {


    switch(mod_buf[1])
        {
       case 0x03:
                            if(count_receiveNByte>=8)
                                           {
                                          crcData = crc_chk(mod_buf,6);  //CRC校驗
                          dat=mod_buf[7];
                          if(crcData==mod_buf[6]+(dat<<8)) //CRC校驗結果比較

                              readRegisters();         // 如果檢驗正確,那么就回應數據
                                                          count_receiveNByte=0;     //接受數據指針歸零   

                         }
                    break;


/*            case 0x06:
               if(count_receiveNByte>=8)
                                       {
                                     crcData = crc_chk(mod_buf,6);  //CRC校驗
                                         dat=mod_buf[7];
                   if(crcData==mod_buf[6]+(dat<<8)) //CRC校驗結果比較

                             presetSingleRegisters();
                    count_receiveNByte=0;     //接受數據指針歸零  
                                }
                   break;*/
            case 0x10:
                           dat=mod_buf[4];
                   tempData = (dat<<8) + mod_buf[5];
                   tempData = tempData * 2; //數據個數
                   tempData += 9;
                if(count_receiveNByte >= tempData)
                 {

                     crcData = crc_chk(mod_buf,tempData-2);
                     dat=mod_buf[tempData-1];
                    if(crcData == (dat<<8)+ mod_buf[tempData-2])

                                presetMultipleRegisters();
                                                count_receiveNByte=0;     //接受數據指針歸零   

                                 }
                                  break;
                 default:
                  break;
         }


   }


  }
  else
    count_receiveNByte=0;     //接受數據指針歸零
  _nop_();
//    Receive_timeout();
   PCA0CPH4 = 0x00;
}
}

//-----------------------------------------------------------------------------
// SYSCLK_Init
//-----------------------------------------------------------------------------
//
// This routine initializes the system clock to use an 22.1184MHz crystal
// as its clock source.
//
//void SYSCLK_Init (void)
//{
//   int i;                              

//   OSCXCN = 0x67;                     
//  for (i=0; i < 256; i++) ;         

//   while (!(OSCXCN & 0x80)) ;         

//   OSCICN = 0x88;                     
//}

//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// Configure the Crossbar and GPIO ports
//

void PCA_Init()
{
    PCA0CN     =  0x40;                // PCA counter enable
    PCA0MD    &= ~0x40 ;               // Watchdog timer disabled-clearing bit 6
    PCA0MD    &=  0xF1;                // timebase selected - System clock / 12
    PCA0CPL4   =  0xFF;                // Offset value
    PCA0MD  |= 0x40;
    PCA0L    = 0x00;                          // Set lower byte of PCA counter to 0  
    PCA0H    = 0x00;
}

void PORT_Init (void)
{
   XBR0    = 0x01;                      //UART TX0, RX0連到端口引腳P0.4和P0.5
   XBR1    = 0x40;
   XBR2    = 0x00;                     //UART1的I/O不連到端口引?
   P0MDOUT |= 0x01;                    //TX0輸出為推挽方式
   P2MDOUT |= 0x3f;                  
   P1MDOUT |= 0xff;
//   P0SKIP  |= 0xc0;
}

//-----------------------------------------------------------------------------
// UART0_Init
//-----------------------------------------------------------------------------
//
// Configure the UART0 using Timer1, for <baudrate> and 8-N-1.
//
void UART0_Init (void)
{
    SCON0   = 0x50;                    
    TMOD    = 0x20;                    
        if(BaudRate > 38400)                 
        {
                CKCON  = 0x08;                      //定時器使用系統時鐘
                TH1    = 256-SYSCLK/2/BaudRate;
        }
        if(BaudRate <= 38400)
        {
                CKCON  = 0x01;                      //定時器時鐘用系統時鐘的4分頻
                TH1    = 256-SYSCLK/4/2/BaudRate;
        }
   TL1=TH1;
   TR1    = 1;                        
   CKCON |= 0x01;                      //定時器時鐘用系統時鐘的4分頻
   PF=0;
}

/*void Timer0_Init(void)
{
TMOD |= 0x01;        // 定時器0: 方式1,16位定時器
TF0=0;        
TR0=1;// TR0
CKCON |= 0x10;        //
TH0 = 0xf1; //256 -((60*SYSCLK/1000/12)/256);
TL0 = 0xc2;//256 -((60*SYSCLK/1000/12)%256);
ET0=1;
}

void timer0() interrupt 1 using 2 //定時器中斷
{   
    TF0=0;
    TR0=0;
    TH0=0xf1;    //3.646ms interrupt
    TL0=0xc2;
    flag++;
        if(flag==15)
         {
           flag=0;
       if(count_receiveNByte<=2)    //超時后,若接收緩沖區有數則判斷為收到一幀
       {
              count_receiveNByte=0;     //接受數據指針歸零   ;
       }
          }
        TR0=1;
}
/***********************************************************
CRC校驗
***************************************************************/
u16 crc_chk(u8 *pData,u8 nLen)
{
u16 temp=0xffff,temp1,i,j;
for(i=0;i<nLen;i++)
    {
    temp^=*(pData+i);
        for(j=0;j<8;j++)
                {
                temp1=temp;
                temp>>=1;
                if(temp1&0x0001)
                        temp^=0xa001;
        }
    }
return(temp);
}

/*功能碼03讀*/
void readRegisters(void)
{
   u16 addr;
   u16 tempAddr;
// u16 result;
   u16 crcData;
   u8 readCount;
   u8 byteCount;

// u8  finsh; //
   u8 i;
   u16 tempData = 0;
   tempData=mod_buf[2];
   addr = (tempData<<8) + mod_buf[3];
   tempAddr = addr ;//& 0xfff;
   //addr = mod_buf[3];
   //tempAddr = addr;

//readCount = (receBuf[4]<<8) + receBuf[5];
   readCount  = mod_buf[5];
   if(readCount<MAXREG)
   {
       byteCount = readCount* 2 ;//;

      for(i=0;i<byteCount;i++,tempAddr++)
      {
          tempData=FLASH_ByteRead(tempAddr);
          //getRegisterVal(tempAddr,&tempData);   
          sendBuf[i+3] = tempData;// & 0xff;

       }

       sendBuf[0] = localAddr;
       sendBuf[1] = 3;
       sendBuf[2] = byteCount;
       byteCount += 3;
       crcData = crc_chk(sendBuf,byteCount);
       sendBuf[byteCount] = crcData & 0xff;
       byteCount++;
       sendBuf[byteCount] =  crcData >> 8;

       sendCount = byteCount + 1;
       beginSend();
   }
   else
        {

            send_err(0x83,0x03);
    }
}//void readRegisters(void)

/*****************************************************************
功能碼6 設置單個寄存器
******************************************************************
void presetSingleRegisters(void)
{
u16 addr;
u16 tempAddr;


u16 crcData;
u16 tempData;
// uint8  finsh; //為1時完成 為0時出錯

tempData=mod_buf[2];
addr = (tempData<<8) + mod_buf[3];
  tempAddr = addr;// & 0xfff;
  //addr = mod_buf[3];
  //tempAddr = addr & 0xff;

  //setCount = (receBuf[4]<<8) + receBuf[5];
  //setCount = mod_buf[5];
  //byteCount = mod_buf[6];

     FLASH_PageErase (tempAddr);

//    tempData = (modbuf[i*2+7]<<8) + modbuf[i*2+8];
      tempData=mod_buf[4];
//    setRegisterVal(tempAddr,tempData);
      FLASH_ByteWrite (tempAddr, tempData);
          sendBuf[4] = tempData ;
          tempData=mod_buf[5];
          FLASH_ByteWrite (tempAddr+1, tempData);         
      sendBuf[5] = tempData;


sendBuf[0] = localAddr;
sendBuf[1] = 6;
sendBuf[2] = addr >> 8;
sendBuf[3] = addr & 0xff;
crcData = crc_chk(sendBuf,6);
sendBuf[6] = crcData & 0xff;
sendBuf[7] = crcData >> 8;
sendCount = 8;
beginSend();
}

/****************************************************************
功能碼16,設置多個功能寄存器
******************************************************************/
void presetMultipleRegisters(void)
{

u16 addr;
u16 tempAddr;
u8 byteCount;
u8 setCount;
u16 crcData;
u16 tempData;
// uint8  finsh; //為1時完成 為0時出錯
u8 i;

//addr = mod_buf[3];
tempData=mod_buf[2];
addr = (tempData<<8) + mod_buf[3];
tempAddr = addr;// & 0xfff;

//tempAddr = addr & 0xff;

//setCount = (receBuf[4]<<8) + receBuf[5];
setCount = mod_buf[5];
if(setCount<=0x78)
{
  byteCount = mod_buf[6];


sendBuf[0] = localAddr;
sendBuf[1] = 16;
sendBuf[2] = addr >> 8;
sendBuf[3] = addr & 0xff;
sendBuf[4] = setCount >> 8;
sendBuf[5] = setCount & 0xff;
crcData = crc_chk(sendBuf,6);
sendBuf[6] = crcData & 0xff;
sendBuf[7] = crcData >> 8;
sendCount = 8;
beginSend();

    FLASH_PageErase (0x7c00);

   for(i=0;i<byteCount;i++,tempAddr++)
   {
//    tempData = (modbuf[i*2+7]<<8) + modbuf[i*2+8];
      tempData=mod_buf[7+i];
//    setRegisterVal(tempAddr,tempData);

      FLASH_ByteWrite (tempAddr, tempData);
   }

}
else//寄存器數量>120
   {

     send_err(0x90,0x03);

   }

}//void presetMultipleRegisters(void)




/*UART0中斷處理*/
void UART0_ISR (void) interrupt 4
{
ES0=0;
if(!TI0)              
   {
//    Receivetimeout=time0;
    RI0 = 0;  
    mod_buf[count_receiveNByte] = SBUF0; //獲取數據
   count_receiveNByte++;       //接收字節數目
//   Receivetimeout=350;  
  if(count_receiveNByte >= MAXNByte)   //如果接收滿
   count_receiveNByte = 0;     //接受滿 歸0  

   }
  TI0 = 0;   
  ES0=1;
}
//發送子程序
void beginSend(void)
{        u8 i;
        ES0=0;
        GREEN=0;
                RED=1;
                PF=1;          //485允許發送
         for(i=0;i<sendCount;i++)
       {
        SBUF0 = sendBuf[i];
        while(TI0==0);
        TI0=0;
       }
           PF=0;           //485允許接收
           GREEN=1;
           RED=0;
           ES0=1;
}

void send_err(u8 err,u8 err_code)//發送錯誤
{
  u16 crc_tmp;

  sendBuf[0]=localAddr;
  sendBuf[1]=err;
  sendBuf[2]=err_code;
  crc_tmp=crc_chk(mod_buf,3);
  sendBuf[3]=crc_tmp;
  sendBuf[4]=crc_tmp>>8;
  sendCount=5;
  beginSend();        

}
/*****************************************************
接收超時判斷
調用條件:
((Receivetime_flag=1)&&(count_receiveNByte>0))  1ms定時時間到
并且 有接收到的字符,調用此模塊,判定是否接收超時
*****************************************************
void Receive_timeout(void)
{
Receivetimeout--;
if((Receivetimeout==0)&&(count_receiveNByte>0)) //說明接收超時
  {
   count_receiveNByte=0;     //接受數據指針歸零
   SCON0|=0x10;       //允許UART0接收,REN0=1;
  }
}*/
void FLASH_PageErase (u16 addr)
{
   bit EA_SAVE = EA;                   // Preserve EA
   char xdata * data pwrite;           // FLASH write pointer

   EA = 0;                             // Disable interrupts
   // change clock speed to slow, then restore later

   VDM0CN = 0x80;                      // Enable VDD monitor

   RSTSRC |= 0x02;                      // enable VDD monitor as a reset source


   FLKEY  = 0xA5;                      // Key Sequence 1
   FLKEY  = 0xF1;                      // Key Sequence 2
   PSCTL |= 0x03;                      // PSWE = 1; PSEE = 1


   VDM0CN = 0x80;                      // Enable VDD monitor

   RSTSRC |= 0x02;                      // Enable VDD monitor as a reset source

   pwrite = (char xdata *) addr;

   VDM0CN = 0x80;                      // Enable VDD monitor

   *pwrite = 0;                        // Initiate page erase

   PSCTL &= ~0x03;                     // PSWE = 0; PSEE = 0

   EA = EA_SAVE;                       // Restore interrupts
}
/********************************************************************
讀寄存器值
********************************************************************/
u8 FLASH_ByteRead (u16 addr)
{
   bit EA_SAVE = EA;                   // Preserve EA
   char code * data pread;             // FLASH read pointer
   unsigned char byte;

   EA = 0;                             // Disable interrupts

   pread = (char code *) addr;

   byte = *pread;                      // Read the byte

   EA = EA_SAVE;                       // Restore interrupts

   return byte;
}
/************************************************************
Flash寫
************************************************************/
void FLASH_ByteWrite (u16 addr, u8 byte)
{
   bit EA_SAVE = EA;                   // Preserve EA
   char xdata * data pwrite;           // FLASH write pointer

   EA = 0;                             // Disable interrupts

   // change clock speed to slow, then restore later

   VDM0CN = 0x80;                      // Enable VDD monitor

   RSTSRC |= 0x02;                      // Enable VDD monitor as a reset source

   pwrite = (char xdata *) addr;

   PFE0CN &= 0XFE;                //設定單字節寫入FLASH方式

   PSCTL |= 0x01;                      // PSWE = 1
   FLKEY  = 0xA5;                      // Key Sequence 1
   FLKEY  = 0xF1;                      // Key Sequence 2

   VDM0CN = 0x80;                      // Enable VDD monitor


   RSTSRC |= 0x02;                      // Enable VDD monitor as a reset source

   VDM0CN = 0x80;                      // Enable VDD monitor

   *pwrite = byte;                     // Write the byte

   PSCTL &= ~0x01;                     // PSWE = 0

   EA = EA_SAVE;                       // Restore interrupts
}


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:1 發表于 2019-4-25 19:43 | 只看該作者
本帖需要重新編輯補全電路原理圖,源碼,詳細說明與圖片即可獲得100+黑幣(帖子下方有編輯按鈕)
回復

使用道具 舉報

板凳
ID:33455 發表于 2020-10-28 15:07 | 只看該作者
樓主能不能把源程序補全打包發一下,最近在學習找不到合適的,感謝
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表