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<
delay_ms(2);
PORTB&=0B00111111;//
PORTD=~smg_zx[hour%10]; // 给5的字形编码
PORTB|=1<
delay_ms(2);
PORTB&=0B00111111;//
PORTD=~smg_zx[min/10]; // 给5的字形编码
PORTC|=1<
delay_ms(2);
PORTC&=0B00001111;//
PORTD=~smg_zx[min%10]; // 给5的字形编码
PORTC|=1<
delay_ms(2);
PORTC&=0B00001111;//
PORTD=~smg_zx[sec/10]; // 给5的字形编码
PORTC|=1<
delay_ms(2);
PORTC&=0B00001111;//
PORTD=~smg_zx[sec%10]; // 给5的字形编码
PORTC|=1<
delay_ms(2);
PORTC&=0B00001111;//
}
else if(mode==1)
{
PORTD=~smg_zx[hour/10]; // 给5的字形编码
PORTB|=1<
delay_ms(2);
PORTB&=0B00111111;//
PORTD=~smg_zx[hour%10]; // 给5的字形编码
if(set==0) PORTD&=0x7f;//控制小数点亮
PORTB|=1<
delay_ms(2);
PORTB&=0B00111111;//
PORTD=~smg_zx[min/10]; // 给5的字形编码
PORTC|=1<
delay_ms(2);
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<
delay_ms(2);
PORTC&=0B00001111;//
PORTD=~smg_zx[sec%10]; // 给5的字形编码
if(set==2) PORTD&=0x7f;//控制小数点亮
PORTC|=1<
delay_ms(2);
PORTC&=0B00001111;//
}
else if(mode==2)
{
PORTD=~smg_zx[nz_hour/10]; // 给5的字形编码
PORTB|=1<
delay_ms(2);
PORTB&=0B00111111;//
PORTD=~smg_zx[nz_hour%10]; // 给5的字形编码
if(set==0) PORTD&=0x7f;//控制小数点亮
PORTB|=1<
delay_ms(2);
PORTB&=0B00111111;//
PORTD=~smg_zx[nz_min/10]; // 给5的字形编码
PORTC|=1<
delay_ms(2);
PORTC&=0B00001111;//
PORTD=~smg_zx[nz_min%10]; // 给5的字形编码
if(set==1) PORTD&=0x7f;//控制小数点亮
PORTC|=1<
delay_ms(2);
PORTC&=0B00001111;//
}
if((hour==nz_hour)&&(min==nz_min))//闹钟
{
if(zz++>20)
{
PORTB^=1<
zz=0;
}
}
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)
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』