?? pump_watch.c
字號:
//485通訊協儀*********************************************************************
// 主機發送: D9------校驗和
// D8------報警數據第25-32路
// D7------報警數據第17-24路
// D6------報警數據第 9-16路
// D5------報警數據第 1- 8路
// D4------報警狀態碼
// D3------主機當前的按鍵操作碼
// D2------數據接收方的機器號碼
// D1------數據發送方的機器號碼
// D0------幀起始標志 0xff
#include "REG52.H"
#include "stdio.h"
#include "stdlib.h"
#include "ABSACC.H"
//#include "math.h"
#include <rtx51tny.h>
#define INT 0
#define MAIN 1
#define AD_CNV 2
#define DISPLAY 3
#define ALARM 4
#define serialer 5
#define RESET 1
#define MUTE 2
#define TEST 3
#define SET_DAT 4
#define MAX485_send 0xFF //485發送定義
#define MAX485_REC ~0X80 //485接收定義
#define COMM_BUF_SIZE 10 //串行接收緩存大小
#define uchar unsigned char
#define uint unsigned int
//***************************************************************************************
//用于設置的全局變量定義*****************************************************************
unsigned char alarm_delay[32]; //定義延時報警緩存
//unsigned char alarm_fz[32]; //定義延伸分組設置
unsigned char alarm_cou[4]; //定義報警是否可恢復 0鎖存,1可自動恢復
unsigned char slect_no_nc[4]; //定義選取擇常開常閉輸入的緩存
unsigned char match_number; //用于保存本機機器號
unsigned char comm_in_buf[42]; //串口接收緩存
unsigned char comm_out_buf[42]; //串口接收緩存
unsigned char alarm_out_slect[4]; //設置報警選擇
//用于報警的全局變量定義******************************************************************
//****************************************************************************************
unsigned char delay_time[32]; //用于延時的時間寄存單元
unsigned char alarm_data[4]; //定義最終報警數據
unsigned char in_buf[4]; //定義報警輸入緩存
unsigned char MUTE_buff[4]={0,0,0,0}; //定義消音暫存報警單元
unsigned char MUTE_out[4]={0x0,0x0,0x0,0x0}; //定義消音后的輸出單元
unsigned char dis_buf[4];// //定義顯示緩存共4個字節
unsigned char key_buf; //定義按鍵緩存
unsigned char COMM; //串口控制緩存
unsigned char *comm_send_point; //串口發送指針
unsigned char comm_rec_point=0; //串口接收指針
unsigned char Alarm[9]={0,0,0,0,0,0,0,0,0}; //定義報警
unsigned char line;
unsigned char cnt;
////位地址定義****************************************************************************
bit SEND; //需要發送標志
bit mu; //消音標志位
bit comm_send_over; //串口發送完畢位
bit comm_rec_over; //串口接收完畢位
bit power_fault; //電源故障標志
bit set; //設置
bit commstart; //串口開始接受標志
bit power_up; //上電
bit lpmute_f; //失電報警消音標志
sbit mute = P1^7; //消音按鍵定義
sbit test = P3^3; //試燈鍵定義
sbit reset= P3^2; //復位鍵定義 sbit FMQ = P1^5; //蜂鳴器控制引腳定義
sbit LPD = P1^3; //失電報警檢測
sbit LPF = P1^4; //失電報警輸出
sbit YS = P1^6; //延伸報警繼電器輸出//*****************************************************************************
//*****************************************************************************
//函數預定義*******************************************************************
void alarm_in(void);
void delay_alarm(void);
void time_delay_copy(void);
extern uchar nbyteRead(uchar addr, uchar nbyte, uchar *index);// addr 要讀取的地址 nbyte 讀取的字節
extern uchar nbyteWrite( uchar addr, uchar nbyte,uchar *index);
//*****************************************************************************
//*****************************************************************************
//報警輸出函數*****************************************************************
void alarm_out(void){
//主機才執行
uchar count;
if (match_number==0){
Alarm[8]=Alarm[0]|Alarm[1]|Alarm[2]|Alarm[3]|Alarm[4]|Alarm[5]|Alarm[6]|Alarm[7];
} //如果機號為0,則給Alarm[8]賦值
for (count=0;count<4;count++){
dis_buf[count]=alarm_data[count]; //將報警值存入顯示緩存
}
if (((Alarm[8]!=0)&&(mu==0))||((power_fault)&&(!lpmute_f)&&(key_buf!=RESET))){ FMQ=1; } //操作蜂鳴器
if (power_fault) LPF= 0; //如果失電點亮失電指示燈
os_wait(K_TMO,150,0); //延時(為了閃亮)
for (count=0;count<4;count++){
dis_buf[count]=MUTE_out[count]; //將消音處理的值存入報警緩存
FMQ = 0;
if (!lpmute_f)LPF =1; }
os_wait(K_TMO,150,0); //延時(為了閃亮)
if ((MUTE_out[0]==alarm_data[0])&&(MUTE_out[1]==alarm_data[1])&&(MUTE_out[2]==alarm_data[2])&&(MUTE_out[3]==alarm_data[3])){
YS=0;}
else{YS=1;} //繼電器輸出判斷
}
//*****************************************************************************
//*****************************************************************************
//按鍵讀取函數*****************************************************************
//*****************************************************************************
void key_read(void){
if (!reset||!test||!mute){ //如果有鍵按下
os_wait(K_TMO,1,0); //延時去抖動
if (!reset) key_buf = RESET ; //復位鍵
if (!mute) key_buf = MUTE ; //消音鍵
if (!test) key_buf = TEST ; //試燈鍵
if (!mute&&!test) key_buf=SET_DAT; //同時按下消音鍵和測試鍵為設置
}
//else {os_wait(K_TMO,20,0);if (comm_send_over==1){key_buf=0;comm_send_over=0;}} //***********按鍵放下清空緩沖區
LPD =1;
if (LPD) { power_fault=1; } //主電源失電檢測
else{power_fault=0;lpmute_f=0;} //否則清除失電報警信號
}
//串口發送程序*****************************************************************
//*****************************************************************************
//輸入:count 要發送的數據長度(字節)
// P 要發送數據的起始地址指針
void comm_send(char count,char *p){
ES=0; //禁止串口中斷
COMM=MAX485_send; //將485串口轉換器置為發送狀態
XBYTE[0XA000]=line&COMM;
os_wait(K_TMO,2,0); // 延時穩定
while(count>0){
if (!TI){SBUF=*p;count--;p++;} //發送數據
while(!TI){os_wait(K_TMO,1,0);}
TI=0; //等待發送完畢
}
COMM=MAX485_REC; //485串口轉回接受狀態
XBYTE[0XA000]=line&COMM;
ES=1; //允許串口中斷
}
//*****************************************************************************
//*****************************************************************************
//初始化函數,對程序進行初始化操作
void init(void){ //初始化設置程序
char k;
comm_out_buf[0]=0xff; //初始化comm_out_buf[0],幀起始
for (k=0;k<4;k++){
alarm_data[k]=0; //初始化數據單元
dis_buf[k]=0;
MUTE_out[k]=0;
}
lpmute_f=0; //初始化各標志位
mu =0;
FMQ =0;
cnt =0;
time_delay_copy();
for (k=0;k<9;k++)Alarm[k]=0;
match_number = (~P1)&0x07; //讀取本機機器號
}
void init1 (void)
{ char k;
TMOD =TMOD|0X20; //定時器1工作于方式2
TL1 =0XF3;
TH1 =0XF3;
SCON =0X50; //8位數據位1位停止位無校驗位
PCON =0X80; //波特率倍增
ES=1; //允許串口中斷
TR1=1; //啟動波特率發生器
key_buf=0; //初始化串口緩沖區
set = 0;
commstart=0;
COMM =MAX485_REC; //初始時485串口處于接收狀態
comm_rec_point=0; //接收指針為0
nbyteRead(0, 4, slect_no_nc ); //從24c02中讀取相應數據
nbyteRead(4, 4, alarm_out_slect );
nbyteRead(8, 4, alarm_cou );
nbyteRead(12,32,delay_time );
for (k=0;k<32;k++){
alarm_delay[k]= delay_time[k]; //重新設定延時時間
power_up=1;
}
}
//******************************************************************************
//******************************************************************************
//延時時間重新設定函數**********************************************************
//******************************************************************************
void time_delay_copy(void){
unsigned char kk;
for (kk=0;kk<32;kk++){
alarm_delay[kk]= delay_time[kk]; //重新設定延時時間
}
}
//******************************************************************************
//******************************************************************************
//串行口中斷函數
serial()interrupt 4 using 3{
unsigned char k;
if (RI){
RI=0; //清除串行接收中斷標志
ES=0;
k=SBUF;
if ((!commstart)&&(k==0XFF)){
comm_in_buf[comm_rec_point]=k;
commstart=1;comm_rec_point++;ES=1;return;}
if (commstart){
comm_in_buf[comm_rec_point]=SBUF; //將接收到的串口數據存入接收緩存
comm_rec_point++; //調整接收指針
}
if( comm_rec_point>=COMM_BUF_SIZE){
commstart=0;
comm_rec_point=0;
if (comm_in_buf[9]==(comm_in_buf[0]^comm_in_buf[1]^comm_in_buf[2]^comm_in_buf[3]^comm_in_buf[4]^comm_in_buf[5]^comm_in_buf[6]^comm_in_buf[7]^comm_in_buf[8]) ) //和校驗判斷
{
comm_rec_over=1 ; //置位接收完畢標志
}
//else {comm_rec_over=0;}
}
}
ES=1; }
//*******************************************************************************
//數據接收處理程序***************************************************************
void serial_cl(void){
uchar i;
uchar k;
if(comm_rec_over){ //如果所有數據接收完畢
if (!set){ //非設置狀態
if (match_number==0){ //機號為0時,讀入Alarm[]
Alarm[comm_in_buf[1]]=comm_in_buf[4];
Alarm[8]=Alarm[0]|Alarm[1]|Alarm[2]|Alarm[3]|Alarm[4]|Alarm[5]|Alarm[6]|Alarm[7]; //主機才執行
if(Alarm[8]!=0){ //處理報警:Alarm[8]!=0即有新報警,清消音標志
mu=0;
}
// else {Alarm = Alarm&(~(comm_in_buf[1]+1));}//如果沒有報警,則清除相應從機的報警位
return;
}
if (match_number!=0) key_buf= comm_in_buf[3]; //非0機子,存入按鍵狀態
if (key_buf==SET_DAT) set =1; //判斷是否需進入設置
if (key_buf==MUTE){
for (k=0;k<4;k++){MUTE_out[k]=alarm_data[k];} //消音處理
FMQ=0;mu=1;//key_buf=0;
}
if (match_number==comm_in_buf[2]){ //如果需要本機作出應答
if (comm_in_buf[3]!=SET_DAT){ SEND = 1; } }//允許發送信號準備回應
comm_rec_over=0; //清除接收完畢標志
return;
}
else { if(match_number==comm_in_buf[2]){ //設置狀態下,如果是對本機操作
switch (comm_in_buf[3]){ //判斷命令代碼
case 1:{
if (comm_in_buf[1]==9){
for(i=0;i<4;i++){ //設置數據類型是輸入方式
slect_no_nc[i]=comm_in_buf[i+5];}
nbyteWrite(0, 4, slect_no_nc ); }
else { init();
os_create_task (ALARM);
os_create_task (AD_CNV);
set =0; }
}break;
case 2:{
for(i=0;i<4;i++) { //設置數據類型是輸入方式
alarm_out_slect[i]=comm_in_buf[i+5]; }
nbyteWrite(4, 4, alarm_out_slect );
}break;
case 3:{
for(i=0;i<4;i++){ //設置數據類型是報警鎖存
alarm_cou[i]=comm_in_buf[i+5];}
nbyteWrite(8, 4,alarm_cou );
}break;
case 4:{
for(i=0;i<4;i++){ //設置數據類型是延時時間
delay_time[i+comm_in_buf[4]]=comm_in_buf[i+5];}
if (comm_in_buf[4]==28) nbyteWrite(12, 32,delay_time );
}break;
case 7: { //回應
SEND =1;
}break;
}
comm_rec_over=0; }
comm_rec_over=0;return; }
}
}
// }
//******************************************************************************
//******************************************************************************
void RE32 (unsigned char *point,unsigned char dt ){
unsigned char i,k;
for (i=0;i<8;i++){
for (k=0;k<4;k++){
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -