显示时和分(可调)
#include"iom16v.h"
unsigned char code[] = { 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71 }; //段码
unsigned char ledbuff[4] = { 0x7f, 0xbf, 0xdf, 0xef }; //位码
unsigned char k = 1; //刷新位
unsigned char dot = 0x80;//小数点
unsigned char sec = 0; //秒
unsigned int min = 480; //分 初始时间 08:00
void delay(void) //数码管余辉延时
{
int i = 0;
for (i = 100; i > 0; i--);
}
void delay_ms(unsigned int millisecond)//ms延时
{
unsigned int ms;
for (ms = millisecond; ms > 1; ms--)
{
for (millisecond = 999; millisecond > 1; millisecond--);
}
}
//io初始化
void io_init(void)
{
//数码管
DDRD = 0xf0;
//PORTD = 0xff;
DDRC = 0xff;
//PORTC = 0xff;
//按键
DDRB = ~(0b00011111); //PB0~PB4输入
PORTB = 0b00011111;
}
//定时器初始化 t1 256分频
void t1_init(void)
{
//TCCR1A = 0x40; //比较匹配时置位 OC1A/OC1B ( 输出高电平 )
TCCR1B = 0x04; //256分频
TCNT1 = 34285;
//OCR1A = 31250;
TIMSK = 0x04; //溢出中断使能
SREG = 0x80; //全局中断使能
}
void decode(unsigned int min) //数码管显示
{
//获取段码号
unsigned char a;
unsigned char b;
unsigned char c;
unsigned char d;
a = (min / 60) / 10;//时十位
b = (min / 60) % 10;//时个位
c = (min % 60) / 10;//分的十位
d = (min % 60) % 10;//分的个位
k = (++k) % 4;
PORTD = ledbuff[k];
switch (k)
{
case 0:
PORTC = code[a]; //时十位
delay();
break;
case 1:
PORTC = code[b]; //时个位
PORTC |= dot; //点闪烁代表秒
delay();
break;
case 2:
PORTC = code[c]; //分十位
delay();
break;
case 3:
PORTC = code[d]; //分个位
delay();
break;
default:;
}
}
//t1 溢出中断
#pragma interrupt_handler time1:9
void time1(void)
{
TCNT1 = 34285;
//OCR1A = 31250;
sec = sec + 1; //时间增加
if (sec > 59) //60秒后
{
sec = 0; //重新置零
min = min + 1;
if (min > 1439) //24小时 60*24
{
min = 0;
}
}
dot ^= 0x80;
}
void time_set(void) //真实时间设置
{
while (1)
{
if ((PINB & 0x01) == 0)
{
delay_ms(110);
if ((PINB & 0x01) == 0)
{
min = min + 60;
if (min > 1380) //超23小时置零
{
min = 0;
}
}
}
if ((PINB & 0x02) == 0)
{
delay_ms(110);
if ((PINB & 0x02) == 0)
{
min = min + 1;
if (min > 1439)
{
min = 0;
}
}
}
decode(min);
}
}
void clock_set(void)
{
while (1)
{
if ((PINB & 0x08) == 0) //按下按键S4时开始设置闹钟
{
TIMSK &= ~0x04; //关闭中断使能
while (1)
{
if ((PINB & 0x01) == 0) //确定按键被按下
{
delay_ms(100);
if ((PINB & 0x01) == 0) //确定按键被按下
{
min_clock = min_clock + 60; //加60分钟/1个小时
}
}
if ((PINB & 0x02) == 0) //确定按键被按下
{
delay_ms(100);
if ((PINB & 0x02) == 0) //确定按键被按下
{
min_clock = min_clock + 1; //加1分钟
}
}
if (min_clock > 1440) //超24小时重新置零
{
min_clock = 0;
}
decode(min_clock);
}
}
}
}
void main(void)
{
io_init(); //端口初始化
t1_init(); //定时器初始化
time_set();
}