//有两个按键,其中一个接INT0,另一个接PD7
//启动时,数码管显示00.00 ,按下INT0 ,开始计时
//再按下INT0,计时停止。
//无论何时,按下PD7,计时清零。
//问题在于:时间不准,比1秒慢。时间转过一分钟,计时只有36秒。此时熔丝位为
#includeconst unsigned char duanma[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; const unsigned char weima[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; unsigned char shu[8]; unsigned int aa; unsigned int cnt; /**************************************** 延时函数 ****************************************/ void delay(unsigned char t) { unsigned char x,y; for(x=t;x>0;x--) for(y=100;y>0;y--); } /**************************************** 显示函数 ****************************************/ void display(void) { unsigned char i; for(i=0;i<4;i++) { PORTB =0X00; PORTA|=0X01; PORTA&=0XFE; PORTB =weima[i]; PORTA|=0x02; PORTA&=0XFD; PORTB=shu[i]; PORTA|=0X01; PORTA&=0XFE; delay(3); } } /*************************************** 数据转换子函数 ***************************************/ void change(unsigned int i) { shu[0]=duanma[i/1000]; shu[1]=duanma[i/100%10]|0x80; shu[2]=duanma[i%100/10]; shu[3]=duanma[i%10]; } /*************************************** 端口初始化 ***************************************/ void init_port(void) { PORTA=0XFF; DDRA=0XFF; PORTB=0XFF; DDRB=0XFF; PORTD=0XFF; DDRD=0X7B; // 0111 1011 } /*************************************** 按键检测 ***************************************/ void keyscan(void) { if((PIND&0X80)!=0X80) { change(cnt); display(); //延时 display(); if((PIND&0X80)!=0X80) { cnt=0; //按键按下 计数清零 } } } /*************************************** 定时器1初始化 ***************************************/ void timer1_init(void) { TCNT1H=0xd8; //装10ms的定时器初值 TCNT1L=0xf0; } /*************************************** 定时器1服务函数 ***************************************/ #pragma interrupt_handler timer1_ovf_isr:9 void timer1_ovf_isr(void) { TCNT1H=0XD8; //重装10ms的定时器初值 TCNT1L=0XF0; if(++cnt>9999) cnt=0; } /*************************************** INT0中断服务子函数 ***************************************/ #pragma interrupt_handler int0_isr:2 void int0_isr(void) { if(cnt<10) TCCR1B=0x02; //启动定时器1 else TCCR1B=0x00; //关闭定时器1 } /*************************************** IO及中断初始化 ***************************************/ void init_interrupt(void) { init_port(); //IO初始化 timer1_init(); //定时器1初始化 MCUCR=0X02; //INT0下降沿触发 GICR=0X40; //使能INT0 TIMSK=0X04; //使能T1中断 SREG=0X80; //使能总中断 } /*************************************** MAIN ***************************************/ void main(void) { init_interrupt(); while(1) { change(cnt); display(); keyscan(); } }
上一篇:ATmega16L-定时器数码管扫描
下一篇:ATmega16L-EEPROM读写操作实验
推荐阅读最新更新时间:2024-03-16 13:06
- 热门资源推荐
- 热门放大器推荐
设计资源 培训 开发板 精华推荐
- Allegro MicroSystems 在 2024 年德国慕尼黑电子展上推出先进的磁性和电感式位置感测解决方案
- 左手车钥匙,右手活体检测雷达,UWB上车势在必行!
- 狂飙十年,国产CIS挤上牌桌
- 神盾短刀电池+雷神EM-i超级电混,吉利新能源甩出了两张“王炸”
- 浅谈功能安全之故障(fault),错误(error),失效(failure)
- 智能汽车2.0周期,这几大核心产业链迎来重大机会!
- 美日研发新型电池,宁德时代面临挑战?中国新能源电池产业如何应对?
- Rambus推出业界首款HBM 4控制器IP:背后有哪些技术细节?
- 村田推出高精度汽车用6轴惯性传感器
- 福特获得预充电报警专利 有助于节约成本和应对紧急情况