单片机源程序如下:
#include
#include
#define key_bz 0b00000111
#define uchar unsigned char
#define uint_16 unsigned short
char smg_zx[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d, 0x7d,0x07,0x7f,0x6f,0x37};// 全局变量
char smg_wx[]={0B00000001,0B00000010,0B00000100,0b00001000};
char smg_oFF[]={0x3f,0X71,0X71};
unsigned int flag_10ms=0,flag_1s=0,on=0,buff[]={0,0,0},mode=0;
unsigned int jh_hour1=2,u=0,count=0,count1=2,on_sec=0;
unsigned int jh_sec1=5,jh_hour=0,jh_sec=0,flag=0;
unsigned long int jishi_sec=0;
void delay_ms(unsigned int k)
{
unsigned int i,j;
for(i=0;i
{
for(j=0;j<570;j++);
}
}
// 用定时器实现定时
void T0_init(void)// 端口初始化函数
{
TIFR=0XFF;
TCCR0=0X0B; //64FENPIN, CTC MODE
TCNT0=0;
OCR0=250;
TIMSK=0X02;
}
void port_init(void)// 端口初始化函数
{
DDRC|=0b10001111; // PC4 5 OUT PUT
PORTC=0b11110000; //m103 output only
PORTD= 0xFF;
DDRD= 0xff;
DDRB&= 0b11111000;
PORTB|=0B00000111;
}
void init_devices(void)
{
CLI(); //disable all interrupts
port_init();//smg_zx[0]=1;
T0_init();
SEI(); //re-enable interrupts
}
////多位数拆分函数///////*/
void xs_buff(uchar va1, uchar va2)
{
buff[0]=va1/10;
buff[1]=va1%10;
buff[2]=va2/10;
buff[3]=va2%10;
}
void xs_buff_on( uchar va2)
{
buff[0]=0;
buff[1]=10;
buff[2]=va2/10;
buff[3]=va2%10;
}
void xs_smg()
{//char smg_zx[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,
// 0x7d,0x07,0x7f,0x6f};// 局部变量
static unsigned char posit=0;
PORTC&=0X80; // turn off
PORTC|=smg_wx[posit];//selecting led 7-segment
PORTD=~smg_zx[buff[posit]]; //
if(posit++>=3)posit=0;
}
////////////////////////////////////////////////////////////
void smg_xs(void)
{
if((count<=20)||(flag==1))
{
if((on!=1)&&(on!=2))
{
xs_buff(jh_hour,jh_sec);
xs_smg();
}
else
{
if((on==1))
{ xs_buff_on(on_sec);
xs_smg();
}
else if(on==2)
{PORTC&=0X80;on_sec=0;
PORTD=~smg_oFF[u];
PORTC|=smg_wx[u];if(u++>=2)u=0;
}
}
}
else
{PORTC&=0X80;count1=0;}
}
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
void motor(void)
{
if(on==1)
{PORTC|=0X80;flag=1;
}
else
{
on_sec=0;
if(on==2){PORTC&=0X7F;flag=0;}//off状态下关闭电机
else if((jishi_sec>jh_hour1*3600)&&(jishi_sec<=jh_hour1*3600+jh_sec1))//大于设定的时间间隔和浇花时长
{PORTC|=0X80;//开电机
flag=1;}
else
{
PORTC&=0X7F;flag=0;
if(jishi_sec>jh_hour1*3600+jh_sec1)
jishi_sec=0;
}
}
}
///////////////////////////////////////////////////////////////////////////////////
/// 按键子程序,实现按键值返回
uchar key(void)
{ static uchar key_zt=1, key_value;
uchar returnvalue=100; // 100表示无按键对应的一个数值
switch(key_zt) // 0b00000111 /0b00000110 //0b00000110
{
case 1:if((PINB&key_bz)!=key_bz)
{key_value=PINB&key_bz;
key_zt=2;}
break;
case 2: if((PINB&key_bz)==key_value)
{key_zt=3;
switch(key_value)
{
case 0b00000110:
returnvalue=1; //切换模式
break;
case 0b00000101:
returnvalue=2;//在时分之间切换
break;
case 0b00000011:
returnvalue=3;//在时分之间切换
break;
}
}else key_zt=1;
break;
case 3:
if((PINB&key_bz)==key_bz)
key_zt=1;
break;
}
return returnvalue;
}
// 根据按键子程序返回的按键值去执行相应的功能
void key_process(void)
{
switch(key())
{ case 1:count=0;count1++;if(count1>1){count1=2;if(on==0)/*只有on=0,回归正常显示界面才能加*/{if(jh_hour++>=99)jh_hour=0;}}break; //mode:0-计时,1,校准,2闹钟 // 模式切换
case 2:count=0;count1++;if(count1>1){count1=2;if(on++>=2){on=0;jishi_sec=0;}}break;//每手动开启电机,jishi_sec就赋零
case 3:count=0;count1++;if(count1>1){count1=2;if(on==0)/*只有on=0,回归正常显示界面才能加*/{if(jh_sec++>=99)jh_sec=0;}}break;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void sj_lj(void)
{
jishi_sec++;
if(jishi_sec%3600==0&&jishi_sec!=0)jh_hour--;
if(jh_hour==0){if(jh_sec--<=0){jh_hour=jh_hour1;jh_sec=jh_sec1;}}
}
//主函数////////////////////////////////////////////////////////////////////////////////////
void main(void)
{
jh_hour=jh_hour1;
jh_sec=jh_sec1;
init_devices();
while(1)
{
motor();
smg_xs();
if(flag_1s==1)
{flag_1s=0;
sj_lj();}
if(flag_10ms==1)
{flag_10ms=0;
key_process();}
}
}
/////////////////
//////////////
//T0中断服务程序 // 2ms 进入中断
#pragma interrupt_handler timer0_ocf_isr:20
void timer0_ocf_isr(void)
{static uint_16 count_1s=0,count_10ms=0,count_5s=0;
if(++count_10ms>=5)
{ count_10ms=0;
flag_10ms=1;
if(++count_1s>=100)
{count_1s=0;
flag_1s=1;
count++;
if(on==1)
on_sec++;
}
}
}
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』