AVR单片机Atmega16电子时钟程序+仿真,内部定时器实现
2019-10-18 来源:eefocus
Atmega16电子时钟,内部定时器,有可调闹钟。
仿真原理图如下
单片机源程序如下:
#include #include #define key_bz 0b00000111 char smg_zx[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d, 0x7d,0x07,0x7f,0x6f};// 全局变量 char hour=12; char min; char sec; char nz_hour=12; char nz_min=1; char mode=0; char set; void delay_ms(unsigned int k) { unsigned int i,j; for(i=0;i for(j=0;j<570;j++); } } // 用定时器实现定时 void T0_init(void)// 端口初始化函数 { TIFR=0XFF; TCCR0=0X0B; //64FENPIN, CTC MODE TCNT0=0; OCR0=250; TIMSK=0X02; } void port_init(void)// 端口初始化函数 { DDRC |= 0b11110000; // PC4 5 OUT PUT PORTC |= 0b00111111; //m103 output only PORTD = 0x00; // 上电关闭数码管, 因为上电电压不稳 DDRD = 0xff; DDRB |= 0b11100000; // PC5 6 7OUT PUT } //call this routine to initialize all peripherals void init_devices(void) { //stop errant interrupts until set up CLI(); //disable all interrupts port_init();//smg_zx[0]=1; T0_init(); SEI(); //re-enable interrupts //all peripherals are now initialized } //miao=45; void key (void) { if(!(PINC&0X01)) { delay_ms(2); if(!(PINC&0X01)) { TIMSK=0X00; mode++; mode%=3; set=0; if(mode==0)TIMSK=0X02; while(!(PINC&0X01)); } } if(!(PINC&0X02)) { delay_ms(2); if(!(PINC&0X02)) { if(mode==1) { set++; set%=3; } if(mode==2) { set++; set%=2; } while(!(PINC&0X02)); } } if(!(PINC&0X04)) { delay_ms(2); if(!(PINC&0X04)) { if(mode==1) { if(set==0) { hour++; hour%=24; } if(set==1) { min++; min%=60; } if(set==2) { sec++; sec%=60; } } if(mode==2) { if(set==0) { nz_hour++; nz_hour%=24; } if(set==1) { nz_min++; nz_min%=60; } } while(!(PINC&0X04)); } } } //主函数 void main() {/// 变量声明 char zz; // 调用初始化哈数 //port_init(); init_devices(); // 特定代码 while(1) { if(mode==0) { PORTD=~smg_zx[hour/10]; // 给5的字形编码 PORTB|=1< PORTB&=0B00111111;// PORTD=~smg_zx[hour%10]; // 给5的字形编码 PORTB|=1< PORTB&=0B00111111;// PORTD=~smg_zx[min/10]; // 给5的字形编码 PORTC|=1< PORTC&=0B00001111;// PORTD=~smg_zx[min%10]; // 给5的字形编码 PORTC|=1< delay_ms(2); PORTC&=0B00001111;// PORTD=~smg_zx[sec/10]; // 给5的字形编码 PORTC|=1< PORTC&=0B00001111;// PORTD=~smg_zx[sec%10]; // 给5的字形编码 PORTC|=1< PORTC&=0B00001111;// } else if(mode==1) { PORTD=~smg_zx[hour/10]; // 给5的字形编码 PORTB|=1< PORTB&=0B00111111;// PORTD=~smg_zx[hour%10]; // 给5的字形编码 if(set==0) PORTD&=0x7f;//控制小数点亮 PORTB|=1< PORTB&=0B00111111;// PORTD=~smg_zx[min/10]; // 给5的字形编码 PORTC|=1< PORTC&=0B00001111;// PORTD=~smg_zx[min%10]; // 给5的字形编码 if(set==1) PORTD&=0x7f;//控制小数点亮 PORTC|=1< delay_ms(2); PORTC&=0B00001111;// PORTD=~smg_zx[sec/10]; // 给5的字形编码 PORTC|=1< PORTC&=0B00001111;// PORTD=~smg_zx[sec%10]; // 给5的字形编码 if(set==2) PORTD&=0x7f;//控制小数点亮 PORTC|=1< PORTC&=0B00001111;// } else if(mode==2) { PORTD=~smg_zx[nz_hour/10]; // 给5的字形编码 PORTB|=1< PORTB&=0B00111111;// PORTD=~smg_zx[nz_hour%10]; // 给5的字形编码 if(set==0) PORTD&=0x7f;//控制小数点亮 PORTB|=1< PORTB&=0B00111111;// PORTD=~smg_zx[nz_min/10]; // 给5的字形编码 PORTC|=1< PORTC&=0B00001111;// PORTD=~smg_zx[nz_min%10]; // 给5的字形编码 if(set==1) PORTD&=0x7f;//控制小数点亮 PORTC|=1< PORTC&=0B00001111;// } if((hour==nz_hour)&&(min==nz_min))//闹钟 { if(zz++>20) { PORTB^=1< } } else PORTB|=1< key (); } } //T0中断服务程序 // 2ms 进入中断 #pragma interrupt_handler timer0_ocf_isr:20 void timer0_ocf_isr(void) {static int count=0; if(++count>=500) { count=0; sec++; if(sec>=60) { sec=0; min++; if(min>=60) { min=0; hour++; hour%=24; } } } }