📄 clock.c
字号:
/************************************************************/
/* 广州天河双龙电子有限公司 */
/* http://www.sl.com.cn */
/* 电脑时钟演示程序(ICCAVR版本) */
/* 程序作者:詹卫前 */
/*接线方式:CS=PORTC.4 CLK=PORTC.3 DATA=PORTC.2 KEY=PORTC.1 */
/* 处理器:AT90S8515 晶振频率:8MHZ */
/* SL279 晶振频率:12MHZ 使用SLAVR库 */
/************************************************************/
#include<io8515.h>
#include<slavr.h>
#pragma interrupt_handler timer1_ovf:7
#pragma interrupt_handler timer0_ovf:8
#define setcs PORTC|=0x10;
unsigned char flag=0;//时间刷新标志
unsigned char dflag=0;//计数方向标志
/* 定义结构体time */
struct time
{
signed char second;
signed char minute;
signed char hour;
} time;
/* 字节接收函数 */
unsigned char receive_byte(void)
{
unsigned char i,temp=0;
DDRC&=0xfb;
delay_us(90);
for(i=0;i<8;i++)
{
temp=temp<<1;
PORTC|=0x08;//clk=1
delay_us(10);
if((PINC&0x04)!=0)
temp|=0x01;
PORTC&=0xf7;//clk=0
delay_us(10);
}
DDRC|=0x04;
return temp;
}
/* 字节发送函数 */
void send_byte(unsigned char para)
{
unsigned char i;
PORTC&=0xef;//cs=0
delay_us(90);
for(i=0;i<8;i++)
{
if((para&0x80)==0x80)
PORTC|=0x04;//data=1
else
PORTC&=0xfb;//data=0
PORTC|=0x08;//clk=1
delay_us(10);
PORTC&=0xf7;//clk=0
delay_us(10);
para=para<<1;
}
}
/* 写sl279双字节命令 */
void write279(unsigned char cmd1, unsigned char cmd2)
{
send_byte (cmd1);
send_byte (cmd2);
PORTC|=0x10;
}
/*在启动时设置时间,按shift键后进入计时状态*/
void initdis()
{
unsigned char i=7;
unsigned char key=0;
write279(0xc8,0);
write279(0xc9,0);
write279(0x92,1);
write279(0xcb,0);
write279(0xcc,0);
write279(0x95,1);
write279(0xce,0);
write279(0xcf,0);
write279(0x88,0x7f);
do
{
while((PINC&0x02)!=0)
;
send_byte(0x15);
key=receive_byte();
setcs;
switch (i)
{
case 7:{
if(key<3)
{
write279(0xc8+i,key);
i--;
write279(0x88,0xbf);
time.hour=time.hour%10+key*10;
}
break;
}
case 6:{
if(key<10)
{
if((time.hour<20)|(key<4))
{
write279(0xc8+i,key);
i--;
i--;
write279(0x88,0xef);
time.hour=(time.hour/10)*10+key;
}
}
break;
}
case 4:{
if(key<6)
{
write279(0xc8+i,key);
i--;
write279(0x88,0xf7);
time.minute=time.minute%10+key*10;
}
break;
}
case 3:{
if(key<10)
{
write279(0xc8+i,key);
i--;
i--;
write279(0x88,0xfd);
time.minute=(time.minute/10)*10+key;
}
break;
}
case 1:{
if(key<6)
{
write279(0xc8+i,key);
i--;
write279(0x88,0xfe);
time.second=time.second%10+key*10;
}
break;
}
case 0:{
if(key<10)
{
write279(0xc8+i,key);
i=7;
write279(0x88,0x7f);
time.second=(time.second/10)*10+key;
}
break;
}
}
while((PINC&0x02)==0)//按键释放检查
;
}
while(key!=0x17);
write279(0x88,0xff);
}
/* 设置定时器1及中断系统 */
void opentime()
{
TCNT1=0x85ee;
TCCR1A=0;
TCCR1B=0x04;
TCNT0=0x83;
TCCR0=0x03;
TIMSK=0x80;
SREG|=0x80;
}
/* 显示刷新 */
void display(void)
{
write279(0xc8,time.second%10);
write279(0xc9,time.second/10);
write279(0x92,1);
write279(0xcb,time.minute%10);
write279(0xcc,time.minute/10);
write279(0x95,1);
write279(0xce,time.hour%10);
write279(0xcf,time.hour/10);
}
/* 正计时 */
void inctime(void)
{
if(time.second<59)
time.second++;
else
{
time.second=0;
if(time.minute<59)
time.minute++;
else
{
time.minute=0;
if(time.hour<23)
time.hour++;
else
time.hour=0;
}
}
}
/* 倒计时 */
void dectime(void)
{
if(time.second>0)
time.second--;
else
{
time.second=59;
if(time.minute>0)
time.minute--;
else
{
time.minute=59;
if(time.hour>0)
time.hour--;
else
time.hour=23;
}
}
}
/*启动时为正计时,按shift键进行正计时和倒计时切换 */
/*启动时允许整点报时,按0~F中任意键一次关闭,二次打开*/
void main(void)
{
unsigned char temp,bpflag=0;
MCUCR=0x00;
DDRC=0b00011101;
PORTC=0b00010001;
delay_ms(30);
send_byte(0xa4);
setcs;
initdis();
opentime();
while(1)
{
if(flag==0x01)
{
if(dflag==0)
inctime();
else
dectime();
display();
flag=0;
}
if((PINC&0x02)==0)//检查shift按键
{
send_byte(0x15);
temp=receive_byte();
setcs;
if(temp==0x17)
{
if (dflag==0)
dflag=1;
else
dflag=0;
}
else
bpflag^=0x01;
while((PINC&0x02)==0)//按键释放检查
;
}
if ((time.minute==0)&(bpflag==0))
TIMSK|=0x02; //整点报时
else
TIMSK&=0xfd;
}
}
void timer1_ovf() //溢出中断子程序
{
TCNT1=0x85ee;
flag=0x01;
}
void timer0_ovf()
{
static unsigned int i;
TCNT0=0x83;
i++;
if(i<400)
{
PORTC^=0X01;
}
if(i>800)
i=0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -