📄 main.c
字号:
//************************************************************************
// File : main.c
// Date : 2008-08-22
// Version : 1.3
// Powerd by : shenyae86 QQ:184676957
// modify by :
//*************************************************************************
// Descriptoon:
// 数码管显示程序 显示120000 采用中断扫描模式
// 适用于CC100B、CC100C
// 产品网站 http://www.sxcckj.com 传诚科技
// 普通的家用时钟一般只能设置一个闹钟时间,
// 但很多人均需为工作日、周末、早晨、午休等
// 不同时段设置不同的闹钟时间。如果是使用普通的闹钟,
// 只好每次休息前重新设置,很不方便,
// 有时甚至会出现忘记更改闹钟设置而睡过头的情况。
// 针对这种情况,本人利用89C51单片机设计了
// 一款有8种闹钟设置的时钟,通过一段
// 时间的使用,情况良好。
// help:
// 参见实验指导书
//*************************************************************************
#include <at89x51.h>
#include <intrins.h>
unsigned char hour,min,sec,year,month,day,weekday; //当前时间、日期、星期
unsigned int count_down; //1秒钟计时用
unsigned char code dis_code[]={
0xC0,/*0*/
0xF9,/*1*/
0xA4,/*2*/
0xB0,/*3*/
0x99,/*4*/
0x92,/*5*/
0x82,/*6*/
0xF8,/*7*/
0x80,/*8*/
0x90,/*9*/};//0-9 off
bit led_on; //数码管是否点亮的标志
unsigned char display[8]; //8位数码管要显示的数据
unsigned char attr; //八个数码管的闪烁控制字节,当为0时,对应数码管闪
bit flash; //LED 闪烁开关,与attr共同决定数码管是否闪烁
unsigned char show_status; //LED 显示状态标志
// 0:设置闹钟数据
// 1:显示当前日期及星期
// 2:显示当前时间
// 3:设置当前日期
// 4:设置当前时间
bit km; //按键已去抖动标志
bit kp; //按键已处理标志
bit sound; //蜂鸣器响标志
bit alarm_stop; //蜂鸣器响后用户手工按停标志
struct {
unsigned char h; //小时
unsigned char m; //分钟
} alarm[8]; //8个闹钟项
unsigned char alarm_en; //闹钟项启用标志
unsigned char alarm_wk; //闹钟项周末启用标志
unsigned char cur_alarm_set; //当前设置的闹钟项
unsigned char cur_alarm_active; //当前到点的闹钟项
bit new_alarm_info; //闹钟项内容已修改标志
sbit sound_output = P3^7; //蜂鸣器驱动端口,输出0时蜂鸣器响
sbit SDA_PIN = P1^6; //EEPROM数据线端口
sbit SCL_PIN = P1^5; //EEPROM时钟线端口
////////////////////////////////////////////////////////////////
void I2cDelay() //EEPROM操作时需要的延时函数
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
///////////////////////////////////////////////////////////////
void DelayX1ms(unsigned char count) //延迟函数,参数为毫秒数
{
unsigned char i,j;
for(i=0;i<count;i++)
for(j=0;j<240;j++);
}
///////////////////////////////////////////////////////////////
void Start() //I2C启动,24C08使用I2C方式
{
SDA_PIN=1;
I2cDelay();
SCL_PIN=1;
I2cDelay();
SDA_PIN=0;
I2cDelay();
SCL_PIN=0;
}
/////////////////////////////////////////////////////////////////////
void Stop() //I2C停止
{ I2cDelay(); SDA_PIN=0;
I2cDelay(); SCL_PIN=1;
I2cDelay(); SDA_PIN=1;
I2cDelay();
}
////////////////////////////////////////////////////////////////////
bit SendByte(unsigned char value) //发送1字节数据给EEPROM
{unsigned char i;
bit no_ack=0;
for(i=0;i<8;i++) //发送8位数据
{ I2cDelay();
if(value&0x80) SDA_PIN=1;
else SDA_PIN=0;
value=value<<1;
I2cDelay(); SCL_PIN=1;
I2cDelay();
I2cDelay(); SCL_PIN=0;
}
I2cDelay(); SDA_PIN=1; //确认脉冲周期,等待EEPROM的确认
I2cDelay(); SCL_PIN=1;
I2cDelay();
if(SDA_PIN==1) no_ack=1;
I2cDelay(); SCL_PIN=0;
return no_ack;
}
/////////////////////////////////////////////////////////////////////////
void mywrite(unsigned char address,unsigned char value) //向EEPROM写1字节
{
Start();
SendByte(0xa0);
SendByte(address);
SendByte(value);
Stop();
DelayX1ms(10);
}
////////////////////////////////////////////////////////////////////////
unsigned char ReadByte() //从EEPROM接收1字节
{
unsigned char i,bval;
bval=0;
for(i=0;i<8;i++) //接收8位数据
{ I2cDelay();
SDA_PIN=1; //从P1输入数据时,先往P1输入"1"
I2cDelay(); SCL_PIN=1;
I2cDelay(); bval=bval<<1; if(SDA_PIN) bval=bval|0x01;
I2cDelay(); SCL_PIN=0;
}
I2cDelay(); SDA_PIN=1; //确认脉冲周期,不送出确认
I2cDelay(); SCL_PIN=1;
I2cDelay();
I2cDelay();
return(bval);
}
////////////////////////////////////////////////////////////////////////
unsigned char myread(unsigned char address) //从EEPROM读入1字节数据
{
unsigned char tmp;
Start();
SendByte(0xa0);
SendByte(address);
Start();
SendByte(0xa1);
tmp=ReadByte();
Stop();
DelayX1ms(2);
return(tmp);
}
////////////////////////////////////////////////////////////////////////
void SetNext(void) //轮换调节函数
{
switch(attr)
{ case 0xff:
if(show_status==1)show_status=3; //如果当前显示日期 切换到调准日期状态
if(show_status==2)show_status=4; //如果当前显示时间 切换到调准时间状态
attr=0x3f; break; //第一、二个数码管闪烁
case 0x3f: attr=0xcf; break; //第三、四个数码管闪烁
case 0xcf: attr=0xf3; break; //第五、六个数码管闪烁
case 0xf3: if(show_status==0) attr=0xfd; //第七个数码管闪烁
if(show_status==3) {show_status=1; attr=0xff;} //恢复正常显示日期
if(show_status==4) {show_status=2; attr=0xff;} //恢复正常显示时间
break;
case 0xfd: if(show_status==0) attr=0xfe; //第八个数码管闪烁
break;
case 0xfe: if(show_status==0) attr=0x3f; //第一、二个数码管闪烁
}
}
///////////////////////////////////////////////////////////////////////
void SetInc(void) //轮换调节函数
{
switch(attr)
{
case 0xff: if(show_status==1) show_status=2; //在显示时间与日期间切换
else if(show_status==2) show_status=1;
break;
case 0x3f: if(show_status==0) cur_alarm_set=(cur_alarm_set+1)%8;
else if(show_status==3)
year=(year+1)%50; //当前日期的"年"加1
else if(show_status==4)
hour=(hour+1)%24; //当前时间的"时"加1
break;
case 0xcf: if(show_status==0) //闹钟设置的"时"加1
alarm[cur_alarm_set].h=(alarm[cur_alarm_set].h+1)%24;
else if(show_status==3)
{
month++; //当前日期的"月"加1
if(month==13) month=1;
}
else if(show_status==4)
min=(min+1)%60; //当前时间的"分"加1
break;
case 0xf3: if(show_status==0)
alarm[cur_alarm_set].m=(alarm[cur_alarm_set].m+1)%60;
else if(show_status==3)
{
day++; //当前日期的"日"加1
if(day==32) day=1; }
else if(show_status==4)
{
count_down=8000;
sec=(sec+1)%60;
} //当前时间的"秒"加1
break;
case 0xfd: if(show_status==0)alarm_wk^=0x1<<cur_alarm_set; //周末标志位切换
break;
case 0xfe: if(show_status==0)alarm_en^=0x1<<cur_alarm_set; //启用标志位切换
break;
}
}
////////////////////////////////////////////////////////////////////////
void SetReduce()
{
char tmp;
switch(attr)
{ case 0xff: if(show_status==1 || show_status==2)
led_on=~led_on; //打开或关闭数码管显示
break;
case 0x3f: if(show_status==0) //如果正在设置闹钟
{ if(cur_alarm_set==0) cur_alarm_set=7;
else cur_alarm_set--;}
else if(show_status==3) //当前日期的"年"减1
{ if(year==0) year=49; else year--; }
else if(show_status==4) //当前时间的"时"减1
{ tmp=hour-1; if(tmp<0) hour=23; else hour=tmp; }
break;
case 0xcf: if(show_status==0) //闹钟设置的"时"减1
{ tmp=alarm[cur_alarm_set].h-1;
if(tmp<0) alarm[cur_alarm_set].h=23;
else alarm[cur_alarm_set].h=tmp;
}
else if(show_status==3)
{ month--; //当前日期的"月"减1
if(month==0) month=12; }
else if(show_status==4)
{ tmp=min-1; //当前时间的"分"减1
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -