|
如題, 提供給大家參考. 也歡迎大神指正.
工程文檔在附件中.
單片機源程序如下:
- #include "reg51.h"
- #include "main.h"
- #include "EEPROM.h"
- #define uchr unsigned char
- #define uint unsigned int
- //#define FOSC 11059200L //System frequency
- #define FOSC 12000000L //System frequency
- //#define BAUD 9600 //UART baudrate
- #define T1MS (65536-FOSC/12/1000) //1ms timer calculation method in 12T mode
- #define ON 1 //定義ON
- #define OFF 0 //定義OFF
- #define STARTBYTE 0x24 //開始字節(jié)
- #define STOPBYTE 0x2a //結(jié)束字節(jié)
- #define UART_P1() (AUXR1 |= 0x80) //串口切換到P1口
- #define UART_P3() (AUXR1 &= 0x7f) //串口切換到P3口
- uchr Settings[2]; //從EEPROM讀取的設(shè)定
- uchr addr; //系統(tǒng)地址
- bit PowerONWhenSTARTUP; //系統(tǒng)上電ESD是否開啟(保留)
- bit flagRec_OK; //標(biāo)誌位, 接收完成
- bit flagBusy; //標(biāo)誌位, 發(fā)送忙
- uchr recBuff[5]; //接收緩存
- bit flagWriteEN; //標(biāo)誌位, 寫地址使能
- uchr ESDState; //ESD狀態(tài) 1-> PASS, 2 -> FAIL, 3 -> POWEROFF, 4 -> IDLE
- uchr PowerState; //ESD電源狀狀態(tài) 0-> 關(guān)閉, 1-> 開啟, 2->空閒.
- sfr AUXR = 0x8e; //輔助寄存器
- sfr AUXR1 = 0xa2; //串口選擇寄存器
- sfr BRT = 0x9c;
- sbit pin485EN = P1^4; //485寫使能
- sbit pinESDState= P1^3; //ESD偵測
- sbit pinLampG = P1^2; //綠燈
- sbit pinLampR = P1^1; //紅燈
- sbit pinESDPower= P1^0; //ESD電源
- sbit pinWriteEN = P3^5; //寫地址使能
- sbit pinSensor = P3^7; //感應(yīng)器
- extern void delayms(uint ms); //毫秒延時函數(shù)
- extern void SysInit(void); //系統(tǒng)初始化
- extern void sendData(uchr dat); //發(fā)送1Byte
- extern void UartSend(uchr cmd,dat); //發(fā)送一幀
- extern void UartDriver(void); //串口數(shù)據(jù)處理
- extern void LampControl(uchr t); //燈控制
- extern void UartChangePort(void); //串口切換
- extern void HumanDetection(void); //人員檢測
- /**************主函數(shù)******************/
- void main(void)
- {
- SysInit();
-
- for(;;)
- {
- UartChangePort();
- HumanDetection();
- UartDriver();
- if(PowerState == 1) LampControl(ESDState);
- }
- }
- //#############################
- //毫秒延時
- //#############################
- void delayms(uint ms)
- {
- unsigned char i, j;
- do{
- i = 11;
- j = 190;
- do
- {
- while (--j);
- } while (--i);
- } while (--ms);
- }
- //#############################
- //發(fā)送1byte
- //#############################
- void sendData(uchr dat)
- {
- while(flagBusy); //檢測是否還在發(fā)送狀態(tài)
- flagBusy = 1;
- SBUF = dat;
- }
- //#############################
- //發(fā)送1幀
- //485接收發(fā)送狀態(tài)轉(zhuǎn)換時應(yīng)提前, 以適應(yīng)電路的反應(yīng)時間. 特別是發(fā)送完成. 延時不夠易造成停止位發(fā)送失敗.
- //#############################
- void UartSend(uchr cmd,dat)
- {
- pin485EN = 0; //485發(fā)送使能
- delayms(1); //延時
- sendData(STARTBYTE); //發(fā)送開始位
- sendData(addr); //發(fā)送地址
- sendData(cmd); //發(fā)送指令
- sendData(dat); //發(fā)送數(shù)據(jù)
- sendData(STOPBYTE); //發(fā)送結(jié)束位
- delayms(1); //延時,此時發(fā)送停止位
- pin485EN = 1; //485發(fā)送禁止
- }
- //#############################
- //人員檢測, 僅在電源開啟時起作用
- //#############################
- void HumanDetection(void)
- {
- static uint DetecCount = 0;
-
- if(DetecCount <= 3000) //設(shè)置檢測間隔時間, 防止人員動作造成誤判
- {
- delayms(1);
- DetecCount++;
- } else {
- DetecCount = 0;
- if(PowerState == 1) //確認(rèn)為開啟狀態(tài)
- {
- if(pinSensor == 1) //確認(rèn)人員離開
- {
- delayms(200);
- if(pinSensor == 1)
- {
- PowerState = 2; //進入空閒狀態(tài)
- pinLampG = OFF; //綠燈
- pinLampR = OFF; //紅燈
- pinESDPower = OFF; //ESD電源
- }
- }
- } else if(PowerState == 2) //空閒狀態(tài)
- {
- if(pinSensor == 0) //確認(rèn)人員就位
- {
- delayms(200);
- if(pinSensor == 0)
- {
- PowerState = 1; //進入開啟狀態(tài)
- pinESDPower = ON; //ESD電源
- }
- }
- }
- }
- }
- //#############################
- //燈控制
- // 1-> 綠燈 2-> 紅燈 其他燈滅
- //#############################
- void LampControl(uchr t)
- {
- static uchr lampState = 4; //上一次的燈狀態(tài), 燈狀態(tài)只有0,1,2. 默認(rèn)4防止上電后狀態(tài)不變燈顯示錯誤.
-
- if(lampState != t)
- {
- lampState = t;
- pinLampG = OFF;
- pinLampR = OFF;
- switch(t)
- {
- case 1:
- pinLampG = ON;
- break;
- case 2:
- pinLampR = ON;
- break;
- default:
- break;
- }
- }
- }
- //#############################
- //串口切換
- //單片機默認(rèn)串口在P3, 所以初始化的時候不用設(shè)置
- //#############################
- void UartChangePort(void)
- {
- static uchr UartPort;
- if(UartPort != pinWriteEN) //用個標(biāo)誌位判斷防止不斷寫寄存器
- {
- UartPort = pinWriteEN;
- if(pinWriteEN == 0) //下載端口最後一pin短接到地時, 串口從P1切換到P3. 可使用TTL進行通信調(diào)試.
- {
- UART_P3();
- } else {
- UART_P1();
- }
- }
- }
- //#############################
- //串口數(shù)據(jù)處理
- //檢查接收完成狀態(tài)位flagRec_OK為1, 進函數(shù)進行處理.
- //#############################
- void UartDriver(void)
- {
- uchr returnDat; //返回的數(shù)據(jù)
- uchr returnCmd; //返回的指令
- uchr recCmd; //收到的指令
- uchr recDat; //收到的數(shù)據(jù)
- if(flagRec_OK) //判斷接收標(biāo)誌位
- {
- flagRec_OK = 0;
- if((recBuff[1] == addr) || recBuff[1] == 0xff) //判斷數(shù)據(jù)幀中的地址位是否與本機一致, 或者數(shù)據(jù)幀的地址位廣播地址0xff
- {
- recCmd = recBuff[2];
- returnCmd = recCmd;
- recDat = recBuff[3];
- returnDat = 1;
-
- switch(recCmd)
- {
- case 0x11: //感應(yīng)器測試
- returnDat = pinSensor;
- break;
- case 0x22: //ESD狀態(tài)
- returnDat = ESDState;
- break;
-
- case 0x30: //關(guān)閉ESD電源
- PowerState = 0;
- pinESDPower = OFF;
- pinLampG = OFF;
- pinLampR = OFF;
- break;
- case 0x31: //開啟ESD電源
- PowerState = 1;
- pinESDPower = ON;
- break;
-
- case 0x41: //開綠燈, 只能在ESD關(guān)閉狀態(tài)下
- if(PowerState == 0)
- {
- pinLampG = ON;
- pinLampR = OFF;
- } else {
- returnDat = 0;
- }
- break;
- case 0x42: //開紅燈, 只能在ESD關(guān)閉狀態(tài)下
- if(PowerState == 0)
- {
- pinLampG = OFF;
- pinLampR = ON;
- } else {
- returnDat = 0;
- }
- break;
- case 0x50: //使能地址寫
- flagWriteEN = 1;
- break;
-
- case 0x51: //寫地址
- //if((flagWriteEN == 1) && (pinWriteEN == 0)) //檢查地址寫是否使能
- if(flagWriteEN == 1) //檢查地址寫是否使能
- {
- Settings[0] = recDat;
- addr = recDat;
- ISP_IAP_EraseData(0);
- ISP_IAP_WriteData(0,Settings,2);
- } else {
- returnDat = 0;
- }
- break;
- default: //無法匹配的指令返回0xff
- returnDat = 0xff;
- break;
- }
- UartSend(returnCmd, returnDat); //發(fā)送返回數(shù)據(jù)
- }
- }
- }
- //#############################
- //系統(tǒng)初始化
- //#############################
- void SysInit(void)
- {
- ///*******寄存器初始化**********/
- TL0 = T1MS; //計時器0 1毫秒 初值
- TH0 = T1MS >> 8;
- TR0 = 1; //開啟計時器0
- ET0 = 1; //開啟計時器0中斷
- PCON &= 0x7F; //波特率不倍速
- SCON = 0x50; //8位數(shù)據(jù),可變波特率
- BRT = 0xD9; //獨立波特率初裝值
- AUXR |= 0x04; //獨立波特率1T
- AUXR |= 0x01; //串口1波特率發(fā)生器選擇為獨立波特率發(fā)生器
- AUXR |= 0x10; //啟動獨立波特率發(fā)生器
-
- UART_P1(); //將串口切換到P1口
-
- ES = 1; //開串口中斷
- EA = 1; //開總中斷
-
- /*******設(shè)定初始化**************/
- ISP_IAP_ReadData(0x00,Settings,2); //從EEPROM中讀取3個Byte資料
- addr = Settings[0]; //地址
- PowerONWhenSTARTUP = (bit)(Settings[1]); //開機狀態(tài), 先做在這裡, 但不做處理
-
- /*******端口初始化*************/
- pin485EN = 1; //禁止485發(fā)送, 備註: 485默認(rèn)通過電阻弱下拉, 接收狀態(tài), 使能端低電平使光耦導(dǎo)通, 485使能端轉(zhuǎn)為高電平發(fā)送狀態(tài).
- pinESDState = 1;
- pinWriteEN = 1;
- pinESDPower = ON;
- pinLampG = OFF;
- pinLampR = OFF;
-
- /*******變量初始化**************/
- PowerState = 1; //默認(rèn)電源開啟
- flagWriteEN = 0; //禁止寫地址
- }
- //#############################
- //串口中斷, 接收上位機數(shù)據(jù)
- //數(shù)據(jù)幀格式
- // 24 | 地址 | 指令 | 數(shù)據(jù) | 2A
- //開始位 | 地址位 | 指令位 | 數(shù)據(jù)位 | 結(jié)束位
- //#############################
- void uart_isr() interrupt 4
- {
- static bit recStart; //接收開始
- static bit recStop; //接收結(jié)束
- static uchr recIdx; //接收序號
- uchr recTmp; //接收緩存
-
- if(TI) //發(fā)送
- {
- TI = 0;
- flagBusy = 0;
- } else { //接收
- RI = 0;
- recTmp = SBUF;
-
- if((recTmp == STARTBYTE) && (recStart == 0)) //判斷接收開始
- {
- recStart = 1;
- recStop = 0;
- recIdx = 0;
- flagRec_OK = 0;
- }
-
- if((recStart == 1) && (recStop == 0)) //接收數(shù)據(jù)
- {
- recBuff[recIdx++] = recTmp;
-
- if((recTmp == STOPBYTE) || (recIdx >= 5)) //判斷接收結(jié)束
- {
- recStop = 1;
- recStart = 0;
- flagRec_OK = 1;
- }
- }
- }
- }
- //#############################
- //計時器0中斷函數(shù), 用於獲取ESD狀態(tài)
- //數(shù)據(jù)來源是一個指示異常的閃爍紅燈LED電壓, 燈亮?xí)r為0, 燈滅為1.
- //#############################
- void tm0_isr() interrupt 1 using 1
- {
- static uint count;
- static uchr lampStates[8]; //採集的狀態(tài), 共8個
- static uchr lampStateIdx; //燈狀態(tài)數(shù)據(jù)Idx
- uchr i;
- TL0 = T1MS; //reload timer0 low byte
- TH0 = T1MS >> 8; //reload timer0 high byte
- if (count++ == 250) //每250毫秒採集一次紅燈的狀態(tài), 保存在狀態(tài)數(shù)組中, 從數(shù)組判斷當(dāng)前系統(tǒng)的狀態(tài)
- {
- count = 0; //reset counter
-
- if(PowerState == 0) //關(guān)閉狀態(tài), 採集狀態(tài) = 3
- {
- lampStates[lampStateIdx++] = 3;
- } else if(PowerState == 1) //開啟狀態(tài), 採集狀態(tài) = 紅燈關(guān)聯(lián)
- {
- lampStates[lampStateIdx++] = pinESDState ? 1 : 2;
- } else if(PowerState == 2){ //空閒狀態(tài), 採集狀態(tài) = 4
- lampStates[lampStateIdx++] = 4;
- }
- if(lampStateIdx >=8) //分析採集數(shù)組
- {
- lampStateIdx = 0;
- for(i=0; i<8; i++)
- {
- if(lampStates[i] == 4) //如有採集結(jié)果中有4, 狀態(tài)為空閒
- {
- ESDState = 4;
- break;
- } else if(lampStates[i] == 3) //如有採集結(jié)果中有3, 狀態(tài)為關(guān)閉
- {
- ESDState = 3;
- break;
- } else if(lampStates[i] == 2) //如果採集結(jié)果中有2, 狀態(tài)為異常
- {
- ESDState = 2;
- break;
- } else { //否則, 狀態(tài)為正常.
- ESDState = 1;
- }
- }
- }
- }
- }
復(fù)制代碼 全部資料51hei下載地址:
ESDMonitor.zip
(57.42 KB, 下載次數(shù): 24)
2019-5-15 08:59 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|
評分
-
查看全部評分
|