- *********************************************************************/
- #include "main.h"
- #include "init.h"
- #define ENABLE_IAP 0x83 //系統工作時鐘<12MHz 時,對IAP_CONTR 寄存器設置此值
- #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 //存儲地址
- uint8 add; //掉電保持485的地址
- uint8 j=0;
- uint8 dat=0X00;
- bit flag_zx=0;
- bit bz1=0;
- bit bz2=0;
- bit bz3=0;
- bit bz4=0;
- bit bz5=0;
- bit bz6=0;
- bit bz7=0;
- bit bz8=0;
- uint8 sendPosi=0; //發送緩沖區指針
- uint8 receCount=0; //接收緩沖區指針
- uint8 sendCount=0; //需要發送數據個數
- uint8 receTimeOut=0; //通訊超時值
- uint8 byteCount=5; //發送個數
- uint8 sendBuf[10]; //發送緩沖區
- uint8 receBuf[10]; //接收緩沖區
- /********************************************************************
- 定義數據類型
- *********************************************************************/
- uint8 TBUF,RBUF;
- uint8 TDAT,RDAT;
- uint8 TCNT,RCNT;
- uint8 TBIT,RBIT;
- bit TING,RING;
- bit TEND,REND;
- uint8 t,r,ii; //定義數據類型
- uint8 but[16]; //數據存儲數組
- /********************************************************************
- 定義 ISP/IAP/EEPROM 命令
- *********************************************************************/
- void IapIdle();//禁用 ISP/IAP/EEPROM functionmake 單片機 在 一 安全 狀態
- uint8 IapReadByte(uint16 addr);//讀數據
- void IapProgramByte(uint16 addr, uint8 dat);//寫數據
- void IapEraseSector(uint16 addr);//擦除數據
- void delay()//延時程序
- {
- uint8 m,n,s;
- for(m=10;m>0;m--)
- for(n=20;n>0;n--)
- for(s=248;s>0;s--);
- }
- /****************發送函數*********************/
- void senduart2()
- { RS485_DIR=1;
- for(ii=0;ii<5;ii++)
- {
- if(TEND) //允許發送
- {
- TEND=0;
- TBUF=sendBuf[t++&0x0F];
- TING=1;
- }
- while(!TEND);
- }
- t=0;
- RS485_DIR=0;
- }
- /*****************清空發送緩沖區*************************/
- void clear_receBuf()
- {
- uint8 i;
- for(i=0;i<5;i++)
- {
- receBuf[i]=0;
- }
- }
- void main()
- {
- delay();
- clear_receBuf();
- add= IapReadByte(0x01);//讀取存儲的值
- if(add==0xff)
- add=0x00;
- ConfigUART1();
- TR0=1;
- EA=1;
- while(1)
- {
- if(REND) //如果有接收
- {
- REND=0; //接收標志清零
- receBuf[r++&0x0F]=RBUF; //把接受的數據存儲到BUT數組中
- 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
- //起始位 地址位 功能位 數據位 結束位
- if((receBuf[0]==0xaa)&&(receBuf[4]==0xbb)&&(receBuf[1]==add)) //如果開始位和結束位,還有地址都正確,進行下一步判斷
- {
- if(receBuf[2]==0x01) //修改板子地址
- {
- add=receBuf[3];
- IapEraseSector(0); //擦除扇區
- IapProgramByte(0x01,add);//寫入新的地址
- }
- else if(receBuf[2]==0x02) //打開單路繼電器
- {
- switch(receBuf[3])
- {
- case 0x01: COM1=0; break;
- case 0x02: COM2=0; break;
- case 0x03: COM3=0; break;
- case 0x04: COM4=0; break;
- default:break;
- }
- }
- else if(receBuf[2]==0x03) //關閉單路繼電器
- {
- switch(receBuf[3])
- {
- case 0x01: COM1=1; break;
- case 0x02: COM2=1; break;
- case 0x03: COM3=1; break;
- case 0x04: COM4=1; break;
- default:break;
- }
- }
- else if(receBuf[2]==0x04) //打開全部繼電器
- {
- if(receBuf[3]==0xff)
- {
- COM1=0; COM2=0; COM3=0;COM4=0;
- }
- }
- else if(receBuf[2]==0x05) //關閉全部繼電器
- {
- if(receBuf[3]==0x00)
- {
- COM1=1; COM2=1; COM3=1; COM4=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(COM1==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
- case 0x02: if(COM2==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
- case 0x03: if(COM3==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
- case 0x04: if(COM4==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;
- case 0x02: if(IN2==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
- case 0x03: if(IN3==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
- case 0x04: if(IN4==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
- case 0x05: if(IN5==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
- case 0x06: if(IN6==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
- case 0x07: if(IN5==0) sendBuf[3]=0xFF;else sendBuf[3]=0x00;break;
- case 0x08: if(IN6==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); //擦除扇區
- IapProgramByte(0x01,0x00);//寫入新的地址
- sendBuf[0]=0xaa;
- sendBuf[1]=add;
- sendBuf[2]=0x00;
- sendBuf[3]=0x00;
- sendBuf[4]=0xbb;
- senduart2();
- }
- clear_receBuf();
- }
- if((IN1==0)&&(bz1==0)){delay();if(IN1==0){bz1=1;if(TEND){TEND=0;TBUF='A';TING=1;}while(!TEND);}}
- if((IN1==1)&&(bz1==1)){delay();if(IN1==1){bz1=0;}}
-
- if((IN2==0)&&(bz2==0)){delay();if(IN2==0){bz2=1;if(TEND){TEND=0;TBUF='B';TING=1;}while(!TEND);}}
- if((IN2==1)&&(bz2==1)){delay();if(IN2==1){bz2=0;}}
- if((IN3==0)&&(bz3==0)){delay();if(IN3==0){bz3=1;if(TEND){TEND=0;TBUF='C';TING=1;}while(!TEND);}}
- if((IN3==1)&&(bz3==1)){delay();if(IN3==1){bz3=0;}}
-
- if((IN4==0)&&(bz4==0)){delay();if(IN4==0){bz4=1;if(TEND){TEND=0;TBUF='D';TING=1;}while(!TEND);}}
- if((IN4==1)&&(bz4==1)){delay();if(IN4==1){bz4=0;}}
- }
- }
- // /**********************************************************
- //放在主函數,定時0溢出中斷函數,
- //*********************/
- 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 單片機 在 一 安全 狀態
- IAP_CONTR = 0; //
- IAP_CMD = 0; //
- IAP_TRIG = 0; //
- IAP_ADDRH = 0x80; //
- IAP_ADDRL = 0; //
- }
- uint8 IapReadByte(uint16 addr){//讀數據
- 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){//寫數據
- 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){//擦除數據
- IAP_CONTR = ENABLE_IAP;
- IAP_CMD = CMD_ERASE;
- IAP_ADDRL = addr;
- IAP_ADDRH = addr >> 8;
- IAP_TRIG = 0x5A;
- IAP_TRIG = 0xA5;
- _nop_();
- IapIdle();
- }
復制代碼 |