8051F340MODBUS程序,學習學習
單片機源程序如下:
- #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
- }
復制代碼
所有資料51hei提供下載:
340.zip
(51.69 KB, 下載次數: 55)
2018-3-9 16:03 上傳
點擊文件名下載附件
modbus編程
|