|
#include "main.h"
#include "init.h"
#define ENABLE_IAP 0x83 //系統(tǒng)工作時(shí)鐘<12MHz 時(shí),對(duì)IAP_CONTR 寄存器設(shè)置此值
#define CMD_IDLE 0
#define CMD_READ 1
#define CMD_PROGRAM 2
#define CMD_ERASE 3
#define ENABLE_IAP 0x83//SYSCLK<12MH
#define IAP_ADDRESS 0x0000 //存儲(chǔ)地址
uint8 add; //掉電保持485的地址
uint8 j=0;
uint8 dat=0X00;
bit flag_zx=0;
uint8 sendPosi=0; //發(fā)送緩沖區(qū)指針
uint8 receCount=0; //接收緩沖區(qū)指針
uint8 sendCount=0; //需要發(fā)送數(shù)據(jù)個(gè)數(shù)
uint8 receTimeOut=0; //通訊超時(shí)值
uint8 byteCount=5; //發(fā)送個(gè)數(shù)
uint8 sendBuf[10]; //發(fā)送緩沖區(qū)
uint8 receBuf[10]; //接收緩沖區(qū)
bit bz1=0;
/********************************************************************
定義數(shù)據(jù)類型
*********************************************************************/
uint8 TBUF,RBUF;
uint8 TDAT,RDAT;
uint8 TCNT,RCNT;
uint8 TBIT,RBIT;
bit TING,RING;
bit TEND,REND;
uint8 t,r,ii; //定義數(shù)據(jù)類型
uint8 but[16]; //數(shù)據(jù)存儲(chǔ)數(shù)組
/********************************************************************
定義 ISP/IAP/EEPROM 命令
*********************************************************************/
void IapIdle();//禁用 ISP/IAP/EEPROM functionmake 單片機(jī) 在 一 安全 狀態(tài)
uint8 IapReadByte(uint16 addr);//讀數(shù)據(jù)
void IapProgramByte(uint16 addr, uint8 dat);//寫數(shù)據(jù)
void IapEraseSector(uint16 addr);//擦除數(shù)據(jù)
void delay()//延時(shí)程序
{
uint8 m,n,s;
for(m=100;m>0;m--)
for(n=200;n>0;n--)
for(s=248;s>0;s--);
}
/****************發(fā)送函數(shù)*********************/
void senduart1()
{ RS485_DIR=1;
for(ii=0;ii<5;ii++)
{
if(TEND) //允許發(fā)送
{
TEND=0;
TBUF=sendBuf[t++&0x0F];
TING=1;
}
while(!TEND);
}
t=0;
RS485_DIR=0;
}
/****************發(fā)送函數(shù)*********************/
void senduart2()
{ RS485_DIR=1;
sendBuf[0]=0xaa;
sendBuf[1]=add;
sendBuf[2]=0x07;
sendBuf[3]=0xff;
sendBuf[4]=0xbb;
for(ii=0;ii<5;ii++)
{
if(TEND) //允許發(fā)送
{
TEND=0;
TBUF=sendBuf[t++&0x0F];
TING=1;
}
while(!TEND);
}
t=0;
RS485_DIR=0;
}
/*****************清空發(fā)送緩沖區(qū)*************************/
void clear_receBuf()
{
uint8 i;
for(i=0;i<5;i++)
{
receBuf[i]=0;
}
}
void main()
{
delay();
clear_receBuf();
add= IapReadByte(0x01);//讀取存儲(chǔ)的值
if(add==0xff)
add=0x00;
ConfigUART1();
TR0=1;
EA=1;
while(1)
{
if((IN1==0)&&(bz1==0)){bz1=1;senduart2();}if((IN1==1)&&(bz1==1)){bz1=0;}
if(REND) //如果有接收
{
REND=0; //接收標(biāo)志清零
receBuf[r++&0x0F]=RBUF; //把接受的數(shù)據(jù)存儲(chǔ)到BUT數(shù)組中
if(receBuf[0]!=0xaa){r=0;}
if(r>=5)
{ r=0;
flag_zx=1;
}
}
if(flag_zx==1)
{
flag_zx=0;
//0 1 2 3 4
//起始位 地址位 功能位 數(shù)據(jù)位 結(jié)束位
if((receBuf[0]==0xaa)&&(receBuf[4]==0xbb)&&(receBuf[1]==add)) //如果開始位和結(jié)束位,還有地址都正確,進(jìn)行下一步判斷
{
if(receBuf[2]==0x01) //修改板子地址
{
add=receBuf[3];
IapEraseSector(0); //擦除扇區(qū)
IapProgramByte(0x01,add);//寫入新的地址
}
else if(receBuf[2]==0x02) //打開單路繼電器
{
switch(receBuf[3])
{
case 0x01: OUT1=0; break;
}
}
else if(receBuf[2]==0x03) //關(guān)閉單路繼電器
{
switch(receBuf[3])
{
case 0x01: OUT1=1; break;
}
}
else if(receBuf[2]==0x04) //打開全部繼電器
{
if(receBuf[3]==0xff)
{
OUT1=0;
}
}
else if(receBuf[2]==0x05) //關(guān)閉全部繼電器
{
if(receBuf[3]==0x00)
{
OUT1=1;
}
}
else if(receBuf[2]==0x06) //查詢繼電器
{
sendBuf[0]=0xaa;
sendBuf[1]=add;
sendBuf[2]=0x07;
//sendBuf[3]=0xfe;
sendBuf[4]=0xbb;
switch(receBuf[3])
{
case 0x01: if(OUT1==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
default:break;
}
senduart2();
}
else if(receBuf[2]==0x08) //查詢繼電器
{
sendBuf[0]=0xaa;
sendBuf[1]=add;
sendBuf[2]=0x09;
//sendBuf[3]=0xfe;
sendBuf[4]=0xbb;
switch(receBuf[3])
{
case 0x01: if(IN1==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
default:break;
}
senduart2();
}
}
if((receBuf[0]==0xaa)&&(receBuf[1]==0x00)&&(receBuf[2]==0x00)&&(receBuf[3]==0x00)&&(receBuf[4]==0xbb))
{
add=0x00;
IapEraseSector(0); //擦除扇區(qū)
IapProgramByte(0x01,0x00);//寫入新的地址
sendBuf[0]=0xaa;
sendBuf[1]=add;
sendBuf[2]=0x00;
sendBuf[3]=0x00;
sendBuf[4]=0xbb;
senduart1();
}
clear_receBuf();
}
}
}
// /**********************************************************
//放在主函數(shù),定時(shí)0溢出中斷函數(shù),
//*********************/
void tm0()interrupt 1 using 1
{
if(RING)
{
if(--RCNT==0)
{
RCNT=3;
if(--RBIT==0)
{
RBUF=RDAT;
RING=0;
REND=1;
}
else
{
RDAT>>=1;
if(RXB)RDAT|=0X80;
}
}
}
else if(!RXB)
{
RING=1;
RCNT=4;
RBIT=9;
}
if(--TCNT==0)
{
TCNT=3;
if(TING)
{
if(TBIT==0)
{
TXB=0;
TDAT=TBUF;
TBIT=9;
}
else
{
TDAT>>=1;
if(--TBIT==0)
{
TXB=1;
TING=0;
TEND=1;
}
else
{
TXB=CY;
}
}
}
}
}
void IapIdle(){//禁用 ISP/IAP/EEPROM functionmake 單片機(jī) 在 一 安全 狀態(tài)
IAP_CONTR = 0; //
IAP_CMD = 0; //
IAP_TRIG = 0; //
IAP_ADDRH = 0x80; //
IAP_ADDRL = 0; //
}
uint8 IapReadByte(uint16 addr){//讀數(shù)據(jù)
uint8 dat;
IAP_CONTR = ENABLE_IAP;
IAP_CMD = CMD_READ;
IAP_ADDRL = addr;
IAP_ADDRH = addr >> 8;
IAP_TRIG = 0x5A;
IAP_TRIG = 0xA5;
_nop_();
dat = IAP_DATA;
IapIdle();
return dat;
}
void IapProgramByte(uint16 addr, uint8 dat){//寫數(shù)據(jù)
IAP_CONTR = ENABLE_IAP;
IAP_CMD = CMD_PROGRAM;
IAP_ADDRL = addr;
IAP_ADDRH = addr >> 8;
IAP_DATA = dat;
IAP_TRIG = 0x5A;
IAP_TRIG = 0xA5;
_nop_();
IapIdle();
}
void IapEraseSector(uint16 addr){//擦除數(shù)據(jù)
IAP_CONTR = ENABLE_IAP;
IAP_CMD = CMD_ERASE;
IAP_ADDRL = addr;
IAP_ADDRH = addr >> 8;
IAP_TRIG = 0x5A;
IAP_TRIG = 0xA5;
_nop_();
IapIdle();
}
|
|