📄 dongli_24h.c
字号:
#include <16f877a.h>
//#include <18F452.h>
//#include <P16F877A.INC>
#include <stdio.h>
#include <dongli_24h.h>
#include <rs232.c>
#define CS PIN_B7
#define CLK PIN_B6
#define DAT PIN_B5
#define KEY PIN_B4
#define J5v_on PIN_D7
#define J5v_off PIN_D6
#define J10v_on PIN_D5
#define J10v_off PIN_D4
#define J20v_on PIN_D3
#define J20v_off PIN_D2
#define FS_RLY7 PIN_C1
#define BJ_RLY8 PIN_C2
#define PL_RLY9 PIN_B2
#define SD_RLY10 PIN_B3
#define RUN PIN_B0
#define lmt_year 0x07
#define lmt_month 0x02
#define lmt_date 0x16
#use delay(clock=4000000,RESTART_WDT)
#fuses XT,WDT
#use i2c(master,sda=PIN_C4,scl=PIN_C3)
char dot_flag=0;
uchar dura_time;
uchar is_set=0;
uchar count_day_flag=0;
uchar time_flag=0;
//*************写SD2304时钟芯片************************//
/*
void wr2304byte(unsigned char cmd,unsigned char add,unsigned char data)
{
i2c_start();
i2c_write(cmd);
i2c_write(add);
i2c_write(data);
i2c_stop();
}
void write2304(uchar min,uchar hour,uchar day)
{
wr2304byte(0x64,0x10,min); //分钟
wr2304byte(0x64,0x20,hour); //小时
wr2304byte(0x64,0x40,day); //天
wr2304byte(0x64,0x50,0x11); //月
wr2304byte(0x64,0x60,0x06); //年
// wr2304byte(0x64,0x70,0x00);
// wr2304byte(0x64,0xf0,0x20); //24小时制,秒调整,禁止32K脉冲输出
}
*/
//**********************读SD2304实时时钟*********************//
void read2304(unsigned char cmd,unsigned char add,unsigned char mmd)
{
UCHAR i;
#use i2c(master,sda=PIN_C4,scl=PIN_C3)
restart_wdt();
i2c_start();
i2c_write(cmd);
i2c_write(add);
i2c_start();
i2c_write(mmd);
// i=i2c_read();
realtime.min=i2c_read();
realtime.hour=i2c_read();
i=i2c_read();
realtime.day=i2c_read();
realtime.month=i2c_read();
realtime.year=i2c_read();
i2c_stop();
}
void send7279_byte(unsigned char out_byte)
{
unsigned char i;
output_low(CS);
delay_us(100);
for(i=0;i<8;i++)
{
if(out_byte & 0x80)
{
output_high(DAT);
}
else
{
output_low(DAT);
}
output_high(CLK);
delay_us(15);
output_low(CLK);
delay_us(15);
out_byte=out_byte*2;
}
output_low(DAT);
}
unsigned char receive7279_byte(void)
{
unsigned char i,in_byte;
char lf;
output_high(DAT);
delay_us(100);
for(i=0;i<8;i++)
{
output_high(CLK);
delay_us(15);
in_byte=in_byte*2;
lf=input(DAT);
if(lf==1)
{
in_byte=in_byte|0x01;
}
output_low(CLK);
delay_us(15);
}
output_low(DAT);
return(in_byte);
}
void write7279(unsigned char cmd,unsigned char dta)
{
send7279_byte(cmd);
send7279_byte(dta);
}
unsigned char read7279(unsigned char cmd)
{
send7279_byte(cmd);
return(receive7279_byte());
}
//***************************************************************************
#int_rb
void disp_key_isr(void)
{
uchar xkey,BCD_time;
disable_interrupts(int_RB);
if(input(KEY)==0)//判断是否KEY中断
{
xkey=read7279(0x15);
if(xKey==0x23)
is_set=1;
if(is_set==1)
{
switch (xkey)
{
case 0x22:
if(dura_time>=1 && dura_time<99)
dura_time++;
break;
case 0x21:
if(dura_time>1 && dura_time<=99)
dura_time--;
break;
case 0x20:
is_set=0;
EEPROM_write_parameter(pd_time,dura_time);
break;
default:
}
}
if(is_set==1)
{
disable_interrupts(int_TIMER1);
BCD_time= HEX_TO_BCD(dura_time);
write7279(0x80,(BCD_time & 0x0F));
write7279(0x81,(BCD_time & 0xF0)>>4);
write7279(0x82,0x0F);
write7279(0x83,0x8C);
//count_day_flag=0;
}
else
{
dot_flag=0;
// disp_time();
enable_interrupts(int_TIMER1);
}
}
enable_interrupts(int_RB);
}
//************************************************************************************************
#int_TIMER1
void TIMER1_isr()//显示时间
{
char hourl,hourh,minl,minh;
minl=(realtime.min & 0x0F);
minh=(realtime.min & 0xF0)>>4;
write7279(0x80,minl);
write7279(0x81,minh);
hourl=(realtime.hour & 0x0F);
hourh=(realtime.hour & 0xF0)>>4;
if(dot_flag==0x00)
write7279(0x82,(hourl|0x80));
else
write7279(0x82,hourl);
//write7279(0x82,(hourl|0x80));
dot_flag=dot_flag^0x01;
write7279(0x83,hourh);
}
unsigned char BCD_TO_HEX(unsigned char x)
{
unsigned char t,y;
t=(x/16)*10;
y=t+(x&0x0F);
return y;
}
unsigned char HEX_TO_BCD(unsigned char x)
{
unsigned char t,y;
t=(x/10)*16;
y=t+x%10;
delay_us(1);
return y;
}
void first_run()
{
uchar is_first;
is_first=EEPROM_read_parameter(first_flag);
if(is_first!=0xAA)
{
EEPROM_write_parameter(a_year,lmt_year);
EEPROM_write_parameter(a_month,lmt_month);
EEPROM_write_parameter(a_date,lmt_date);
EEPROM_write_parameter(first_flag,0xAA);
EEPROM_write_parameter(pd_time,24);
get_endate(lmt_year,lmt_month,lmt_date);
}
}
void get_endate(uchar year,uchar month,uchar date)
{
year=BCD_TO_HEX(year);
month=BCD_TO_HEX(month);
date=BCD_TO_HEX(date);
if(month==0x02 )
{
if( date>13)
{
endtime.day=HEX_TO_BCD(date-13);
endtime.month=HEX_TO_BCD(month+1);
endtime.year=HEX_TO_BCD(year);
}
else
{
endtime.day=HEX_TO_BCD(date+15);
endtime.month=HEX_TO_BCD(month);
endtime.year=HEX_TO_BCD(year);
}
}
//*****************************************
else if(month==12)
{
if( date>15)
{
endtime.day=HEX_TO_BCD(date-15);
endtime.month=HEX_TO_BCD(1);
endtime.year=HEX_TO_BCD(year+1);
}
else
{
endtime.day=HEX_TO_BCD(date+15);
endtime.month=HEX_TO_BCD(12);
endtime.year=HEX_TO_BCD(year);
}
}
//*****************************************
else
{
if( date>15)
{
endtime.day=HEX_TO_BCD(date-15);
endtime.month=HEX_TO_BCD(month+1);
endtime.year=HEX_TO_BCD(year);
}
else
{
endtime.day=HEX_TO_BCD(date+15);
endtime.month=HEX_TO_BCD(month);
endtime.year=HEX_TO_BCD(year);
}
}
//*****************************************
EEPROM_write_parameter(e_year,endtime.year);
EEPROM_write_parameter(e_month,endtime.month);
EEPROM_write_parameter(e_date,endtime.day);
}
//***********************************************************************
//判断是否过期函数 1-有效 0-过期
uchar in_date(uchar adr_year,uchar adr_month,uchar adr_date)
{
uchar tflag;
uchar year,month,date;
uchar set_year,set_month,set_date;
year=BCD_TO_HEX(realtime.year);
month=BCD_TO_HEX(realtime.month);
date=BCD_TO_HEX(realtime.day);
set_year=BCD_TO_HEX(EEPROM_read_parameter(adr_year));
set_month=BCD_TO_HEX(EEPROM_read_parameter(adr_month));
set_date=BCD_TO_HEX(EEPROM_read_parameter(adr_date));
delay_us(10);
if(year<set_year)
{
tflag=1;
}
else if (year==set_year)
{
if(month<set_month)
{
tflag=1;
}
else if(month==set_month)
{
if(date<=set_date)
tflag=1;
else
tflag=0;
}
else
tflag=0;
}
else
tflag=0;
return tflag;
}
//************************************************************************************************
void main()
{
uchar aflag,eflag,inb,step_flag,day_flag,i,j;
uchar reel_bool=0x00;
//*********初始化将有用的管脚置低所有继电器断开********//
output_low(J20v_on);
output_low(FS_RLY7);
output_low(BJ_RLY8);
output_low(PL_RLY9);
output_low(SD_RLY10);
output_low(J5v_on);
output_high(J5v_off);
output_low(J10v_on);
output_high(J10v_off);
output_low(J20v_on);
output_high(J20v_off);
//**************************************************//
ini_rs232();
enable_interrupts(GLOBAL);
enable_interrupts(int_rda); //打开串口接收中断
send7279_byte(0xa4);
//delay_ms(1000);
send7279_byte(0xBF);
delay_ms(2000);
send7279_byte(0xa4);
first_run();
read2304(0x64,0x10,0x65); //读取分、时,日,月,年
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
set_timer1(3035);
enable_interrupts(INT_TIMER1);
delay_us(100);
set_tris_B(1);
port_b_pullups(TRUE);
ext_int_edge(H_TO_L);
dura_time=EEPROM_read_parameter(pd_time);//读取初始持续时间
//打开B中断,能够改变持续时间
enable_interrupts(int_RB);
while(1)
{
//检查是否过期
// aflag=in_date(a_year,a_month,a_date);
// eflag=in_date(e_year,e_month,e_date);
//取消日期限制
aflag=1;
eflag=1;
//**********************************************************************
if(eflag==1)//正常
{
delay_ms(2000);//延时以便正确读时钟
read2304(0x64,0x10,0x65); //读取分、时,日,月,年
B0_INT: inb=input(RUN);
if(inb==0)
{
if(time_flag==0)
{
time_flag=1;
step_flag=0;
count_day_flag=0;
//记录启动时刻
startime.min=realtime.min;
startime.hour=realtime.hour;
startime.day=realtime.day;
startime.month=realtime.month;
startime.year=realtime.year;
//初设切变换时刻
altime.min=startime.min;
altime.day=startime.day;
altime.month=startime.month;
altime.year=startime.year;
dura_time=EEPROM_read_parameter(pd_time);
//启动设备,之所以放在这里是防止在58,59秒启动设备直到切换前系统无动作
output_high(FS_RLY7);
if( delay_int(15)==1)
goto B0_INT;
output_high(J20v_on);
//注意从取初始时间到if(startime.min==realtime.min && startime.hour==realtime.hour)段必须超过1分钟,否则回直接step_flag=2;
if( delay_int(60)==1)
goto B0_INT;
}
//计算切换时刻和天数
altime.hour=HEX_TO_BCD((BCD_TO_HEX(startime.hour)+dura_time)%24);
day_flag=(BCD_TO_HEX(startime.hour)+dura_time)/24;
//对于24小时的持续时间,这时商等于1,但余数=0,但是这时候也是遇到
//第一个altime就应该切换,所以这时应该将day_flag减1,对于24小时倍数的
//持续时间也应该将day_flag减1。
if(altime.hour==startime.hour)
{
day_flag--;
}
if(realtime.min==altime.min && realtime.hour==altime.hour)
{
if(count_day_flag==day_flag)
{
step_flag=step_flag^1;
// write7279(0x83,step_flag);//for debug
//执行程序段
if(step_flag==0)
{
output_low(J20v_on);
if( delay_int(15)==1)
goto B0_INT;
output_low(BJ_RLY8);
if( delay_int(5)==1)
goto B0_INT;
output_high(FS_RLY7);
if( delay_int(15)==1)
goto B0_INT;
output_high(J20v_on);
}
else //if(step_flag==1)
{
output_low(J20v_on);
if( delay_int(15)==1)
goto B0_INT;
output_low(FS_RLY7);
if( delay_int(5)==1)
goto B0_INT;
output_high(BJ_RLY8);
if( delay_int(15)==1)
goto B0_INT;
output_high(J20v_on);
}
startime.hour=altime.hour;//时间从切换的时间继续开始
count_day_flag=0;
}
else//(count_day_flag==day_flag)
{
count_day_flag++;
}
//延时超过一分钟避免同一分钟内多次满足(realtime.min==altime.min && realtime.hour==altime.hour)
if( delay_int(70)==1)
goto B0_INT;
}//(realtime.min==altime.min && realtime.hour==altime.hour)
}//(inb==0)
else
{ //消抖动
delay_ms(50);
if(input(RUN)==1)
{
delay_ms(50);
if(input(RUN)==1)
{
time_flag=0;
output_low(J20v_on);
output_low(FS_RLY7);
output_low(BJ_RLY8);
}
}
}
//时间报警处理
if(aflag==1)//正常无报警
{
output_low(PIN_C5);
write7279(0x88,0xFF);
}
else //最后15天内报警
{
write7279(0x88,0x00);
reel_bool=reel_bool^0x01;
output_bit(PIN_C5,reel_bool);
}
}//(eflag==1)
else
{
output_low(J20v_on);
output_low(FS_RLY7);
output_low(BJ_RLY8);
//过期停机
output_high(PIN_C5);
disable_interrupts(int_TIMER1); //过期则停止显示时间
write7279(0x88,0xF0);
write7279(0x80,0x0B);
write7279(0x81,0x0B);
write7279(0x82,0x0B);
write7279(0x83,0x0B);
}
}//while(1)
}
char delay_int(UWORD c_time)
{
uchar is_manu;
UWORD j;
is_manu=0;
c_time=c_time*2;//所以C_time不能大于255/2
for(j=0;j<c_time;j++)
{//消抖动
delay_ms(500);
if(input(RUN)==1)
{
delay_ms(20);
if(input(RUN)==1)
{
delay_ms(20);
if(input(RUN)==1)
{
time_flag=0;
output_low(J20v_on);
output_low(FS_RLY7);
output_low(BJ_RLY8);
// write7279(0x80,0x0B);
is_manu=1;
break;
}
}
}
}
return is_manu;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -