

//*APPLICATION NOTE E6000 ICEXPLORER ***************
//* Title: FOR colk_time *
//* Version: 00 *
//* Last Updated: *
//* MCU: PIC16F72 *
//* FOR: WWW.PICAVR.COM *
//***************************************************
//****ROM PCLATH.D3=0 000H-7FFH ;
// PCLATH.D3=1 800H-FFFH ;
//***************************************************
//** RAM BANK0=20H---7FH STATUS RP0=0,RP1=0 *
//** BANK1=A0H---FFH STATUS RP0=1,RP1=0 *
//***************************************************
// __________________
// MCLR/VPP/TH-| 1 28 |-RB7/PGD
// RA0/AN0-| 2 27 |-RB6/PGC
// RA1/AN1-| 3 26 |-RB5
// RA2/AN2/VRref--| 4 25 |-RB4
// RA3/AN3/VRref+-| 5 24 |-RB3/PGM
// RA4/TOCKI-| 6 23 |-RB2
// RA5/AN4/SS-| 7 22 |-RB1
// VSS-| 8 21 |-RB0/INT
// OSC1/CLKIN-| 9 20 |-VDD
// OSC2/CLKOUT-| 10 19 |-VSS
// RC0/TISO/TICKI-| 11 18 |-RC7/RX/DT
// RC1/T1OSI/CCP2-| 12 17 |-RC6/TX/CK
// RC2/CCP1-| 13 16 |-RC5/SDO
// RC3/SCK/SCL-| 14 15 |-RC4/SDA
// |________________|
// 16F72
//***************************************************
#include <pic.h> //
#include <stdio.h> //
#include <math.h> //
#define uchar unsigned char //
#define uint unsigned int //
//------------------------------------------
#define KEY_UP RA4 //
#define KEY_DOWN RA5 //
#define KEY_SET RA3 //
//------------------------------------------
void com_buf(void); //
void display(void); //
void buf_initial(void); //
void ad_program(void); //
void add_colk(void); //
void keywork1(void); //
void PORT_DATA(void); //
void sub_colk(void); //
void timr0int(void); //
void colk_stt(void); //
//------------------------------------------
static volatile unsigned char ADRES @ 0x1E;
static volatile unsigned char FLAG1 @ 0x20; //可位寻址的状态寄存器
static volatile bit SET @ (unsigned) &FLAG1 * 8 + 2; //
static volatile bit UP @ (unsigned) &FLAG1 * 8 + 1; //
static volatile bit DOWN @ (unsigned) &FLAG1 * 8 + 0; //
//----------------------------------------------------
static bit B_JIAN0,B_JIAN1,B_JIAN2,B_JIAN3,B_ON,B_OFF,B_BUF,B_ADD;
static bit B_DP,B_COM,B_END;//
unsigned char buf[4]; //
unsigned char k,data,sreg,disppoint,msec,sec,ad_buf,SEL,spbuf; //
unsigned char T_ON0,T_ON1,T_ON2,T_ON3,T_OFF0,T_OFF1,T_OFF2,T_OFF3; //
unsigned char colk0,colk1,colk2,colk3; //
unsigned int i,kcon1,kcon2,PORT_BUF; //
const char table[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xd8,0x80,0x90}; //
//*********************************
/*延时函数*/
//*********************************
void delay_10ms() //
{ uint j; //
for(j=0;j<300;j++) //
{;} //
} //
//*********************************
void delay_50us() //
{ uchar j; //
for(j=0;j<20;j++) //
{;} //
} //
//=================================
//延时最大255毫秒
//=================================
void delay_ms(uchar ms) //
{
uchar i,j; //
for(j=0;j<ms;j++) //
for(i=0;i<86;i++) //
{
#asm //
nop //
nop //
#endasm //
}
}
//==================================
//**********************************
void delay_1s() //延时1S
{
uint j; //
for(j=0;j<200;j++); //
{
display(); //
keywork1(); //
}
}
//********************************
void ds_sp() //报警程序
{
uchar i; //
uint j; //
for(i=0;i<100;i++) //
{
for(j=0;j<20;j++); //
{
display(); //
keywork1(); //
}
RA2=!RA2; //
}
RA2=0; //
}
//*********************************
void sp() //
{
uchar i; //
for(i=0;i<20;i++) //
{
if(B_END==1)
{
B_COM=1; //
return; //
}
ds_sp(); //
delay_1s(); //
}
}
//*******************************
//显示清0程序
//*******************************
void buf_initial() //
{
buf[0]=0X00; //
buf[1]=0X00; //
buf[2]=0X00; //
buf[3]=0X00; //
T_ON0=0X00;T_ON1=0X07;T_ON2=0X00;T_ON3=0X00; //
T_OFF0=0X00;T_OFF1=0X07;T_OFF2=0X00;T_OFF3=0X05;//
sreg=0x00; //
msec=0x00; //
} //
//**********************************
//**********************************
void put_num(char c)
{
PORTB=table[c&0x0f]; //
RB7=0; //
if(B_DP==0) //
{
RB7=1; //
}
}
//*********************************
//**********************************
//显示子程序
//**********************************
void display() //
{
disppoint=0; //
put_num(buf[disppoint]); //
RC4=0; //
delay_ms(1); //
RC4=1; //
disppoint++; //
put_num(buf[disppoint]); //
RC5=0; //
delay_ms(1); //
RC5=1; //
CLRWDT(); //
disppoint++; //
put_num(buf[disppoint]); //
RC6=0; //
delay_ms(1); //
RC6=1; //
disppoint++; //
put_num(buf[disppoint]); //
RC7=0; //
delay_ms(1); //
RC7=1; //
}
//*********************************
//*********************************
//AD转换初始化子程序 //
//*********************************
void ad_program() //
{
TRISA=0XFF; //
ADCON1=0B00000010; //AN0-AN4=A VREF=VDD
PIE1=0; //
ADCON0=0B01001001; //fosc/8 RA1/AN1 ADON=1
INTCON=0; //
ADIF=0; //
ADRES=0; //
delay_50us(); //
ADGO=1; // GODONE=1
while(ADIF==0); //
{
;
} //
ad_buf=ADRES; //
ADCON1=0B00000111; // RA0-RA5=D
TRISA=0X38; // RA3-RA5=IN
ADCON0=0B00000000; //fosc/2 RA0/AN0 ADON=0
}
//*********************************
//*********************************
//tmr0初始化子程序
//*********************************
void timr0int()
{
T0CS=0; //tmr0工作于定时器方式
PSA=1; //tmr0不用分频
T0IF=0; //清除tmr0的中断标志
T0IE=1; //tmr0中断允许
}
//**********************************
//**********************************
//按键等待程序
//**********************************
void keywait() //
{
while((PORTC & 0x06)!=0x06) //
{
display(); //
} //
} //
//**********************************
void keywait1() //
{
while((PORTA & 0x08)!=0x08) //
{
display(); //
} //
} //
//************************************
//*****************************************
//当前时间与开机,关机时间比较
//*****************************************
void com_buf()
{ //
if((T_ON0==buf[0])&&(T_ON1==buf[1])&&(T_ON2==buf[2])&&(T_ON3==buf[3])) //
{ //
RC3=1;return; //
} //
else if((T_OFF0==buf[0])&&(T_OFF1==buf[1])&&(T_OFF2==buf[2])&&(T_OFF3==buf[3]))
{
RC3=0; //
B_COM=1; //
sp(); //
return; //
} //
} //
//******************************************
//******************************************
//时钟显示程序
//******************************************
void add_colk()
{
CLRWDT(); //
buf[3]++; //
B_COM=0; //
B_END=0; //
if(buf[3]>9) //
{
buf[3]=0; //
buf[2]++; //
if(buf[2]>5) //
{
buf[2]=0; //
buf[1]++; //
//----------------------------------
if(buf[1]==4) //
{
if(buf[0]==2)
{
buf[0]=0; //
buf[1]=0; //
return; //
}
return; //
}
//----------------------------------
else if(buf[1]>9)
{
buf[1]=0; //
buf[0]++; //
}
}
}
}
//**********************************
//**********************************
void sub_colk()
{
CLRWDT(); //
if(buf[3]!=0) //
{
buf[3]--; //
return; //
}
buf[3]=9;
if(buf[2]!=0) //
{
buf[2]--; //
return; //
}
buf[2]=5;
if(buf[1]!=0) //
{
buf[1]--; //
return; //
}
buf[1]=9;
if(buf[0]!=0) //
{
buf[0]--; //
return; //
}
buf[1]=3; //
buf[0]=2; //
}
//***************************************************
void colk_to_time_on()
{
T_ON0=buf[0];T_ON1=buf[1];T_ON2=buf[2];T_ON3=buf[3]; //
}
//---------------------------------------------------
void colk_to_time_off()
{
T_OFF0=buf[0];T_OFF1=buf[1];T_OFF2=buf[2];T_OFF3=buf[3];//
}
//---------------------------------------------------
void colk_to_disp_buf()
{
colk0=buf[0];colk1=buf[1];colk2=buf[2];colk3=buf[3]; //
}
//***************************************************
void colk_stt()
{
CLRWDT(); //
if(KEY_UP==0) //
{
B_ADD=1; //
}
if(KEY_DOWN==0)
{
B_ADD=0; //
}
//-----------------------------------
if(B_ON==1)
{
if(B_ADD==0) //
{
add_colk(); //
colk_to_time_on(); //
return;
}
sub_colk(); //
colk_to_time_on(); //
return;
}
//------------------------------------
if(B_OFF==1)
{
if(B_ADD==0) //
{
add_colk(); //
colk_to_time_off();//
return;
}
sub_colk();
colk_to_time_off(); //
return;
}
//------------------------------------------
if(B_BUF==1)
{
if(B_ADD==0) //
{
add_colk(); //
colk_to_disp_buf(); //
return;
}
sub_colk(); //
colk_to_disp_buf(); //
return;
}
}
//*********************************************
void PORT_DATA()
{
TRISC=0X01; //RC7--RC1清0为输出,RC0置1为输入
RA0=1; //开LED显示
PORTC=PORT_BUF; //按键扫描完成后恢复I/O口状态
}
//*********************************************
//按键处理子程序 //
//*********************************************
void keywork1()
{
if(B_JIAN1==1) //连加标志位 B_JIAN1=1
{
//-------------------------------------------------------
JIAN_add: if(B_JIAN0==0) //按键按下时间为3S后置B_JIAN0=1 ,B_JIAN1=0为点动按键
{
if(B_JIAN1==0) //B_JIAN1=1时, 计算第一次按下的时间,B_JIAN1=0为点动按键
{
delay_10ms();
if((KEY_UP==0)||(KEY_DOWN==0))
{
B_JIAN1=1; //KEY_UP 按下,B_JIAN1=1
CLRWDT(); //
//______________________________________________________
JIAN_add1: if((KEY_UP==0)||(KEY_DOWN==0)) //
{
if(KEY_UP==0) //
{
B_ADD=1; //时间减标志位
}
if(KEY_DOWN==0) //
{
B_ADD=0; //时间加标志位
}
if((--kcon1)==0) //
{
kcon1=500; //设置第一次按键的计数值
B_JIAN0=1; //
colk_stt(); //时间加
return; //子程序返回
}
else
{
return;//子程序返回
}
}
B_JIAN0=0;B_JIAN1=0;B_JIAN2=0;B_JIAN3=0; //清除按键标志位
colk_stt(); // 时间+1
return;//子程序返回
}
else
{
return; //子程序返回
}
}
goto JIAN_add1; // B_JIAN1=1时,转JIAN_add1计算RB7按下的时间
//_________________________________________________________________________
}
if((KEY_UP==0)||(KEY_DOWN==0)) //
{
//_________________________________________
if((--kcon1)==0) //
{
kcon1=20; //设置按键连加时的速度计数值
colk_stt(); //
return;//子程序返回
}
else
{
return; //子程序返回
}
}
B_JIAN0=0;B_JIAN1=0;B_JIAN2=0;B_JIAN3=0;
return;
}
//---------------------------------------------
else if((KEY_UP==0)||(KEY_DOWN==0)) //比较KEY_UP键按下否
{
goto JIAN_add; //RB7=0, KEY_UP按下,转到连加处JIAN_ADD
}
//----------------------------------------------
else if((PORTA&0x08)!=0x08) //重读P1.2-P1.4位,若还是不全为1,定有键按下
{
delay_10ms();
if((PORTA&0x108)!=0x08)
{
di(); //
B_DP=0;B_COM=1;B_END=1;//
SEL++; //
if(SEL==0X01) //
{
keywait1(); //
RC1=0;RC2=1; //
buf[0]=T_ON0; buf[1]=T_ON1; buf[2]=T_ON2; buf[3]=T_ON3; //
B_ON=1;B_OFF=0,B_BUF=0; //
return;
}
if(SEL==0X02)
{
keywait1(); //
RC1=1;RC2=0; //
buf[0]=T_OFF0; buf[1]=T_OFF1; buf[2]=T_OFF2; buf[3]=T_OFF3; //
B_ON=0;B_OFF=1,B_BUF=0; //
return;
}
if(SEL==0X03)
{
keywait1();
RC1=1;RC2=1; //
buf[0]=colk0; buf[1]=colk1; buf[2]=colk2; buf[3]=colk3; //
SEL=0x00;sreg=0x00; msec=0x00;sec=0x00; B_ON=0; B_OFF=0,B_BUF=1; //
ei(); //开总中断
TMR0=0X14; //TMR0置初值
return;
}
}
}
//----------------------------------------------------------
B_JIAN0=0;B_JIAN1=0;B_JIAN2=0;B_JIAN3=0; //清除按键标志位
kcon1=20; //
CLRWDT(); //
}
//***********************************************************
//***********************************************************
//按键处理子程序 //
//***********************************************************
void keywork() //
{
if((PORTC&0x06)!=0x06) //如果P1.2--P1.4不为全1,可能有键按下
{
delay_10ms(); //延时去抖动
if((PORTC&0x06)!=0x06) //重读P1.2-P1.4位,若还是不全为1,定有键按下
{
//----------------------------------
if (KEY_SET==0) //按下SET键,如在SET状态就退出,否则进入
{
keywait();
ei(); //
TMR0=0X08; //
return; //
}
else if (KEY_UP==0) //按下UP键
{
keywait(); //
buf_initial(); //
di(); //
return;
}
}
}
else if((PORTA&0x10)!=0x10) //如果P1.2--P1.4不为全1,可能有键按下
{
delay_10ms(); //延时去抖动
if((PORTA&0x10)!=0x10) //重读P1.2-P1.4位,若还是不全为1,定有键按下
{
di(); //
keywait1(); //
add_colk(); //
return;
}
}
}
//*******************************
//*******************************
//****** Tmr0中断程序 ***********
//*******************************
void interrupt clkint(void)
{
TMR0=0x14; //
T0IF=0; //
CLRWDT(); //
sreg=sreg+1; //
if(sreg==40) //
{
sreg=0; //
msec=msec+1; //
if(msec>99) //
{
msec=0; //
B_DP=!B_DP; //
sec=sec+1; //
if(sec>59) //
{
sec=0; //
add_colk(); //
}
}
}
}
//*******************************
//主函数
//*******************************
void main(void) //
{
OPTION=0; //
ADCON1=0x07; // RA0-RA5=D
ADCON0=0B01001001;//
TRISA=0x38; //00111000= RA3,RA4,RA5
TRISB=0X00; //
TRISC=0X01; //
PORTB=0x00; //
PORTC=0X07; //
PORTA=0x38; //
B_DP=0; //
B_COM=0; //
B_END=0; //
B_ON=0; B_OFF=0,B_BUF=1;//
timr0int(); //
buf_initial(); //
di(); //
while(1) //
{
CLRWDT(); //
display(); //
keywork1(); //
if(B_COM==0) //
{
com_buf(); //
}
}
}
PCB图: