使用ATMega16单片机实现数码管00-99显示
最近学习了ATMega16单片机的中断系统,要求完成单片机外部中断的实践。
利用Mega16单片机的外部中断控制数码管计数显示。要求:
1、Mega16连接一个两位数码管,用于显示00—99的数字;
2、在mega16的PD2和PD3各接一个按键,一个为偶数计数键,一个为清零键。每按动一次偶数计数键数码管显示值按偶数计数方式递增一次;按动清零键,计数显示清零即数码管显示“00”
3、利用外部中断的方式实现两个按键检测。
我们可以在proteus中这样连接电路,其中BTN1为“偶数计数键”,BTN2为“清零键”,BTN3为“暂停键”。
我们在ICCAVR中这样编写程序,之后即可实现上述所有要求的功能。
PS:我也不知道为什么,代码和图片在电脑上直接就放在最后面了,似乎不能放在文字中间
# include 《iom16v.h》
#include《macros.h》
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_di***uffer(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_di***uffer(0);
display();
while(1)
{
if(key_flag == 1 )
{
scan_delayms(100);
N++;
number_to_di***uffer(N);
if(N》=99)
N=0;
}
if(key_flag == 0 )
{
scan_delayms(100);
}
}
}

使用ATMega16单片机实现数码管00-99显示
最近学习了ATMega16单片机的中断系统,要求完成单片机外部中断的实践。
利用Mega16单片机的外部中断控制数码管计数显示。要求:
1、Mega16连接一个两位数码管,用于显示00—99的数字;
2、在mega16的PD2和PD3各接一个按键,一个为偶数计数键,一个为清零键。每按动一次偶数计数键数码管显示值按偶数计数方式递增一次;按动清零键,计数显示清零即数码管显示“00”
3、利用外部中断的方式实现两个按键检测。
我们可以在proteus中这样连接电路,其中BTN1为“偶数计数键”,BTN2为“清零键”,BTN3为“暂停键”。
我们在ICCAVR中这样编写程序,之后即可实现上述所有要求的功能。
PS:我也不知道为什么,代码和图片在电脑上直接就放在最后面了,似乎不能放在文字中间
# include 《iom16v.h》
#include《macros.h》
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_di***uffer(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_di***uffer(0);
display();
while(1)
{
if(key_flag == 1 )
{
scan_delayms(100);
N++;
number_to_di***uffer(N);
if(N》=99)
N=0;
}
if(key_flag == 0 )
{
scan_delayms(100);
}
}
}

举报