嵌入式电子闹钟()时钟课程设计

嵌入式电子闹钟()时钟课程设计
嵌入式电子闹钟()时钟课程设计

#include //头文件

#include

#define uchar unsigned char //宏定义

#define uint unsigned int

//位定义

sbit rs=P2^5; //液晶位定义

sbit lcden=P2^7;

sbit s1=P2^0; //时间功能切换按键

sbit s2=P2^1; //按键加

sbit s3=P2^3; //按键减

sbit s4=P2^4; //闹钟功能切换键

sbit rst=P1^5; //ds1302引脚定义

sbit io=P1^6;

sbit sclk=P1^7;

sbit beep=P3^0; //蜂鸣器

uchar num,count,shi,fen,miao,s1num,s2num,

year,month,day,week,flag,flag1,year1,month1,

day1,week1,shi1,fen1,miao1,year2,month2,

day2,week2,shi2,fen2,miao2,year5,month5,

day5,week5,shi5,fen5,miao5,wk,ashi,afen; //参数定义

uchar code table[]="20 - - "; //液晶固定显示

uchar code table1[]=" : : 00:00";

/*

uchar time_dat[7]={12,1,6,6,12,59,59}; //年周月日时分秒

uchar write_add[7]={0x8c,0x8a,0x88,0x86,0x84,0x82,0x80};

uchar read_add[7]={0x8d,0x8b,0x89,0x87,0x85,0x83,0x81};

*/

void write_com(uchar com); //液晶写指令函数

void write_data(uchar date); //液晶写数据函数

void write_ds1302(uchar add,uchar dat); //ds1302芯片写指令函数void set_rtc(); //ds1302时间设置函数void time_pros(); //ds1302进制转换函数void read_rtc(); //ds1302读时间函数void alarm(); //闹钟函数

void delay(uint z) //延时函数

{

uint x,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--);

}

void init() //初始化

{

lcden=0;

flag=0;

flag1=0;

write_com(0x38);

write_com(0x0c);

write_com(0x06);

write_com(0x01);

write_com(0x80); //液晶固定显示,第一行 for(num=0;num<14;num++)

{

write_data(table[num]);

delay(5);

}

write_com(0x80+0x40); //液晶显示第二行

for(num=0;num<20;num++)

{

write_data(table1[num]);

delay(5);

}

}

void write_com(uchar com)//1602液晶写指令

{

rs=0;

P0=com;

delay(5);

lcden=1;

delay(5);

lcden=0;

}

void write_data(uchar date)//1602液晶写写数据

{

rs=1;

P0=date;

delay(5);

lcden=1;

delay(5);

lcden=0;

}

void write_sfm(uchar add,uchar date)//时分秒

{

uchar shi3,ge;

shi3=date/10;

ge=date%10;

write_com(0x80+0x40+add);

write_data(0x30+shi3);

write_data(0x30+ge);

}

void write_nyr(uchar ad,uchar date)//年月日

{

uchar shi4,ge2;

shi4=date/10;

ge2=date%10;

write_com(0x80+ad);

write_data(0x30+shi4);

write_data(0x30+ge2);

}

void write_week(uchar wk) //星期按西方星期设置星期天为第一天{

write_com(0x80+11);

switch(wk)

{

case 1: write_data('S');

delay(5);

write_data('U');

delay(5);

write_data('N');

break;

case 2: write_data('M');

delay(5);

write_data('O');

delay(5);

write_data('N');

break;

case 3: write_data('T');

delay(5);

write_data('U'); delay(5);

write_data('E'); break;

case 4: write_data('W'); delay(5);

write_data('E'); delay(5);

write_data('D'); break;

case 5: write_data('T'); delay(5);

write_data('H'); delay(5);

write_data('U'); break;

case 6: write_data('F'); delay(5);

write_data('R'); delay(5);

write_data('T'); break;

case 7: write_data('S'); delay(5);

write_data('A'); delay(5);

write_data('T'); break;

}

}

void keyscan() //按键函数{

if(s1==0)

{

delay(5);

if(s1==0)

{

write_com(0x0f);

s1num++; //记录按键次数

flag=1;

flag1=1;

while(!s1);

switch(s1num)//光标闪烁点定位

{

case 1:write_com(0x80+0x40+6); //秒

break;

case 2:write_com(0x80+0x40+3); //分

break;

case 3:write_com(0x80+0x40+0); //时

break;

case 4:write_com(0x80+11); //星期

break;

case 5:write_com(0x80+8); //日

break;

case 6:write_com(0x80+5); //月

break;

case 7:write_com(0x80+2); //年

break;

case 8:s1num=0;

write_com(0x0c);//设置开显示光标不显示关闭时间设置

set_rtc();

flag=0;

break;

}

}

}

if(s1num!=0) //按键加减

{

if(s2==0) //加按键函数

{

delay(10);

if(s2==0)

{

while(!s2);

switch(s1num) //根据功能键相应次数做出调节

{

case 1: miao++; //秒加

if(miao==60)

miao=0;

write_sfm(6,miao);

write_com(0x80+0x40+6);

break;

case 2: fen++; //分加

if(fen==60)

fen=0;

write_sfm(3,fen);

write_com(0x80+0x40+3);

break;

case 3: shi++; //时加

if(shi==24)

shi=0;

write_sfm(0,shi);

write_com(0x80+0x40+0);

break;

case 4: week++; //星期加 if(week==8)

week=1;

write_week(week);

write_com(0x80+11);

break;

case 5: day++; //日加

if(day==32)

day=1;

write_nyr(8,day);

write_com(0x80+8);

break;

case 6: month++; //月加

if(month==13)

month=1;

write_nyr(5,month);

write_com(0x80+5);

break;

case 7: year++; //年加 if(year==100)

year=0;

write_nyr(2,year);

write_com(0x80+2);

break;

}

}

}

if(s3==0) //减按键函数同上 {

delay(10);

if(s3==0)

{

while(!s3);

switch(s1num) //根据功能键相应次数做出调节

{

case 1: miao--;

if(miao==-1)

miao=59;

write_sfm(6,miao);

write_com(0x80+0x40+6);

break;

case 2: fen--;

if(fen==-1)

fen=59;

write_sfm(3,fen);

write_com(0x80+0x40+3);

break;

case 3: shi--;

if(shi==-1)

shi=23;

write_sfm(0,shi);

write_com(0x80+0x40+0); break;

case 4: week--;

if(week==-1)

week=7;

write_week(week);

write_com(0x80+11);

break;

case 5: day--;

if(day==-1)

day=31;

write_nyr(8,day);

write_com(0x80+8);

break;

case 6: month--;

if(month==-1)

month=12;

write_nyr(5,month);

write_com(0x80+5);

break;

case 7: year--;

if(year==-1)

year=99;

write_nyr(2,year);

write_com(0x80+2);

break;

}

}

}

}

if(s4==0) //闹钟按键

{

delay(5);

if(s4==0)

{

write_com(0x0f); //光标闪烁

s2num++; //记录按键次数

flag=1;

while(!s4);

switch(s2num)//光标闪烁点定位

{

case 1:write_com(0x80+0x40+13); //分

break;

case 2:write_com(0x80+0x40+10); //时

break;

case 3:write_com(0x0c); //关闭闹钟设置 flag=0;

s2num=0;

break;

}

}

}

if(s2num!=0) //闹钟设置

{

if(s2==0) //闹钟加

{

delay(10);

if(s2==0)

{

while(!s2);

switch(s2num) //根据功能键相应次数做出调节

{

case 1: afen++;

if(afen==60)

afen=0;

write_sfm(13,afen);

write_com(0x80+0x40+13);

break;

case 2: ashi++;

if(ashi==24)

ashi=0;

write_sfm(10,ashi);

write_com(0x80+0x40+10); break;

}

}

}

if(s3==0) //闹钟减

{

delay(10);

if(s3==0)

{

while(!s3);

switch(s2num) //根据功能键相应次数做出调节 {

case 1: afen--;

if(afen==-1)

afen=59;

write_sfm(13,afen);

write_com(0x80+0x40+13); break;

case 2: ashi--;

if(ashi==-1)

ashi=23;

write_sfm(10,ashi);

write_com(0x80+0x40+10); break;

}

}

}

}

}

