標(biāo)題:
8051F340單片機(jī)MODBUS源程序
[打印本頁(yè)]
作者:
ADETEGA
時(shí)間:
2018-3-9 16:05
標(biāo)題:
8051F340單片機(jī)MODBUS源程序
8051F340MODBUS程序,學(xué)習(xí)學(xué)習(xí)
單片機(jī)源程序如下:
#include"C8051F120.h"
#include"VVVF.h"
#include"UART.h"
#include"DataProcess.h"
sbit S_SL=P5^5;
/*------------------------------------------------------------------------------------
函數(shù)名:Send485Data()
函數(shù)功能:發(fā)送一個(gè)字節(jié)485數(shù)據(jù)
參數(shù):uchar dat;
返回:void
-------------------------------------------------------------------------------------*/
void Send485Data(uchar xdata dat){
uchar xdata old_SFRPAGE;
old_SFRPAGE=SFRPAGE;
SFRPAGE = CONFIG_PAGE;
UART0_Init(9600);
S_SL=1;/////關(guān)閉485發(fā)送 防止在不需要的時(shí)候數(shù)據(jù)寫
UART0SendOneByte(dat);
//P4&=0xEF;/////關(guān)閉485發(fā)送 防止在不需要的時(shí)候數(shù)據(jù)寫,???????????影響串口中斷
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;//命令機(jī)號(hào)
commstr[1]=comm;//命令
commstr[2]=StartAddr/256;//起始地址高在前地在后
commstr[3]=StartAddr%256;
commstr[4]=para/256;
commstr[5]=para%256;//參數(shù)
CRC=VVVF_CRC_CHK(commstr,6);
commstr[6]=CRC%256;
commstr[7]=CRC/256;
for(i=0;i<8;i++){
Send485Data(commstr[i]);
}
}
/*------------------------------------------------------------------------------------
函數(shù)名:MotorRun()
函數(shù)功能:啟動(dòng)電機(jī) 即啟動(dòng)變頻器
參數(shù): void
返回:void
-------------------------------------------------------------------------------------*/
void MotorRun(){
SendVVVFCommand(0x06,0x2000,0x0002);
}
/*------------------------------------------------------------------------------------
函數(shù)名:MotorStop()
函數(shù)功能:停止電機(jī) 即停止變頻器
參數(shù): void
返回:void
-------------------------------------------------------------------------------------*/
void MotorStop(){
SendVVVFCommand(0x06,0x2000,0x0001);
}
/*------------------------------------------------------------------------------------
函數(shù)名:MotorFWD()
函數(shù)功能:電機(jī)正轉(zhuǎn)命令
參數(shù): void
返回:void
-------------------------------------------------------------------------------------*/
void MotorFWD(){
SendVVVFCommand(0x06,0x2000,0x0010);
}
/*------------------------------------------------------------------------------------
函數(shù)名:MotorREV()
函數(shù)功能:電機(jī)反轉(zhuǎn)命令
參數(shù): void
返回:void
-------------------------------------------------------------------------------------*/
void MotorREV(){
SendVVVFCommand(0x06,0x2000,0x0020);
}
/*------------------------------------------------------------------------------------
函數(shù)名:SetFrequnce()
函數(shù)功能:設(shè)置頻率
參數(shù): 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();
復(fù)制代碼
//modbus通信協(xié)議實(shí)現(xiàn)
//
#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 //最大字節(jié)數(shù)
//#define time0 30000
#define MAXREG 100 //最大寄存器數(shù)量
//void SYSCLK_Init (void);
void PORT_Init (void); //IO口初始化
void UART0_Init (void); //uart0初始化
void readRegisters(void) ;//讀寄存器,功能碼03
void beginSend(void) ; //發(fā)送子程序
void presetMultipleRegisters(void);//設(shè)置多個(gè)寄存器,功能碼16
void FLASH_ByteWrite(u16 addr, u8 byte);//flash寫
void FLASH_PageErase (u16 addr); //flash頁(yè)擦寫
//void Receive_timeout(void); //超時(shí)子程序
u16 crc_chk(u8 *dat,u8 length); //CRC校驗(yàn)
u8 FLASH_ByteRead (u16 addr); //flash讀
//void presetSingleRegisters(void); //設(shè)置單個(gè)寄存器,功能碼06
void send_err(u8 err,u8 err_code); //發(fā)送錯(cuò)誤
void Timer0_Init(void); //定時(shí)器0初始化
void PCA_Init();
u16 flag;
u8 temp;
u8 count_receiveNByte;//接收字節(jié)數(shù)
u8 mod_buf[20]; //modubs 數(shù)據(jù)接收緩沖區(qū)
u8 sendBuf[20]; //發(fā)送緩沖區(qū)
u8 sendCount; //發(fā)送字節(jié)數(shù)
u8 localAddr = 3; //單片機(jī)控制板的地址
//u16 Receivetimeout; //定時(shí)初值
//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校驗(yàn)
dat=mod_buf[7];
if(crcData==mod_buf[6]+(dat<<8)) //CRC校驗(yàn)結(jié)果比較
readRegisters(); // 如果檢驗(yàn)正確,那么就回應(yīng)數(shù)據(jù)
count_receiveNByte=0; //接受數(shù)據(jù)指針歸零
}
break;
/* case 0x06:
if(count_receiveNByte>=8)
{
crcData = crc_chk(mod_buf,6); //CRC校驗(yàn)
dat=mod_buf[7];
if(crcData==mod_buf[6]+(dat<<8)) //CRC校驗(yàn)結(jié)果比較
presetSingleRegisters();
count_receiveNByte=0; //接受數(shù)據(jù)指針歸零
}
break;*/
case 0x10:
dat=mod_buf[4];
tempData = (dat<<8) + mod_buf[5];
tempData = tempData * 2; //數(shù)據(jù)個(gè)數(shù)
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; //接受數(shù)據(jù)指針歸零
}
break;
default:
break;
}
}
}
else
count_receiveNByte=0; //接受數(shù)據(jù)指針歸零
_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; //定時(shí)器使用系統(tǒng)時(shí)鐘
TH1 = 256-SYSCLK/2/BaudRate;
}
if(BaudRate <= 38400)
{
CKCON = 0x01; //定時(shí)器時(shí)鐘用系統(tǒng)時(shí)鐘的4分頻
TH1 = 256-SYSCLK/4/2/BaudRate;
}
TL1=TH1;
TR1 = 1;
CKCON |= 0x01; //定時(shí)器時(shí)鐘用系統(tǒng)時(shí)鐘的4分頻
PF=0;
}
/*void Timer0_Init(void)
{
TMOD |= 0x01; // 定時(shí)器0: 方式1,16位定時(shí)器
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 //定時(shí)器中斷
{
TF0=0;
TR0=0;
TH0=0xf1; //3.646ms interrupt
TL0=0xc2;
flag++;
if(flag==15)
{
flag=0;
if(count_receiveNByte<=2) //超時(shí)后,若接收緩沖區(qū)有數(shù)則判斷為收到一幀
{
count_receiveNByte=0; //接受數(shù)據(jù)指針歸零 ;
}
}
TR0=1;
}
/***********************************************************
CRC校驗(yàn)
***************************************************************/
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 設(shè)置單個(gè)寄存器
******************************************************************
void presetSingleRegisters(void)
{
u16 addr;
u16 tempAddr;
u16 crcData;
u16 tempData;
// uint8 finsh; //為1時(shí)完成 為0時(shí)出錯(cuò)
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,設(shè)置多個(gè)功能寄存器
******************************************************************/
void presetMultipleRegisters(void)
{
u16 addr;
u16 tempAddr;
u8 byteCount;
u8 setCount;
u16 crcData;
u16 tempData;
// uint8 finsh; //為1時(shí)完成 為0時(shí)出錯(cuò)
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//寄存器數(shù)量>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; //獲取數(shù)據(jù)
count_receiveNByte++; //接收字節(jié)數(shù)目
// Receivetimeout=350;
if(count_receiveNByte >= MAXNByte) //如果接收滿
count_receiveNByte = 0; //接受滿 歸0
}
TI0 = 0;
ES0=1;
}
//發(fā)送子程序
void beginSend(void)
{ u8 i;
ES0=0;
GREEN=0;
RED=1;
PF=1; //485允許發(fā)送
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)//發(fā)送錯(cuò)誤
{
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();
}
/*****************************************************
接收超時(shí)判斷
調(diào)用條件:
((Receivetime_flag=1)&&(count_receiveNByte>0)) 1ms定時(shí)時(shí)間到
并且 有接收到的字符,調(diào)用此模塊,判定是否接收超時(shí)
*****************************************************
void Receive_timeout(void)
{
Receivetimeout--;
if((Receivetimeout==0)&&(count_receiveNByte>0)) //說(shuō)明接收超時(shí)
{
count_receiveNByte=0; //接受數(shù)據(jù)指針歸零
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; //設(shè)定單字節(jié)寫入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
}
復(fù)制代碼
0.png
(48.18 KB, 下載次數(shù): 50)
下載附件
2018-3-10 00:45 上傳
所有資料51hei提供下載:
340.zip
(51.69 KB, 下載次數(shù): 55)
2018-3-9 16:03 上傳
點(diǎn)擊文件名下載附件
modbus編程
下載積分: 黑幣 -5
作者:
wadz3652002
時(shí)間:
2018-7-12 01:14
正好需要。。。。。。。。。。。。。。。。。。。。。。。。。
作者:
竹子開(kāi)花
時(shí)間:
2018-8-12 10:31
需要。。。。。。。。。。。。。。。。。。。。。。。
作者:
WFX777888
時(shí)間:
2018-8-12 12:07
謝謝分享資料
作者:
yanfeng082
時(shí)間:
2020-10-29 14:42
請(qǐng)問(wèn)這個(gè)怎么能移植到c51單片機(jī)上用來(lái)控制變頻器
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1