/************************************************************************************
***              慧净电子10天学会AVR单片机与C语言视频教程配套程序源码             ***
*** 实验目的:HJ-1 M16 AVR实验板  《推荐用慧净电子的HJ-2G AVR多功能二合一开发板》 ***
*** MCU: ATmega16  部分C源码可以直接用于项目开发、欢迎复制共享、没有版权          ***
*** 作者:慧净免费助学会员  部分源码网上收集整理 感谢有共享精神的朋友             ***
*** 编译器:GCC                                                                   ***
                                      ***
                       ***
*** 日期:2008.12.18                                                              ***
*** 目标:用C语言写程序就这么简单:《1天入门、10天学会、1年精通单片机系列源码》   ***
*************************************************************************************/
//程序说明:
#include <avr/io.h>        
#include <util/delay.h>
#include <avr/interrupt.h>   //中断函数头文件

unsigned char Disp_Buff[17] = {
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8, 
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x00};
				//数码管字型码表显示:0,1,2,3,4,5,6,7,8,9,A,b,C,d,E,F
volatile unsigned char Counter;  //按键按下次数变量,如果在中断中调用全局变量,必须加
                                 //volatile来定义,否则变量不会变化
int main(void)            
{
		
	PORTB = 0X00;      //
	DDRB = 0Xff;      //
	
	//PORTC &= ~(1 << PC6);  //配置数码管0的位选通口为低电平,不导通数码管
	//DDRC |= (1 << PC6);    ///配置数码管0的位选通口为输出,选通数码管0
/*	
	//PORTD = 0X08;     //一定要使能K2的上拉电阻,否则会有干扰
	PORTD = 0X00;//自己接下拉电阻
	DDRD = 0XF3;      //K1、K2按键(PD2、PD3)设置为输入端口
	
	MCUCR |= (1 << ISC11) | (1 << ISC01) | (1 << ISC00);   
	                            //INT0设置为上升沿中断,INT1为下降沿中断请求
    GICR |= (1 << INT0) | (1 << INT1);      //允许INT0、INT1中断
	GIFR |= (1 << INTF1) | (1 << INTF0);    //清除INT0、INT1中断标志位
*/
///
	//T/C0定时中断设置
	TIMSK |= (1 << TOIE0);           //T/C0溢出中断允许
	TCCR0 |= (1 <<CS02) | (1 << CS00);  // T/C0工作于普通模式,1024分频,
	                                //定时器频率 = 1M/1024 = 976.5625Hz
	TCNT0 =  12;                   //定时初值设置,定时时间 = (256-12)/976.5625=249.856ms

//	
	Counter = 0;                //按键按下次数变量清零
	//PORTC |= (1 << PC6);       //选通数码管0

    sei();          //使能全局中断  
	
	while(1)
	{
		PORTB = Disp_Buff[Counter];		//数码管显示按键按下次数
	}
}

/*
//外部中断0函数,当按键K1按下后,进入此中断
ISR(INT0_vect )            
{		
	_delay_ms(20);         //按键按下,延时一会再判断是否按下, 以消除干扰
	if((PIND & (1 <<  PD2)))    // 按键真正按下后,进行相应处理
	{
		if(++Counter >= 16) Counter = 0;	//次数大于15,清零
		while((PIND & (1 <<  PD2)));//等待按键释放				
	}		
}

//外部中断1函数,当按键K2按下后,进入此中断
ISR(INT1_vect)
{		
	_delay_ms(20);         //判断按键按下,延时一会再判断是否按下, 以消除干扰
	if(!(PIND & (1 <<  PD3)))    // 按键真正按下后,进行相应处理
	{
		if(Counter) --Counter;	  // 次数减1
		else Counter = 15;   //   次数为零则改成15
		
		while(!(PIND & (1 <<  PD3)));  //
		
	}
}
*/

//
//T/C0定时中断服务程序
ISR(TIMER0_OVF_vect )
{
	TCNT0 = 12;        //重装计数初值
	if(++Counter >= 16)        //定时时间到1S吗?定时中断溢出4次为1S
	{
		//PORTB ^= (1 << PB0);       //放光二极管亮灭变化
		Counter = 0;           //1S计时变量清零
	}
}