发布时间:2025-10-15 17:58:27    次浏览
#includeiom16v.h#includemacros.h#includemath.h#defineucharunsignedchar#defineuintunsignedintucharconstseg_data={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff};//0~9和熄灭符的段码表ucharconstbit_tab={0xbf,0x7f}; //第7、8只数码管位选表uchar disp_buf[2]={0,0}; //定义2个显示缓冲单元uchar val;#define beep_0 (PORTD=PORTD0xbf) //PD6上的蜂鸣器发声#define beep_1 (PORTD=PORTD|0x40) //PD6上的蜂鸣器不发声/********函数功能:延时函数********/void Delay_ms(uint xms){int i,j;for(i=0;ixms;i++){ for(j=0;j1140;j++) ; }}/*********以下是蜂鸣器响一声函数********/void beep(){uint bb;for(bb=0;bb10;bb++){beep_0; //蜂鸣器响Delay_ms(1);beep_1; //关闭蜂鸣器Delay_ms(1);}}/********端口设置函数********/void port_init(void){PORTA = 0xFF; //输出高电平DDRA = 0xFF; //设为输出PORTC = 0xff; //输出高电平DDRC = 0xFF; //设为输出DDRD =(0PD2)|(1PD6);//PD2(接K1键)设为输入,PD6设为输出PORTD = 0xFF; //PD6输出高电平,其它为带上拉的输入}/********定时器0初始化********/void timer0_init(){SREG = 0x80; //使能全局中断TIMSK|=(1TOIE0); //使能T0溢出中断TCCR0|=(1CS02)|(0CS01)|(1CS00); // T/C0工作于普通模式,1024分频, TCNT0 = 240; //定时初值设置,定时时间2ms}/********以下是显示函数********/void Display(){uchar tmp; //定义显示暂存static uchar disp_sel=0; //显示位选计数器,显示程序通过它得知现正显示哪个数码管,初始值为0tmp=bit_tab[disp_sel]; //根据当前的位选计数值决定显示哪只数码管PORTC=tmp; //送PC控制被选取的数码管点亮tmp=disp_buf[disp_sel]; //根据当前的位选计数值查的数字的显示码tmp=seg_data[tmp]; //取显示码PORTA=tmp; //送到PA口显示出相应的数字disp_sel++; //位选计数值加1,指向下一个数码管if(disp_sel==2)disp_sel=0; //如果2个数码管显示了一遍,则让其回0,重新再扫描}/********以下是定时器T0中断函数, 用于数码管的动态扫描********/#pragma interrupt_handler timer0_ovf:10void timer0_ovf(void){TIFR=0x01; //写1清除定时器T0标志位TCNT0=240; //置计数初值,设置定时时间为2msDisplay(); //调显示函数}/********向EEPROM写入一个字节数据函数********/void EEPROM_write(uint uiAddress,uchar ucData){while(EECR(1EEWE)); //等待上一个数据写完毕EEAR=uiAddress; //把地址写入寄存器EEDR=ucData; //把数据写入寄存器EECR|=(1EEMWE); //主机写入允许EECR|=(1EEWE); //允许EEPROM}/********从EEPROM读出一个字节数据********/uchar EEPROM_read(uint uiAddress){while(EECR(1EEWE)); //等待上一个数据写完毕EEAR=uiAddress; //写地址EECR|=(1EERE); //读允许return EEDR; //返回数据寄存器中的值}/********以下是主函数********/void main(){timer0_init();port_init();Delay_ms(100);val=EEPROM_read(0x01); //从AT mega16内部EEPROM的0x01地址中读取数据if(val=100) val=0; //防止首次读取EEPROM数据时出错while(1){if((PIND0x04)==0) //若K1键按下{Delay_ms(10); //延时10ms去抖if((PIND0x04)==0){while(!(PIND0x04)); //等待K1键释放val++;EEPROM_write(0x01, val);//将数据val写入到ATmega16内部EEPROM的0x01地址中beep();if(val==99)val=0;}}disp_buf[0]=val/10;disp_buf[1]=val%10;}}原文链接:http://www.eeworld.com.cn/mcu/article_2016102630889.html