#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
}
|