#defineuchar unsigned char
#defineuintunsigned int
#defineulong unsigned long int
volatile uint nowtime; //计时变量。然后下面的几个变量是一些逻辑控制的
volatile uint ledmode;
volatile uint shangkeledmode;
volatile uint shangkeledtime;
volatile uint class; //上下课逻辑,上课为1,下课为0,见主函数
#include
#include
void port_init(void)
{
B=0xFF;
PORTB=0x00;
DDRC=0xFF;
DDRA=0XFF;
DDRD|=0XF0;
//初始化IO口
}
void timer0_init(void)
{
TCCR0 = 0x00;
TC 0 = 0x06;
OCR0= 0xFA;
TCCR0 = 0x03;
//初始化timer0
}
//timer0本系统中用于控制上下课指示灯闪烁
#pragma interrupt_handler timer0_ovf_isr:iv_ M0_OVF
void timer0_ovf_isr(void)
{
tm0rsf(); //别看漏
TCNT0 = 0x06;
}
//TIMER1 initialize - prescale:256
// WGM: 0) Normal, TOP=0xFFFF
// desired value: 1Sec
// actual value:1.000Sec (0.0%)
void timer1_init(void)
{
TCCR1B = 0x00; //stop
TCNT1H = 0x0B; //setup
TCNT1L = 0x ;
OCR1AH = 0xF4;
OCR1AL = 0x24;
OCR1BH = 0xF4;
OCR1BL = 0x24;
ICR1H= 0xF4;
ICR1L= 0x24;
TCCR1A = 0x00;
TCCR1B = 0x04; //start Timer
//初始化timer1
}
//timer1本系统中用于上课时间和下课时间计时
#pragma interrupt_handler timer1_ovf_isr:iv_TIM1_OVF
void timer1_ovf_isr(void)
{
tm1rsf(); //哈哈可能有人漏看了这里,回调函数执行另一个函数,这样程序看起来更整洁,这是我的编程习惯^v^
TCNT1H = 0x0B;
TCNT1L = 0xDC; //重载高低值
//timer1回调函数
}
void init_devices(void)
{
CLI();
port_init();
timer0_init();
timer1_init();
CR = 0x00;
GICR= 0x00;
TIMSK = 0x05;
();
}
void delay(uint ms) //这个就不用说了 死循环延迟
{
uint i,j;
for(i=0;i
for (j=0;j<2300;j++);
}
}
void tm0rsf() //控制上课指示灯闪烁的函数,不喜欢写在回调函数里,这样程序看起来更工整。。。
{
if(class==1) //是否上下课,上课就闪,下课就不闪。
{
shangkeledtime++;
if (shangkeledtime==150) //150ms闪一下。其他自己看吧。。。。
{
shangkeledtime=0;
if(shangkeledmode==1) //开灯,相应IO输出高电平
{
PORTA|=0X54;
PORTC|=0x02;
PORTD|=0x20;
shangkeledmode=0;
}
else //关灯,相应IO输出低电平(接地)
{
PORTA&=0X03;
PORTC&=0xFC;
PORTD&=0 F;
shangkeledmode=1; //逻辑自己看吧。。。。
}
}
}
else
{
PORTA&=0X03;
PORTC&=0xFC;
PORTD&=0XDF;
}
}
void tm1rsf() //timer1回调函数执行的函数
{
nowtime++; //计时变量自增
if(ledmode==1) //嗯这个就是控制D0 LED闪烁的了,主要就是看timer1是不是在走。
{
ledmode=0;
PORTA|=0x01;
}
else
{
ledmode=1;
PORTA&=0XFE;
}
}
void ring() //响铃函数,控制继电器的。。(PC7输出高电平)
{
PORTC=0xFF; //因为PC口只有用到一个PC7所以不管这么多懒得算了直接全部输出高电位
delay(300);
PORTC=0x00;
delay(8300);
PORTC=0xFF;
delay(300);
PORTC=0x00;
delay(8300);
}
uchar key_press() //检测K1K2是否按下。。
{
uchar j;
DDRD|=0X0F;
PORTD|=0X0F;
DDRD&=0XF0;
j=PIND;
j=j&0X0F;
if(j==0X0F)
{
return 0;
}
else
{
return 1;
}
}
uchar key_scan() //检测是K1还是K2按下。。
{
uchar key;
delay(10);
if(key_press())
{
key=PIND;
key&=0X0F;
switch(key)
{
case 0X0E:
key=1;
break;
case 0X0D:
key=2;
break;
default:
key=0;
}
while(key_press());
}
else
{
key=16;
}
return key;
}
void main() //好了主函数开始了。。。
{
uchar i,j;
uint k,mode;
uint ledmode;
init_devices(); //初始化IO。。上面有。
k=0;
ledmode=1; //逻辑自己看,不用解释。。。
while(k==0) //注意了 这一段是上电后等待按下K1K2的。
{
if(ledmode==1) //上电后LED走马灯在那狂闪(按下之前)
{
PORTB=0XF0;delay(80);
ledmode=0;
}
else{PORTB=0X0F;delay(80);ledmode=1;}
i=key_press();
if(i)
{ //判断按的哪个
j=key_scan();
if (j==1)
{mode=1;k=1;}
if (j==2)
{mode=2;k=1;}
}
}
if (mode==1) //如果按的K1,也就是早上用,有早读的
{
uint o