使用ATMega16单片机实现数码管00-99显示

使用ATMega16单片机实现数码管00-99显示

最近学习了ATMega16单片机的中断系统,要求完成单片机外部中断的实践。
利用Mega16单片机的外部中断控制数码管计数显示。要求:
1、Mega16连接一个两位数码管,用于显示00—99的数字;
2、在mega16的PD2和PD3各接一个按键,一个为偶数计数键,一个为清零键。每按动一次偶数计数键数码管显示值按偶数计数方式递增一次;按动清零键,计数显示清零即数码管显示“00”
3、利用外部中断的方式实现两个按键检测。

我们可以在proteus中这样连接电路,其中BTN1为“偶数计数键”,BTN2为“清零键”,BTN3为“暂停键”。
我们在ICCAVR中这样编写程序,之后即可实现上述所有要求的功能。
PS:我也不知道为什么,代码和图片在电脑上直接就放在最后面了,似乎不能放在文字中间

# include 
#include
unsigned char disp_code[10]= {0x3F, 0x06, 0x5B, 0x4F,                    0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};
unsigned char position[2]= {0xfd,0xfe};
unsigned char dis_buff[2];
unsigned int Key_Time,key_flag,N;
 
#pragma interrupt_handler ext_int0_isr:2   //iv_INT0
void ext_int0_isr(void) 
{   // INT0中断服务程序 
	N=N+1;	
	if (N>=100) N=0; 
}  

#pragma interrupt_handler ext_int1_isr:3   //iv_INT1
void ext_int1_isr(void) 
{  // INT1中断服务程序 	
	N=-1; 
}  

/* 延时函数  */
void delay_ms(unsigned int i)
{  
	unsigned int a;	
	unsigned char b;	
	for (a = 0; a < i; a++) 	
	{		
		for (b=1; b; b++)
		{ 					 			;
		}	
	}
}

/* IO端口初始化  */
void port_init(void)
{  
	DDRA = 0x00;  
	PORTA= 0x01;  
	DDRC = 0xFF;  
	PORTC= 0xFF;  
	DDRD = 0x0F;  
	PORTD= 0x0F;
	}
	
/* 两位数码管扫描显示函数  */
void display(void)
{  
	unsigned char i;  
	for (i=0;i<=1;i++)  
	{      
		PORTC = disp_code[dis_buff[i]];      
		PORTD = position[i];      
		delay_ms(10);	    
		PORTD = 0xFF;  
	}
}

/* 数码管显示缓冲区更新函数  */
void number_to_disbuffer(unsigned char number)
{    
	dis_buff[0] = number % 10;   
	dis_buff[1] = number / 10;
}

/* 延时_动态扫描数码管函数  */
void show_delayms(unsigned int T)
{   
	unsigned char circle_time,i;   
	circle_time=T/25;   
	for(i=0;i<circle_time;i++)   
	{   	 
		delay_ms(21);  	   
		display();   
	}
}

/* 按键检测函数  */
int scan_key(void)
{   
	unsigned char key = 0;   
	if ( 0 == (PINA&0x01) )   
	{	  
		show_delayms(100);	  
		if( 0 == (PINA & 0x01) )	  
		{		  
			Key_Time++;		 
			key_flag = Key_Time % 2;	  
			key = 1;                
		}	
	}	
	return key;
}

/* 延时_按键检测函数  */
void scan_delayms(unsigned int T)
{   
	int i=0,key_press_ok = 0,sum;   
	sum = (T/100)*100 ;   
	while (i<=sum)   
	{     
		key_press_ok = scan_key();
		if(key_press_ok == 0)	  
		{	    
			display(); 	    
			i=i+4;	  
		}	  
		if(key_press_ok == 1)	   
		break;   
	}
}

 /* 主函数 */
 void main(void)
 {   
 	port_init();  
 	MCUCR=0x0A;
 	GICR|=0xC0;
 	SEI();                     //开全局中断   
 	SREG |=0x80  
 	Key_Time=0;
 	key_flag=1;
 	N=0;  
 	number_to_disbuffer(0);  
 	display();  
 	while(1)  
 	{	
 		if(key_flag == 1 )	
 		{	   
 			scan_delayms(100);	   
 			N++;
 			number_to_disbuffer(N);
 			if(N>=99) 
 				N=0;	
 		}	
 		if(key_flag == 0 )	
 		{	   
 			scan_delayms(100);	
 		}  
 	}
 }

使用ATMega16单片机实现数码管00-99显示_第1张图片

你可能感兴趣的:(ATMega16单片机)