void wirte_ds1302_byte(uchar dat) //ds1302字节写{

uchar i;

for(i=0;i<8;i++)

{

sclk=0;

io=dat&0x01;

dat=dat>>1;

sclk=1;

}

}

void write_ds1302(uchar add,uchar dat) //ds1302写函数{

rst=0;

_nop_();// 空操作

sclk=0;

_nop_();

rst=1;

_nop_();

wirte_ds1302_byte(add);

wirte_ds1302_byte(dat);

rst=0;

io=1;

sclk=1;

}

uchar read_ds1302(uchar add) //ds1302读函数{

uchar i,value;

rst=0;

_nop_();// 空操作

sclk=0;

_nop_();

rst=1;

_nop_();

wirte_ds1302_byte(add);

for(i=0;i<8;i++)

{

value=value>>1;

sclk=0;

if(io)

{

value=value|0x80;

}

sclk=1;

}

rst=0;

_nop_();// 空操作

sclk=0;

_nop_();

io=1;

return value;

}

void set_rtc() //ds1302时间设置{

write_ds1302(0x8e,0x00); //关写保护

year1=year/10; //转换为十六进制

year=year%10;

year=year+year1*16;

write_ds1302(0x8c,year);

week1=week/10;

week=week%10;

week=week+week1*16;

write_ds1302(0x8a,week);

month1=month/10;

month=month%10;

month=month+month1*16;

write_ds1302(0x88,month);

day1=day/10;

day=day%10;

day=day+day1*16;

write_ds1302(0x86,day);

shi1=shi/10;

shi=shi%10;

shi=shi+shi1*16;

write_ds1302(0x84,shi);

fen1=fen/10;

fen=fen%10;

fen=fen+fen1*16;

write_ds1302(0x82,fen);

miao1=miao/10;

miao=miao%10;

miao=miao+miao1*16;

write_ds1302(0x80,miao);

write_ds1302(0x8e,0x80); //开写保护

}

void read_rtc() //从ds1302中读时间

{

year2=read_ds1302(0x8d);

week2=read_ds1302(0x8b);

month2=read_ds1302(0x89);

day2=read_ds1302(0x87);

shi2=read_ds1302(0x85);

fen2=read_ds1302(0x83);

miao2=read_ds1302(0x81);

}

void time_pros() //从ds1302中读出的时间转换为十进制

{

year5=year2/16;

year2=year2%16;

year2=year2+year5*10;

month5=month2/16;

month2=month2%16;

month2=month2+month5*10;

day5=day2/16;

day2=day2%16;

day2=day2+day5*10;

shi5=shi2/16;

shi2=shi2%16;

shi2=shi2+shi5*10;

fen5=fen2/16;

fen2=fen2%16;

fen2=fen2+fen5*10;

miao5=miao2/16;

miao2=miao2%16;

miao2=miao2+miao5*10;

}

void display() //显示函数{

write_sfm(6,miao2);

write_com(0x80+0x40+6);

write_sfm(3,fen2);

write_com(0x80+0x40+3);

write_sfm(0,shi2);

write_com(0x80+0x40+0);

write_week(week2);

write_com(0x80+11);

write_nyr(8,day2);

write_com(0x80+8);

write_nyr(5,month2);

write_com(0x80+5);

write_nyr(2,year2);

write_com(0x80+2);

if((ashi==shi2)&&(afen==fen2))

{

alarm();

}

}

void alarm() // 闹钟

{

beep=0;

delay(1000);

beep=1;

}

void main() //主函数{

init(); //初始化 while(1)

{

keyscan(); //按键函数

if(flag==0)

{

keyscan();

read_rtc();

time_pros();

display();

}

}

}

相关主题
相关文档
最新文档