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