📄 1302.c
字号:
/***********************************************************
文件名称:电子数码万年历
作 者:
版 本:0.1
说 明:共有两个功能,时间的调整,1个闹钟
修改记录:2005.2.28
***********************************************************/
//此程式是从以前的万年历上移植过来的,可以用里面的一些模块函数
#include<regx51.h>
#define uchar unsigned char
sbit RSTB=P3^7;
sbit IO=P3^6;
sbit SCLK=P3^5;
sbit k1=P1^3; //设定
sbit k2=P1^2; //加1
sbit k3=P1^1; //减1
sbit k4=P1^0; //闹钟设定
sbit k5=P1^4; //闹钟开/关
sbit clock_switch=P2^6; //闹钟开关批示
sbit clock_bell=P2^7; //闹钟定时时间到指示()闹铃开/关
uchar flag; //定义闪动标志位
uchar bit_count; //闪动位
uchar clock_flag; //闹钟开/关标志位
/***********************************/
uchar code display_data[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0x0F8,0x80,0x90,0xFF};
uchar display_seg[15]={2,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
uchar data_seg[8]={0x40,0x59,0x23,0x12,0x03,0x1,0x06,0};/*初始化数据年月日数据
2006年星期13月23日23点55分*/
uchar clock_seg[4]; //闹钟数据REM
/***************Display pragma*************/
void dealy(void) //显示延时
{
uchar i;
for(i=0;i<150;i++);
}
void display(void) //显示程序
{
uchar j,*p;
for(j=0;j<15;j++)
{
P2=P2|j;
p=display_data;
if(flag==0xff&&((bit_count-1)==j)) P0=0XFF;
else {p=p+display_seg[j];P0=*p;}
dealy();
P0=0XFF;
P2&=0Xf0;
}
}
/************************************************/
void reset_3w(void) //复位
{
SCLK=0;
RSTB=0;
RSTB=1;
}
void wbyte_3w(uchar number)//写一个字节
{
uchar i;
for(i=0;i<8;i++)
{
IO=0;
if(number&0x01) IO=1;
else IO=0;
SCLK=0;
SCLK=1;
number>>=1;
}
}
uchar rbyte_3w() //读一个字节
{
uchar i,k;
uchar tmpbyte;
k=0x01;
IO=1;
for(i=0;i<8;i++)
{
SCLK=1;
SCLK=0;
if(IO==1) tmpbyte|=k;
else tmpbyte&=(~k);
k<<=1;
}
return tmpbyte;
}
void write_1302(void)
{
uchar i,*p;
p=data_seg;
reset_3w();
wbyte_3w(0x8e); //写保护器开
wbyte_3w(0);
reset_3w();
wbyte_3w(0xbe); //以多字节突发方试写取时钟数据
for(i=0;i<8;i++) //秒,分,时,日期,月,星期,年,保护控制寄存器关
{
wbyte_3w(*p);
p++;
}
}
void read_1302(void)
{
uchar sec,min,hrs,dte,mon,day,yr;
reset_3w();
wbyte_3w(0xbf); //以多官节突发方试读取时钟数据
sec=rbyte_3w(); /*秒 */
min=rbyte_3w(); /*分 */
hrs=rbyte_3w(); /*时 */
dte=rbyte_3w(); /*日期 */
mon=rbyte_3w(); /*月 */
day=rbyte_3w(); /*星期 */
yr=rbyte_3w(); /*年 */
reset_3w();
/*********十六进制转BCD码子程序********/
display_seg[14]=sec%16;
display_seg[13]=sec/16;
display_seg[12]=min%16;
display_seg[11]=min/16;
display_seg[10]=hrs%16;
display_seg[9]=hrs/16;
display_seg[7]=dte%16;
display_seg[6]=dte/16;
display_seg[5]=mon%16;
display_seg[4]=mon/16;
display_seg[8]=day;
display_seg[3]=yr%16;
display_seg[2]=yr/16;
}
void t0(void) interrupt 1 using 0 //定时器T0,闪动定时中断
{
static uchar i=0;
TH0=0x3c; //定时100MS中断一次
TL0=0xb0; //重装计数值
i++;
if(i==4) {flag=~flag;i=0;}
}
void clock_write(void)
{
display_seg[9]=clock_seg[0];
display_seg[10]=clock_seg[1];
display_seg[11]=clock_seg[2];
display_seg[12]=clock_seg[3];
}
void clock_save(void) //闹钟数据保存
{
clock_seg[0]=display_seg[9];
clock_seg[1]=display_seg[10];
clock_seg[2]=display_seg[11];
clock_seg[3]=display_seg[12];
}
void clock_compare(void)
{
if(clock_seg[2]==display_seg[11]&&clock_seg[3]==display_seg[12])
{
if(clock_seg[1]==display_seg[10])
{
if(clock_seg[0]==display_seg[9])
clock_bell=0; //时间到闹铃开
}
}
else clock_bell=1; //时间没到闹铃关
if(clock_flag==0) clock_bell=1; //用闹钟开/关键控制闹铃的工作时间
}
void complex_data(void)
{
data_seg[0]=display_seg[13]*16+display_seg[14];
data_seg[1]=display_seg[11]*16+display_seg[12];
data_seg[2]=display_seg[9]*16+display_seg[10];
data_seg[3]=display_seg[6]*16+display_seg[7];
data_seg[4]=display_seg[4]*16+display_seg[5];
data_seg[5]=display_seg[8];
data_seg[6]=display_seg[2]*16+display_seg[3];
}
void key(void)
{
if(k1==0)
{
display(); //延时去抖动
if(k1==0)
{
TR0=1; //启动定时器
bit_count++;
while(k1==0) display(); //等键释放
while(1)
{
if(k1==0) /*设定/移位*/
{
display(); //延时去抖动
if(k1==0)
{
bit_count++;
while(k1==0) display();
}
}
if(k2==0)/*调整(+)*/
{
display();
if(k2==0)
{
while(k2==0) display();
display_seg[bit_count-1]=display_seg[bit_count-1]+1;
/*实际数据调整位=位实际位闪烁位-1*/
/****************************月份***********************************/
if(bit_count-1==4) //月十位判别
{
if(display_seg[bit_count-1]==2) display_seg[bit_count-1]=0;
}
if(bit_count-1==5&&display_seg[4]==1) //月个位判别
{ if(display_seg[bit_count-1]==3) display_seg[bit_count-1]=0;}
/****************************日期***********************************/
if(bit_count-1==6) //日期十位判别
{
if((display_seg[4]+display_seg[5])==2)
if(display_seg[bit_count-1]==3) display_seg[bit_count-1]=0;
if(display_seg[bit_count-1]==4) display_seg[bit_count-1]=0;
}
/****************************星周***********************************/
if(bit_count-1==8) if(display_seg[bit_count-1]==8) display_seg[bit_count-1]=1;
/****************************时分秒***********************************/
if(bit_count-1==9) if(display_seg[bit_count-1]==3) display_seg[bit_count-1]=0;//时十位
if(bit_count-1==10)//时个位
{
if(display_seg[9]==2) if(display_seg[bit_count-1]==4) display_seg[bit_count-1]=0;
else if(display_seg[bit_count-1]==10) display_seg[bit_count-1]=0;
}
if(bit_count-1==11||bit_count-1==13)//分十位/秒十位
if(display_seg[bit_count-1]==6) display_seg[bit_count-1]=0;
/*********************************************************************/
if(display_seg[bit_count-1]==10) display_seg[bit_count-1]=0;
}
}
if(k3==0)/*调整(-)*/
{
display();
if(k3==0)
{
while(k3==0) display();
display_seg[bit_count-1]=display_seg[bit_count-1]-1;
if(display_seg[bit_count-1]==0xff) display_seg[bit_count-1]=0;
if(bit_count-1==8) if(display_seg[bit_count-1]==0) display_seg[bit_count-1]=1;
}
}
if(bit_count==16)
{
TR0=0;
bit_count=0;
complex_data();
write_1302();
break ;
}
display();
}
}
}
if(k4==0)/*闹钟设定键*/
{
display();
if(k4==0)
{
while(k4==0) display(); //等键释放
TR0=1; //启动定时器
bit_count=10;
clock_write(); //显示闹钟时间(将闹钟数据写入显示缓冲区)
while(1)
{
display();
if(k4==0) /*设定/移位*/
{
display(); //延时去抖动
if(k4==0)
{
bit_count++;
while(k4==0) display(); //等键释放
}
}
if(k2==0)/*调整(+)*/
{
display();
if(k2==0);
{
while(k2==0) display(); //等键释放
display_seg[bit_count-1]=display_seg[bit_count-1]+1;
/****************************时分秒***********************************/
if(bit_count-1==9) if(display_seg[bit_count-1]==3) display_seg[bit_count-1]=0;//时十位
if(bit_count-1==10)//时个位
{
if(display_seg[9]==2) if(display_seg[bit_count-1]==4) display_seg[bit_count-1]=0;//
else if(display_seg[bit_count-1]==10) display_seg[bit_count-1]=0;
}
if(bit_count-1==11||bit_count-1==13)//分十位/秒十位
if(display_seg[bit_count-1]==6) display_seg[bit_count-1]=0;
/*********************************************************************/
if(display_seg[bit_count-1]==10) display_seg[bit_count-1]=0;
}
}
if(k3==0)/*调整(-)*/
{
display();
if(k3==0);
{
while(k3==0) display(); //等键释放
display_seg[bit_count-1]=display_seg[bit_count-1]-1;
if(display_seg[bit_count-1]==0xff) display_seg[bit_count-1]=0;
}
}
if(bit_count==14)
{
TR0=0;
bit_count=0;
clock_save();
break ;
}
}
}
}
if(k5==0) /*闹钟开关*/
{
display();
if(k5==0)
{
clock_flag=~clock_flag; //置标志位
clock_switch=~clock_switch;
while(k5==0) display();
}
}
}
/***************************************/
void main(void)
{
TMOD=0x01; //定时器初始化
TH0=0x3c; //定时100MS中断一次
TL0=0xb0;
//TR0=1;
ET0=1; //开定时器中断
EA=1; //开总中断
clock_flag=0; //闹钟功能开
clock_switch=1; //闹钟控制指示关
clock_bell=1; //闹铃关
write_1302();
while(1)
{
read_1302();
display();
key();
clock_compare();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -