📄 ht1380_time3.c
字号:
#include <reg51.h>
/*****定义ht1380芯片接口********/
// ht1380 ht1380_sclk --->P1.0
// ht1380 I/O --->P1.1
// ht1380 ht1380_rest --->P1.2
sbit ht1380_sclk=P1^0;
sbit ht1380_data=P1^1;
sbit ht1380_rest=P1^2;
sbit beep=P1^7;
bit flag=0;
/**********定义两个全局变量*********/
//定义数组变量用于存放四个数码管的显示数据
//定义number存放动态显示是第几个数码管
unsigned char d[4],number;
/*********定义时间变量年月日时分秒***********/
unsigned char year,month,day,hour,minute,second,callhour,callminute,callsecond,rehour,reminute,resecond;
/**********定义冒号变量 distime=1 是数码管冒号显示出来************/
bit distime;
/*******与数码管相关的两个表*********/
//一个显示译码表 //注:这里表比前一个多了一个值,最后一个数代表空显示
//一个使能译码表
unsigned char code tab[11]={0x3f,6,0x5b,0x4f,0x66,0x6d,0x7d,7,0x7f,0x6f,0};
unsigned char code digit[4]={0xf8,0xf4,0xf2,0xf1};
/******延时程序***********/
void delay(unsigned char dy)
{
while(--dy);
}
/******按键接口描述********/
//左第一 二 三 四 个按键分别对应于 P2.7 P2.6 P2.5 P2.4
//左第一个按键键值为1
//左第二个按键键值为2
//左第三个按键键值为3
//左第四个按键键值为4
/******读取按键子程序 getkey()*************/
unsigned char getkey (void)
{ unsigned char k,m,tem,keytem;
unsigned int j=0;
keytem=0;
tem=P2 & 0xf0; //第一次读取按键值
if(tem!=0xf0) //判断有无按键按下
{
for(k=0;k<20;k++)
delay(250); //延时一段时间
tem=P2 & 0xf0; //再次读取按键值
if(tem!=0xf0)
{ if(tem==0x70) keytem=1; //表示左第一个按键按下
else if(tem==0xb0) keytem=2; //表示左第二个按键按下
else if(tem==0xd0) keytem=3; //表示左第三个按键按下
else if(tem==0xe0) keytem=4; //表示左第四个按键按下
}
}
while(tem!=0xf0)
{
for(m=0;m<250;m++)
delay(250),j++;
tem=P2 & 0xf0; //等待按键释放
if (tem==0x70&&j>500)
{flag=1;
}
}
return(keytem); //返回按键值
}
/******* ht1380 子程序*****************/
//------------- sent_char to ht1380----------
//上升沿写入
void sent_char(unsigned char sentchar)
{
unsigned char ii;
for(ii=0;ii<8;ii++)
{
ht1380_sclk=0;
if ((sentchar & 1)!=0) ht1380_data=1;
else ht1380_data=0;
ht1380_sclk=1;
sentchar=sentchar>>1;
}
}
//------------- get_char from ht1380---------
unsigned char get_char()
{
unsigned char getchar,ii,temp;
getchar=0;temp=1;
for(ii=0;ii<8;ii++)
{
ht1380_sclk=0;
ht1380_data=1;
if(ht1380_data==1) getchar=getchar |temp;
ht1380_sclk=1;
temp=temp<<1;
}
return(getchar);
}
//-------------set_wp_off------------------
void set_wp_off()
{
ht1380_rest=1;
sent_char(0x8e); //10001110b
sent_char(0); //00000000b
ht1380_sclk=0;
ht1380_rest=0;
}
//-----------set_wp_on--------------------
void set_wp_on()
{
ht1380_rest=1;
sent_char(0x8e); //10001110b
sent_char(0x80); //10000000b
ht1380_sclk=0;
ht1380_rest=0;
}
//----------read_time --------------------
void read_time()
{
unsigned char temp;
ht1380_rest=1;
sent_char(0xbf); //10111111b
second=get_char();
minute=get_char();
hour= get_char();
day= get_char();
month= get_char();
temp= get_char(); /* week day */
year= get_char();
temp= get_char();
ht1380_sclk=0;
ht1380_rest=0;
}
//--------------set time-----------------
void set_time()
{
set_wp_off();
ht1380_rest=1;
sent_char(0xbe); //10111110b
sent_char(second);
sent_char(minute);
sent_char(hour);
sent_char(day);
sent_char(month);
sent_char(1); /* week day */
sent_char(year);
sent_char(0);
ht1380_sclk=0;
ht1380_rest=0;
set_wp_on();
}
/*****定时器初始化程序*******/
void Init_Timer (void)
{
TMOD=0x21;
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;
TR0=1;
ET0=1;
EA=1;
}
/*****定时器0中断服务程序******/
//显示处理,具体可以参考前面的实验
void timer0() interrupt 1 using 1
{
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;
number=number++;
if(number>3) number=0;
P2=digit[number];
P0=tab[d[number]];
//在第二个数码管显示时,将最高位的小数点显示出来,这里为冒号
if(distime==1 && number==1)
P0=tab[d[number]]+0x80;
}
/*******主函数***********/
//效果:
//显示时分
//可用按键调整时间-时分
//在较时状态时,相应的数字闪烁
//第一个按键用于调整到较时状态并且可以切换要修改的位,第二个按键用于加1..
//..第三个按键用于减,第四个按键用于确认回到正常显示状态。
//这里就不调整年月日了.大家可以考虑一下如何调整
void main (void)
{
unsigned char keyboard,keyboard1; //键值变量
unsigned char state=0; //状态指示 =1较时状态 =0正常显示状态
unsigned char i,distem,w=3; //变量
year=07;month=03;day=0x05;hour=0x07;minute=0x16;second=13; //软件预设时间参数
callhour=27,callminute=0,callsecond=0;
beep=1;
ht1380_rest=0;ht1380_sclk=0; //选中时钟芯片
read_time(); //设置时间
Init_Timer(); //初始化定时器及全局变量
number=0;
distime=1; //冒号显示
while(1)
{
distime=~distime; // 闪动冒号
read_time(); //读时间
if(state==0) //state=0 正常显示状态
{
read_time();
d[0]=hour/16;
d[1]=hour %16;
d[2]=minute/16;
d[3]=minute %16;
}
else //较时状态。让需要较时的位闪动
{ set_time();
distem=d[w];
d[w]=10;
for(i=0;i<250;i++)
delay(250);
d[w]=distem;
for(i=0;i<250;i++)
delay(250);
}
keyboard=getkey(); //读按键;
while(flag==1)
{
distime=1;
state=1;
/* set_time();*/
distem=d[w];
d[w]=10;
for(i=0;i<250;i++)
delay(250);
d[w]=distem;
for(i=0;i<250;i++)
delay(250);
keyboard1=getkey();
if(keyboard1==1)
{ state=1; // ..按键后会同时向后退到下一位
w++;
if(w>3) w=0;
}
else if(keyboard1==2)
{ d[w]++;
if(d[0]>2) d[0]=0;
if(d[0]==2&&d[1]>3) d[1]=0;
if(d[2]>5) d[2]=0;
else if(w>=1&&d[w]>9) d[w]=0;
}
else if(keyboard1==3)
{ if(d[w]>0) d[w]--; }
else if(keyboard1==4)
{ callhour=d[0]*16+d[1];
callminute=d[2]*16+d[3];
callsecond=0;
read_time();
d[0]=hour/16;
d[1]=hour %16;
d[2]=minute/16;
d[3]=minute %16;
state=0;
flag=0;
}
}
if(keyboard==1) // keyboard=1时,切换转态到较时并且多次..
{ state=1; // ..按键后会同时向后退到下一位
w++;
if(w>3) w=0;
}
else if(keyboard==2)
{ d[w]++;
if(d[0]>2) d[0]=0;
if(d[0]==2&&d[1]>3) d[1]=0;
if(d[2]>5) d[2]=0;
else if(w>=1&&d[w]>9) d[w]=0;
}
else if(keyboard==3)
{ if(d[w]>0) d[w]--; }
else if(keyboard==4)
{ hour=d[0]*16+d[1];
minute=d[2]*16+d[3];
second=0;
set_time();
state=0;
}
if(hour==callhour&&minute==callminute&&(second>=0&&second<=9))
beep=0;
else beep=1;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -