|
GYJ-0025 某一個寶描述451.png (737.4 KB, 下載次數(shù): 50)
下載附件
2023-8-30 22:29 上傳
GYJ-0025 某一個寶描述460.png (819.8 KB, 下載次數(shù): 44)
下載附件
2023-8-30 22:29 上傳
GYJ-0025 某一個寶描述468.png (777.19 KB, 下載次數(shù): 45)
下載附件
2023-8-30 22:29 上傳
//本示例在Keil開發(fā)環(huán)境下請選擇Intel的8058芯片型號進(jìn)行編譯
//若無特別說明,工作頻率一般為11.0592MHz
#include "STC89C52RC.h"
#include "intrins.h"
#define uchar unsigned char//宏定義無符號字符型
#define uint unsigned int //宏定義無符號整型
typedef unsigned char BYTE;
typedef unsigned int WORD;
#define FOSC 11059200L //系統(tǒng)頻率
#define BAUD 9600 //串口波特率
#define NONE_PARITY 0 //無校驗(yàn)
#define ODD_PARITY 1 //奇校驗(yàn)
#define EVEN_PARITY 2 //偶校驗(yàn)
#define MARK_PARITY 3 //標(biāo)記校驗(yàn)
#define SPACE_PARITY 4 //空白校驗(yàn)
#define PARITYBIT NONE_PARITY //定義校驗(yàn)位
/*Declare SFR associated with the IAP */
sfr IAP_DATA = 0xE2; //Flash data register
sfr IAP_ADDRH = 0xE3; //Flash address HIGH
sfr IAP_ADDRL = 0xE4; //Flash address LOW
sfr IAP_CMD = 0xE5; //Flash command register
sfr IAP_TRIG = 0xE6; //Flash command trigger
sfr IAP_CONTR = 0xE7; //Flash control register
/*Define ISP/IAP/EEPROM command*/
#define CMD_IDLE 0 //Stand-By
#define CMD_READ 1 //Byte-Read
#define CMD_PROGRAM 2 //Byte-Program
#define CMD_ERASE 3 //Sector-Erase
/*Define ISP/IAP/EEPROM operation const for IAP_CONTR*/
//#define ENABLE_IAP 0x80 //if SYSCLK<40MHz
#define ENABLE_IAP 0x81 //if SYSCLK<20MHz
//#define ENABLE_IAP x82 //if SYSCLK<10MHz
//#define ENABLE_IAP 0x83 //if SYSCLK<5MHz
//Start address for STC89C58xx EEPROM
#define IAP_ADDRESS 0x02000
sbit IN1= P2^0;
sbit IN2= P2^1;
sbit IN3= P2^2;
sbit IN4= P2^3;
sbit out1= P1^0;
sbit out2= P1^1;
sbit out3= P1^2;
sbit out4= P1^3;
bit flagTxd=0,flagFrame=0,flag=0;
unsigned char cntRxd = 0; //接收字節(jié)計(jì)數(shù)器
unsigned char xdata bufRxd[10];
unsigned char xdata qjc[22];
bit k1=0,kt=0;
unsigned char addr=0,addr1=0;
void UartWrite(unsigned char *buf, unsigned char len);
unsigned int GetCRC16(unsigned char *ptr, unsigned char len);
unsigned int crc;
unsigned char crch, crcl;
bit bz1=0,bz2=0,bz3=0,bz4=0,ks=0,bk1=0,bzw=0;
uchar input=0;
uchar xx_1=0x00,xx_2=0x00,xx_3=0x00,xx_4=0x00;
uchar y_1=0x00,y_2=0x00,y_3=0x00,y_4=0x00;
uchar dat1=0x00,dat2=0x00,yy_1=0,zt1=0x00;
uchar dat4=0,dat5=0,dat6=0,dat7=0,dat8=0,dat9=0;
uint js=0;
/********************************************************************
E2P函數(shù)
*********************************************************************/
void IapIdle();
BYTE IapReadByte(WORD addr);
void IapProgramByte(WORD addr, BYTE dat);
void IapEraseSector(WORD addr);
/*******************************************************************
* 配置串口
********************************************************************/
void ConfigUART(unsigned int baud)
{
#if (PARITYBIT == NONE_PARITY)
SCON = 0x50; //8位可變波特率
#elif (PARITYBIT == ODD_PARITY) || (PARITYBIT == EVEN_PARITY) || (PARITYBIT == MARK_PARITY)
SCON = 0xda; //9位可變波特率,校驗(yàn)位初始為1
#elif (PARITYBIT == SPACE_PARITY)
SCON = 0xd2; //9位可變波特率,校驗(yàn)位初始為0
#endif
TMOD &= 0x0F; //清零T1的控制位
TMOD |= 0x20; //配置T1為模式2
TH1 = 256 - (11059200/12/32)/baud; //計(jì)算T1重載值
TL1 = TH1; //初值等于重載值
ET1 = 0; //禁止T1中斷
ES = 1; //使能串口中斷
TR1 = 1; //啟動T1
// SCON = 0x50; //8位可變波特率
// T2L = (65536 - (FOSC/4/BAUD)); //設(shè)置波特率重裝值
// T2H = (65536 - (FOSC/4/BAUD))>>8;
// AUXR = 0x14; //T2為1T模式, 并啟動定時器2
// AUXR |= 0x01; //選擇定時器2為串口1的波特率發(fā)生器
}
/*******************************************************************
* 配置定時器
********************************************************************/
void Timer0Init(void) //1毫秒@11.0592MHz
{
AUXR |= 0x80; //定時器時鐘1T模式
TMOD &= 0xF0; //設(shè)置定時器模式
TL0 = 0xCD; //設(shè)置定時初值
TH0 = 0xD4; //設(shè)置定時初值
TF0 = 0; //清除TF0標(biāo)志
TR0 = 1; //定時器0開始計(jì)時
ET0 = 1; //使能T0中斷
TR0 = 1; //啟動T0
}
/*******************************************************************
* 串口檢測
********************************************************************/
void UartRxMonitor(unsigned char ms){//串口接收監(jiān)控,由空閑時間判定幀結(jié)束,需在定時中斷中調(diào)用,ms-定時間隔
static unsigned char cntbkp = 0;
static unsigned char idletmr = 0;
if (cntRxd > 0){ //接收計(jì)數(shù)器大于零時,監(jiān)控總線空閑時間
if (cntbkp != cntRxd){ //接收計(jì)數(shù)器改變,即剛接收到數(shù)據(jù)時,清零空閑計(jì)時
cntbkp = cntRxd;
idletmr = 0;
}else{ //接收計(jì)數(shù)器未改變,即總線空閑時,累積空閑時間
if (idletmr < 30){ //空閑計(jì)時小于30ms時,持續(xù)累加
idletmr += ms;
if (idletmr >= 30){ //空閑時間達(dá)到30ms時,即判定為一幀接收完畢
flagFrame = 1; //設(shè)置幀接收完成標(biāo)志
}
}
}
}else{
cntbkp = 0;
}
}
/*******************************************************************
* 串口接收函數(shù)
********************************************************************/
void UartDriver(){//串口1接收
unsigned char xdata buf[20];
unsigned char len=0,lenx=0,bz=0,i=0;
if(flagFrame==1)
{
flagFrame=0; //定時器0檢測接收的數(shù)據(jù)
len = cntRxd; //讀取接收的字節(jié)數(shù)量
lenx = cntRxd;
cntRxd = 0; //接收計(jì)數(shù)器清零
if(bufRxd[0]==addr)
{
crc = GetCRC16(bufRxd, len-2); //計(jì)算CRC校驗(yàn)值
crch = crc >> 8;
crcl = crc & 0xFF;
if ((bufRxd[len-2] == crch) && (bufRxd[len-1] == crcl)) //判斷CRC校驗(yàn)是否正確
{
switch (bufRxd[1]) //按功能碼執(zhí)行操作
{
case 0x01://讀取輸出狀態(tài)
if((bufRxd[2]==0x00)&&(bufRxd[4]==0x00)&&(bufRxd[5]==0x01)&&((len-2)==6))
{
switch(bufRxd[3])
{
case 0x00:if(out1==0){yy_1=0x01;}else{yy_1=0x00;}break;
case 0x01:if(out2==0){yy_1=0x01;}else{yy_1=0x00;}break;
case 0x02:if(out3==0){yy_1=0x01;}else{yy_1=0x00;}break;
case 0x03:if(out4==0){yy_1=0x01;}else{yy_1=0x00;}break;
default:break;
}
buf[0] = addr; //地址位
buf[1] = 0x01; //功能位
buf[2] = 0x01; //數(shù)據(jù)長度位
buf[3] = yy_1;//輸出狀態(tài)2進(jìn)制表示有輸入為1,沒輸入為0
len = 4;
crc = GetCRC16(buf, len); //計(jì)算CRC校驗(yàn)值
buf[len++] = crc >> 8; //CRC高字節(jié)
buf[len++] = crc & 0xFF; //CRC低字節(jié)
UartWrite(buf, len);//發(fā)送其他數(shù)據(jù)用串口1
}
if((bufRxd[2]==0x00)&&(bufRxd[4]==0x00)&&(bufRxd[5]==0x02)&&((len-2)==6))
{
switch(bufRxd[3])
{
case 0x00:if(out1==0){y_1=0x01;}else{y_1=0x00;}
if(out2==0){y_2=0x02;}else{y_2=0x00;}
yy_1=(y_1|y_2);
break;
case 0x01:if(out2==0){y_2=0x01;}else{y_2=0x00;}
if(out3==0){y_3=0x02;}else{y_3=0x00;}
yy_1=(y_2|y_3);
break;
case 0x02:if(out3==0){y_3=0x01;}else{y_3=0x00;}
if(out4==0){y_4=0x02;}else{y_4=0x00;}
yy_1=(y_3|y_4);
break;
case 0x03:if(out4==0){y_4=0x01;}else{y_4=0x00;}
yy_1=y_4;
break;
default:break;
}
buf[0] = addr; //地址位
buf[1] = 0x01; //功能位
buf[2] = 0x01; //數(shù)據(jù)長度位
buf[3] = yy_1;//輸出狀態(tài)2進(jìn)制表示有輸入為1,沒輸入為0
len = 4;
crc = GetCRC16(buf, len); //計(jì)算CRC校驗(yàn)值
buf[len++] = crc >> 8; //CRC高字節(jié)
buf[len++] = crc & 0xFF; //CRC低字節(jié)
UartWrite(buf, len);//發(fā)送其他數(shù)據(jù)用串口1
}
if((bufRxd[2]==0x00)&&(bufRxd[4]==0x00)&&(bufRxd[5]==0x03)&&((len-2)==6))
{
switch(bufRxd[3])
{
case 0x00:if(out1==0){y_1=0x01;}else{y_1=0x00;}
if(out2==0){y_2=0x02;}else{y_2=0x00;}
if(out3==0){y_3=0x04;}else{y_3=0x00;}
yy_1=(y_1|y_2|y_3);
break;
case 0x01:if(out2==0){y_2=0x01;}else{y_2=0x00;}
if(out3==0){y_3=0x02;}else{y_3=0x00;}
if(out4==0){y_4=0x04;}else{y_4=0x00;}
yy_1=(y_2|y_3|y_4);
break;
default:break;
}
buf[0] = addr; //地址位
buf[1] = 0x01; //功能位
buf[2] = 0x01; //數(shù)據(jù)長度位
buf[3] = yy_1;//輸出狀態(tài)2進(jìn)制表示有輸入為1,沒輸入為0
len = 4;
crc = GetCRC16(buf, len); //計(jì)算CRC校驗(yàn)值
buf[len++] = crc >> 8; //CRC高字節(jié)
buf[len++] = crc & 0xFF; //CRC低字節(jié)
UartWrite(buf, len);//發(fā)送其他數(shù)據(jù)用串口1
}
if((bufRxd[2]==0x00)&&(bufRxd[3]==0x00)&&(bufRxd[4]==0x00)&&(bufRxd[5]==0x04)&&((len-2)==6))
{
if(out1==0){y_1=0x01;}else{y_1=0x00;}
if(out2==0){y_2=0x02;}else{y_2=0x00;}
if(out3==0){y_3=0x04;}else{y_3=0x00;}
if(out4==0){y_4=0x08;}else{y_4=0x00;}
dat1=(y_1|y_2|y_3|y_4);
buf[0] = addr; //地址位
buf[1] = 0x01; //功能位
buf[2] = 0x01; //數(shù)據(jù)長度位
buf[3] = dat1;//輸出狀態(tài)2進(jìn)制表示有輸入為1,沒輸入為0
len = 4;
crc = GetCRC16(buf, len); //計(jì)算CRC校驗(yàn)值
buf[len++] = crc >> 8; //CRC高字節(jié)
buf[len++] = crc & 0xFF; //CRC低字節(jié)
UartWrite(buf, len);//發(fā)送其他數(shù)據(jù)用串口1
}
break;
case 0x02://查詢輸入狀態(tài)
if((bufRxd[2]==0x00)&&(bufRxd[4]==0x00)&&(bufRxd[5]==0x01)&&((len-2)==6))
{
switch(bufRxd[3])
{
case 0x00:if(IN1 == 0){xx_1 = 0x01;}else{xx_1 = 0x00;} dat1=xx_1;break;//查詢輸入狀態(tài)打開為1,關(guān)閉為0
case 0x01:if(IN2 == 0){xx_2 = 0x01;}else{xx_2 = 0x00;} dat1=xx_2;break;
case 0x02:if(IN3 == 0){xx_3 = 0x01;}else{xx_3 = 0x00;} dat1=xx_3;break;
case 0x03:if(IN4 == 0){xx_4 = 0x01;}else{xx_4 = 0x00;} dat1=xx_4;break;
default:break;
}
buf[0] = addr; //地址位
buf[1] = 0x02; //功能位
buf[2] = 0x01; //數(shù)據(jù)長度位
buf[3] = dat1; //輸入狀態(tài)2進(jìn)制表示有輸入為1,沒輸入為0
len = 4;
crc = GetCRC16(buf, len); //計(jì)算CRC校驗(yàn)值
buf[len++] = crc >> 8; //CRC高字節(jié)
buf[len++] = crc & 0xFF; //CRC低字節(jié)
UartWrite(buf, len);//發(fā)送其他數(shù)據(jù)用串口1
}
if((bufRxd[2]==0x00)&&(bufRxd[4]==0x00)&&(bufRxd[5]==0x02)&&((len-2)==6))
{
switch(bufRxd[3])
{
case 0x00:if(IN1 == 0){xx_1 = 0x01;}else{xx_1 = 0x00;} //查詢輸入狀態(tài)打開為1,關(guān)閉為0
if(IN2 == 0){xx_2 = 0x02;}else{xx_2 = 0x00;}
dat1=(xx_1|xx_2);
break;
case 0x01:if(IN2 == 0){xx_2 = 0x01;}else{xx_2 = 0x00;}
if(IN3 == 0){xx_3 = 0x02;}else{xx_3 = 0x00;}
dat1=(xx_2|xx_3);
break;
case 0x02:if(IN3 == 0){xx_3 = 0x01;}else{xx_3 = 0x00;}
if(IN4 == 0){xx_4 = 0x02;}else{xx_4 = 0x00;}
dat1=(xx_3|xx_4);
break;
case 0x03:if(IN4 == 0){xx_4 = 0x01;}else{xx_4 = 0x00;} dat1=xx_4;break;
default:break;
}
buf[0] = addr; //地址位
buf[1] = 0x02; //功能位
buf[2] = 0x01; //數(shù)據(jù)長度位
buf[3] = dat1; //輸入狀態(tài)2進(jìn)制表示有輸入為1,沒輸入為0
len = 4;
crc = GetCRC16(buf, len); //計(jì)算CRC校驗(yàn)值
buf[len++] = crc >> 8; //CRC高字節(jié)
buf[len++] = crc & 0xFF; //CRC低字節(jié)
UartWrite(buf, len);//發(fā)送其他數(shù)據(jù)用串口1
}
if((bufRxd[2]==0x00)&&(bufRxd[4]==0x00)&&(bufRxd[5]==0x03)&&((len-2)==6))
{
switch(bufRxd[3])
{
case 0x00:if(IN1 == 0){xx_1 = 0x01;}else{xx_1 = 0x00;} //查詢輸入狀態(tài)打開為1,關(guān)閉為0
if(IN2 == 0){xx_2 = 0x02;}else{xx_2 = 0x00;}
if(IN3 == 0){xx_3 = 0x04;}else{xx_3 = 0x00;}
dat1=(xx_1|xx_2|xx_3);
break;
case 0x01:if(IN2 == 0){xx_2 = 0x01;}else{xx_2 = 0x00;}
if(IN3 == 0){xx_3 = 0x02;}else{xx_3 = 0x00;}
if(IN4 == 0){xx_4 = 0x04;}else{xx_4 = 0x00;}
dat1=(xx_2|xx_3|xx_4);
break;
default:break;
}
buf[0] = addr; //地址位
buf[1] = 0x02; //功能位
buf[2] = 0x01; //數(shù)據(jù)長度位
buf[3] = dat1; //輸入狀態(tài)2進(jìn)制表示有輸入為1,沒輸入為0
len = 4;
crc = GetCRC16(buf, len); //計(jì)算CRC校驗(yàn)值
buf[len++] = crc >> 8; //CRC高字節(jié)
buf[len++] = crc & 0xFF; //CRC低字節(jié)
UartWrite(buf, len);//發(fā)送其他數(shù)據(jù)用串口1
}
if((bufRxd[2]==0x00)&&(bufRxd[3]==0x00)&&(bufRxd[4]==0x00)&&(bufRxd[5]==0x04)&&((len-2)==6))
{
if(IN1 == 0){xx_1 = 0x01;}else{xx_1 = 0x00;} //查詢輸入狀態(tài)打開為1,關(guān)閉為0
if(IN2 == 0){xx_2 = 0x02;}else{xx_2 = 0x00;}
if(IN3 == 0){xx_3 = 0x04;}else{xx_3 = 0x00;}
if(IN4 == 0){xx_4 = 0x08;}else{xx_4 = 0x00;}
dat1=(xx_1|xx_2|xx_3|xx_4);
buf[0] = addr; //地址位
buf[1] = 0x02; //功能位
buf[2] = 0x01; //數(shù)據(jù)長度位
buf[3] = dat1; //輸入狀態(tài)2進(jìn)制表示有輸入為1,沒輸入為0
len = 4;
crc = GetCRC16(buf, len); //計(jì)算CRC校驗(yàn)值
buf[len++] = crc >> 8; //CRC高字節(jié)
buf[len++] = crc & 0xFF; //CRC低字節(jié)
UartWrite(buf, len);//發(fā)送其他數(shù)據(jù)用串口1
}
break;
case 0x03://讀取寄存器狀態(tài)
if((bufRxd[2]==0x00)&&(bufRxd[4]==0x00)&&(bufRxd[5]==0x01)&&((len-2)==6))//讀取2個字節(jié)
{
dat5=addr;
buf[0] = addr; //地址位
buf[1] = 0x03; //功能位
buf[2] = 0x02; //數(shù)據(jù)長度位
buf[3] = dat4;//高
buf[4] = dat5;//低
len = 5;
crc = GetCRC16(buf, len); //計(jì)算CRC校驗(yàn)值
buf[len++] = crc >> 8; //CRC高字節(jié)
buf[len++] = crc & 0xFF; //CRC低字節(jié)
UartWrite(buf, len);//發(fā)送其他數(shù)據(jù)用串口1
}
break;
case 0x04://讀取寄存器狀態(tài)
if((bufRxd[2]==0x00)&&(bufRxd[4]==0x00)&&(bufRxd[5]==0x01))//讀取2個字節(jié)
{
switch(bufRxd[3])
{
case 0x00: dat4=qjc[0];dat5=qjc[1];break;
case 0x01: dat4=qjc[2];dat5=qjc[3];break;
case 0x02: dat4=qjc[4];dat5=qjc[5];break;
case 0x03: dat4=qjc[6];dat5=qjc[7];break;
case 0x04: dat4=qjc[8];dat5=qjc[9];break;
case 0x05: dat4=qjc[10];dat5=qjc[11];break;
case 0x06: dat4=qjc[12];dat5=qjc[13];break;
case 0x07: dat4=qjc[14];dat5=qjc[15];break;
case 0x08: dat4=qjc[16];dat5=qjc[17];break;
case 0x09: dat4=qjc[18];dat5=qjc[19];break;
case 0x0A: dat4=qjc[20];dat5=qjc[21];break;
default:break;
}
buf[0] = addr; //地址位
buf[1] = 0x04; //功能位
buf[2] = 0x02; //數(shù)據(jù)長度位
buf[3] = dat4;//高
buf[4] = dat5;//低
len = 5;
crc = GetCRC16(buf, len); //計(jì)算CRC校驗(yàn)值
buf[len++] = crc >> 8; //CRC高字節(jié)
buf[len++] = crc & 0xFF; //CRC低字節(jié)
UartWrite(buf, len);//發(fā)送其他數(shù)據(jù)用串口1
}
if((bufRxd[2]==0x00)&&(bufRxd[4]==0x00)&&(bufRxd[5]==0x02))//讀取4個字節(jié)
{
switch(bufRxd[3])
{
case 0x00: dat4=qjc[0];dat5=qjc[1];dat6=qjc[2];dat7=qjc[3];break;
case 0x01: dat4=qjc[2];dat5=qjc[3];dat6=qjc[4];dat7=qjc[5];break;
case 0x02: dat4=qjc[4];dat5=qjc[5];dat6=qjc[6];dat7=qjc[7];break;
case 0x03: dat4=qjc[6];dat5=qjc[7];dat6=qjc[8];dat7=qjc[9];break;
case 0x04: dat4=qjc[8];dat5=qjc[9];dat6=qjc[10];dat7=qjc[11];break;
case 0x05: dat4=qjc[10];dat5=qjc[11];dat6=qjc[12];dat7=qjc[13];break;
case 0x06: dat4=qjc[12];dat5=qjc[13];dat6=qjc[14];dat7=qjc[15];break;
case 0x07: dat4=qjc[14];dat5=qjc[15];dat6=qjc[16];dat7=qjc[17];break;
case 0x08: dat4=qjc[16];dat5=qjc[17];dat6=qjc[18];dat7=qjc[19];break;
case 0x09: dat4=qjc[18];dat5=qjc[19];dat6=qjc[20];dat7=qjc[21];break;
case 0x0A: dat4=qjc[20];dat5=qjc[21];dat6=0x00;dat7=qjc[22];break;
default:break;
}
buf[0] = addr; //地址位
buf[1] = 0x04; //功能位
buf[2] = 0x04; //數(shù)據(jù)長度位
buf[3] = dat4;//高
buf[4] = dat5;//低
buf[5] = dat6;//高
buf[6] = dat7;//低
len = 7;
crc = GetCRC16(buf, len); //計(jì)算CRC校驗(yàn)值
buf[len++] = crc >> 8; //CRC高字節(jié)
buf[len++] = crc & 0xFF; //CRC低字節(jié)
UartWrite(buf, len);//發(fā)送其他數(shù)據(jù)用串口1
}
break;
case 0x05://設(shè)置單個輸出狀態(tài)
if((bufRxd[2]==0x00)&&(bufRxd[5]==0x00))//輸出1
{
if((bufRxd[3]==0x00)&&(bufRxd[4]==0xFF)){out1=0;}//打開第一路輸出
if((bufRxd[3]==0x00)&&(bufRxd[4]==0x00)){out1=1;}//關(guān)閉第一路輸出
if((bufRxd[3]==0x01)&&(bufRxd[4]==0xFF)){out2=0;}//打開第二路輸出
if((bufRxd[3]==0x01)&&(bufRxd[4]==0x00)){out2=1;}//關(guān)閉第二路輸出
if((bufRxd[3]==0x02)&&(bufRxd[4]==0xFF)){out3=0;}//打開第二路輸出
if((bufRxd[3]==0x02)&&(bufRxd[4]==0x00)){out3=1;}//關(guān)閉第二路輸出
if((bufRxd[3]==0x03)&&(bufRxd[4]==0xFF)){out4=0;}//打開第二路輸出
if((bufRxd[3]==0x03)&&(bufRxd[4]==0x00)){out4=1;}//關(guān)閉第二路輸出
buf[0] = addr; //地址位
buf[1] = 0x05; //功能位
buf[2] = 0x00; //線圈地址高
buf[3] = bufRxd[3]; //線圈地址低
buf[4] = bufRxd[4]; //打開FF/關(guān)閉00
buf[5] = 0x00;
len = 6;
crc = GetCRC16(buf, len); //計(jì)算CRC校驗(yàn)值
buf[len++] = crc >> 8; //CRC高字節(jié)
buf[len++] = crc & 0xFF; //CRC低字節(jié)
UartWrite(buf, len);//發(fā)送其他數(shù)據(jù)用串口1
}
break;
case 0x06://寫單個寄存器
if((bufRxd[2]==0x00)&&(bufRxd[3]==0x00)&&(bufRxd[4]==0x00))
{
addr=bufRxd[5];//k1=1;
IapEraseSector(0x2000);
IapProgramByte(0x2001,addr); //寫入扇區(qū)
buf[0] = addr; //地址位
buf[1] = 0x06; //功能位
buf[2] = bufRxd[2]; //線圈地址高
buf[3] = bufRxd[3]; //線圈地址低
buf[4] = bufRxd[4]; //發(fā)什么回什么
buf[5] = bufRxd[5];
len = 6;
crc = GetCRC16(buf, len); //計(jì)算CRC校驗(yàn)值
buf[len++] = crc >> 8; //CRC高字節(jié)
buf[len++] = crc & 0xFF; //CRC低字節(jié)
UartWrite(buf, len);//發(fā)送其他數(shù)據(jù)用串口1
}
break;
case 0x10://寫多個寄存器
if((bufRxd[2]==0x00)&&(bufRxd[4]==0x00)&&(bufRxd[5]==0x02)&&(bufRxd[6]==0x04))
{
switch(bufRxd[3])
{
case 0x00: qjc[0]=bufRxd[7];qjc[1]=bufRxd[8];qjc[2]=bufRxd[9];qjc[3]=bufRxd[10];break;
case 0x01: qjc[2]=bufRxd[4];qjc[3]=bufRxd[5];qjc[4]=bufRxd[9];qjc[5]=bufRxd[10];break;
case 0x02: qjc[4]=bufRxd[4];qjc[5]=bufRxd[5];qjc[6]=bufRxd[9];qjc[7]=bufRxd[10];break;
case 0x03: qjc[6]=bufRxd[4];qjc[7]=bufRxd[5];qjc[8]=bufRxd[9];qjc[9]=bufRxd[10];break;
case 0x04: qjc[8]=bufRxd[4];qjc[9]=bufRxd[5];qjc[10]=bufRxd[9];qjc[11]=bufRxd[10];break;
case 0x05: qjc[10]=bufRxd[4];qjc[11]=bufRxd[5];qjc[12]=bufRxd[9];qjc[13]=bufRxd[10];break;
case 0x06: qjc[12]=bufRxd[4];qjc[13]=bufRxd[5];qjc[14]=bufRxd[9];qjc[15]=bufRxd[10];break;
case 0x07: qjc[14]=bufRxd[4];qjc[15]=bufRxd[5];qjc[16]=bufRxd[9];qjc[17]=bufRxd[10];break;
case 0x08: qjc[16]=bufRxd[4];qjc[17]=bufRxd[5];qjc[18]=bufRxd[9];qjc[19]=bufRxd[10];break;
case 0x09: qjc[18]=bufRxd[4];qjc[19]=bufRxd[5];qjc[20]=bufRxd[9];qjc[21]=bufRxd[10];break;
case 0x0A: qjc[20]=bufRxd[4];qjc[21]=bufRxd[5];qjc[22]=bufRxd[10];break;
default:break;
}
buf[0] = addr; //地址位
buf[1] = 0x10; //功能位
buf[2] = bufRxd[2]; //線圈地址高
buf[3] = bufRxd[3]; //線圈地址低
buf[4] = bufRxd[4]; //發(fā)什么回什么
buf[5] = bufRxd[5];
len = 6;
crc = GetCRC16(buf, len); //計(jì)算CRC校驗(yàn)值
buf[len++] = crc >> 8; //CRC高字節(jié)
buf[len++] = crc & 0xFF; //CRC低字節(jié)
UartWrite(buf, len);//發(fā)送其他數(shù)據(jù)用串口1
}
break;
case 0x0F://多路控制
if((bufRxd[2]==0x00)&&(bufRxd[3]==0x00)&&(bufRxd[4]==0x00)&&(bufRxd[5]==0x04)&&(bufRxd[6]==0x01))
{
zt1=bufRxd[7]; //
P1=~zt1;
buf[0] = addr; //地址位
buf[1] = 0x0F; //功能位
buf[2] = bufRxd[2]; //數(shù)據(jù)長度位
buf[3] = bufRxd[3];
buf[4] = bufRxd[4];
buf[5] = bufRxd[5];
len = 6;
crc = GetCRC16(buf, len); //計(jì)算CRC校驗(yàn)值
buf[len++] = crc >> 8; //CRC高字節(jié)
buf[len++] = crc & 0xFF; //CRC低字節(jié)
UartWrite(buf, len);//發(fā)送其他數(shù)據(jù)用串口1
}
break;
default:break;
}
}
}
if((bufRxd[0]==0xAA)&&(bufRxd[1]==0x00)&&(bufRxd[2]==0x00)&&(bufRxd[3]==0x00)&&(bufRxd[4]==0xBB)&&(len==5))
{
addr1=IapReadByte(0x2001);
buf[0]=0xAA;
buf[1]=addr;
buf[2]=addr1;
buf[3]=0x00;
buf[4]=0xBB;
len=5;
UartWrite(buf, len);//發(fā)送其他數(shù)據(jù)用串口1
}
for(bz=0;bz<lenx;bz++){bufRxd[bz] = 0;} //把串口接收的數(shù)據(jù)緩存清零
}
}
void senddate()//發(fā)送輸入狀態(tài)
{
unsigned char xdata buf[10];
unsigned char len=0;
if((k1==1)&&(bk1==0))
{
bk1=1;
switch(input)
{
case 1:if(IN1 == 0){xx_1 = 0x01;}else{xx_1 = 0x00;} dat1=xx_1;break;//查詢輸入狀態(tài)打開為1,關(guān)閉為0
case 2:if(IN2 == 0){xx_2 = 0x01;}else{xx_2 = 0x00;} dat1=xx_2;break;
case 3:if(IN3 == 0){xx_3 = 0x01;}else{xx_3 = 0x00;} dat1=xx_3;break;
case 4:if(IN4 == 0){xx_4 = 0x01;}else{xx_4 = 0x00;} dat1=xx_4;break;
default:break;
}
buf[0] = addr; //地址位
buf[1] = 0x02; //功能位
buf[2] = 0x01; //數(shù)據(jù)長度位
buf[3] = dat1; //輸入狀態(tài)2進(jìn)制表示有輸入為1,沒輸入為0
len = 4;
crc = GetCRC16(buf, len); //計(jì)算CRC校驗(yàn)值
buf[len++] = crc >> 8; //CRC高字節(jié)
buf[len++] = crc & 0xFF; //CRC低字節(jié)
UartWrite(buf, len);//發(fā)送其他數(shù)據(jù)用串口1
k1=0;
ks=1;
}
if(bzw==1){bzw=0;bk1=0;}//消抖延時后清零
}
/*******************************************************************
* 主函數(shù)
********************************************************************/
void main()
{
P1=0XFF;
ES = 1; //使能串口1中斷
EA = 1;
ConfigUART(9600);
Timer0Init();
if(IapReadByte(0x2001)==0xff){addr=0x01;}//首次讀取,如果讀到0xFF說明沒有存過數(shù)據(jù),直接付給00值
else
{
addr=IapReadByte(0x2001);
}
while(1)
{
if((IN1==0)&&(bz1==0)){bz1=1;k1=1;input=1;}
if((IN1==1)&&(bz1==1)){bz1=0;k1=1;input=1;}
if((IN2==0)&&(bz2==0)){bz2=1;k1=1;input=2;}
if((IN2==1)&&(bz2==1)){bz2=0;k1=1;input=2;}
if((IN3==0)&&(bz3==0)){bz3=1;k1=1;input=3;}
if((IN3==1)&&(bz3==1)){bz3=0;k1=1;input=3;}
if((IN4==0)&&(bz4==0)){bz4=1;k1=1;input=4;}
if((IN4==1)&&(bz4==1)){bz4=0;k1=1;input=4;}
senddate();
UartDriver();
// if(k1==1)
// {
// IapEraseSector(0x08000);
// IapProgramByte(0x08001,addr); //寫入扇區(qū)
// k1=0;
// }
}
}
void InterruptTimer0() interrupt 1{//T0中斷服務(wù)函數(shù),執(zhí)行串口接收監(jiān)控
TL0 = 0xCD; //設(shè)置定時初值
TH0 = 0xD4;
if(ks==1){js++;if(js==150){js=0;bzw=1;ks=0;}}
UartRxMonitor(1); //串口接收監(jiān)
}
/*******************************************************************
* 串口中斷
********************************************************************/
void Uart() interrupt 4 using 1
{
if (RI)
{
RI = 0; //清除RI位
ACC=SBUF;
if(P==RB8){flag=1;}else{flag=0;}
if (cntRxd < sizeof(bufRxd)) {//接收緩沖區(qū)尚未用完時,保存接收字節(jié),并遞增計(jì)數(shù)器
bufRxd[cntRxd++] = SBUF; // cntRxd++這個很重要,一開始 cntRxd < sizeof(bufRxd)當(dāng)進(jìn)入函數(shù)的次數(shù)增加,cntRxd慢慢變大,當(dāng)傳入的數(shù)據(jù)不滿的時候就 用時間檢測,判斷是否是傳輸完成
}
}
if (TI)
{
TI = 0; //清除TI位
flagTxd = 1;
}
}
/*******************************************************************
* 串口發(fā)送函數(shù)
********************************************************************/
void UartWrite(unsigned char *buf, unsigned char len){//串口數(shù)據(jù)寫入,即串口發(fā)送函數(shù),buf-待發(fā)送數(shù)據(jù)的指針,len-指定的發(fā)送長度
while (len--){ //循環(huán)發(fā)送所有字節(jié)
flagTxd = 0; //清零發(fā)送標(biāo)志
ACC = *buf;
if (P) //根據(jù)P來設(shè)置校驗(yàn)位
{
#if (PARITYBIT == ODD_PARITY)
TB8 = 0; //設(shè)置校驗(yàn)位為0
#elif (PARITYBIT == EVEN_PARITY)
TB8 = 1; //設(shè)置校驗(yàn)位為1
#endif
}
else
{
#if (PARITYBIT == ODD_PARITY)
TB8 = 1; //設(shè)置校驗(yàn)位為1
#elif (PARITYBIT == EVEN_PARITY)
TB8 = 0; //設(shè)置校驗(yàn)位為0
#endif
}
SBUF = ACC; //發(fā)送一個字節(jié)數(shù)據(jù)
buf++;
while (!flagTxd); //等待該字節(jié)發(fā)送完成
}
}
/*----------------------------
Disable ISP/IAP/EEPROM function
Make MCU in a safe state
----------------------------*/
void IapIdle()
{
IAP_CONTR = 0; //Close IAP function
IAP_CMD = 0; //Clear command to standby
IAP_TRIG = 0; //Clear trigger register
IAP_ADDRH = 0x80; //Data ptr point to non-EEPROM area
IAP_ADDRL = 0; //Clear IAP address to prevent misuse
}
/*----------------------------
Read one byte from ISP/IAP/EEPROM area
Input: addr (ISP/IAP/EEPROM address)
Output:Flash data
----------------------------*/
BYTE IapReadByte(WORD addr)
{
BYTE dat; //Data buffer
IAP_CONTR = ENABLE_IAP; //Open IAP function, and set wait time
IAP_CMD = CMD_READ; //Set ISP/IAP/EEPROM READ command
IAP_ADDRL = addr; //Set ISP/IAP/EEPROM address low
IAP_ADDRH = addr >> 8; //Set ISP/IAP/EEPROM address high
IAP_TRIG = 0x46; //Send trigger command1 (0x46)
IAP_TRIG = 0xb9; //Send trigger command2 (0xb9)
_nop_(); //MCU will hold here until ISP/IAP/EEPROM operation complete
dat = IAP_DATA; //Read ISP/IAP/EEPROM data
IapIdle(); //Close ISP/IAP/EEPROM function
return dat; //Return Flash data
}
/*----------------------------
Program one byte to ISP/IAP/EEPROM area
Input: addr (ISP/IAP/EEPROM address)
dat (ISP/IAP/EEPROM data)
Output:-
----------------------------*/
void IapProgramByte(WORD addr, BYTE dat)
{
IAP_CONTR = ENABLE_IAP; //Open IAP function, and set wait time
IAP_CMD = CMD_PROGRAM; //Set ISP/IAP/EEPROM PROGRAM command
IAP_ADDRL = addr; //Set ISP/IAP/EEPROM address low
IAP_ADDRH = addr >> 8; //Set ISP/IAP/EEPROM address high
IAP_DATA = dat; //Write ISP/IAP/EEPROM data
IAP_TRIG = 0x46; //Send trigger command1 (0x46)
IAP_TRIG = 0xb9; //Send trigger command2 (0xb9)
_nop_(); //MCU will hold here until ISP/IAP/EEPROM operation complete
IapIdle();
}
/*----------------------------
Erase one sector area
Input: addr (ISP/IAP/EEPROM address)
Output:-
----------------------------*/
void IapEraseSector(WORD addr)
{
IAP_CONTR = ENABLE_IAP; //Open IAP function, and set wait time
IAP_CMD = CMD_ERASE; //Set ISP/IAP/EEPROM ERASE command
IAP_ADDRL = addr; //Set ISP/IAP/EEPROM address low
IAP_ADDRH = addr >> 8; //Set ISP/IAP/EEPROM address high
IAP_TRIG = 0x46; //Send trigger command1 (0x46)
IAP_TRIG = 0xb9; //Send trigger command2 (0xb9)
_nop_(); //MCU will hold here until ISP/IAP/EEPROM operation complete
IapIdle();
}
/********************************************************************
結(jié)束
*********************************************************************/
|
|