您的位置 首页 技术

点阵万年历(带时刻、年月日星期调整及闹钟功用)C程序

*此程序是一款用3216点阵屏与DS1302芯片以及三个按键与STC12C5204AD4KROM单片机组合成的万年历电子钟具体功能如下:正常情况下上半屏(32

/*此程序是一款用3216点阵屏与DS1302芯片以及
三个按键与STC12C5204AD 4KROM单片机组合成的
万年历电子钟详细功用如下:正常情况下上半屏
(3208)显现主时刻。当第1次按下功用键时,下半
屏会左移翻滚显现“年、月、日、星期”,当再
次按下时,便进入年、月、日、星期、闹铃等调
整形式,按加与减便利调整,附加功用,当在左
移翻滚显现“年、月、日、星期”时,按下加“+”
按键,便能够回到主界面,当在响铃时,按下
“+键”便能够将本次响铃封闭,当按响铃时下“-”
按键时,便能够封闭闹铃功用,再次按下时,可
以康复闹铃功用*/

视频作用祥见:http://www.tudou.com/programs/view/hQmJSwtHWWc/

完好的源代码下载地址:http://www.51hei.com/f/dzwnl.rar

#include
#define uchar unsigned char
#define uint unsigned int
#define LINE P2//界说行线IO口,即74HC154操控端
sbit DATA1=P1^4;//74HC595数据端
sbit CLK=P1^5;//74HC595移位脉冲端
sbit CLKR=P1^6;//74HC595数据锁存端
sbit BBT =P2^7;//蜂鸣器引脚
sbit SCLK=P1^2;//DS1302移位脉冲端
sbit DATA=P1^1;//DS1302数据端
sbit RST=P1^0;//DS1302操控端
sbit key=P3^4;//功用按键
sbit key1=P3^3;//加”+”按键
sbit key2=P3^2;//加”+”按键
uchar line;//行扫描变量
uchar move;//移位次数变量
uchar mov;//年月日时刻左移变量,即移8次将1个字移完后加1
uchar yin;//按键计数器变量,总共10次,即功用按键有10种功用
uchar lk;//扫描两行仍是1行变量
uchar readvalue;//DS1302转化成果变量
uchar shi,fen,nian,yue,ri,xin;//别离为:小时/分钟/年/月/日/星期变量
uchar shin=12,fenn;//闹钟的小时与分钟变量
bit dian;//主时刻小数点位变量
bit shr,a,b,c,d,e,f,g,h,i;//按键对应的10种功用位变量
bit flag;//主程序与调整时刻切换变量,即进入调整时刻部分就不进入主时刻部分
bit flag1;//闹钟标志位变量
bit clockbiao;//闹钟响铃主标志位
uchar BUF[19];//4组缓存数组以便动态更改数据
/******************************************************/
/**************点阵0-9代码(8*6点阵)******************/
/******************************************************/
uchar code table[]={
0x00,0x0E,0x11,0x11,0x11,0x11,0x11,0x0E,//0
0x00,0x04,0x0C,0x04,0x04,0x04,0x04,0x0E,//1
0x00,0x0E,0x11,0x01,0x02,0x04,0x08,0x1F,//2
0x00,0x0E,0x11,0x01,0x06,0x03,0x11,0x0E,//3
0x00,0x06,0x06,0x0A,0x0A,0x12,0x1F,0x02,//4
0x00,0x1F,0x10,0x10,0x1E,0x01,0x01,0x1E,//5
0x00,0x0E,0x11,0x10,0x1E,0x11,0x11,0x0E,//6
0x00,0x1F,0x01,0x02,0x02,0x04,0x04,0x08,//7
0x00,0x0E,0x11,0x11,0x0E,0x11,0x11,0x0E,//8
0x00,0x0E,0x11,0x11,0x0F,0x01,0x01,0x1E,//9
};
/******************************************************/
/**********两个小数黑屏及坚线代码8*6点阵)*************/
/******************************************************/
uchar code table1[]={
0x00,0x0C,0x0C,0x00,0x00,0x0C,0x0C,0x00,//为两个小数点”:”
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//为黑屏代码
0x00,0x00,0x00,0x1E,0x1E,0x00,0x00,0x00//为两坚线”-“
};
/******************************************************/
/****此数组为74HC154译码器代码(注也能够不必数组)*****/
/******************************************************/
uchar code table2[]={
0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,//上半屏行代码 0-7行
0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff//下半屏行代码 8-15行
};
/******************************************************/
/*****************延时子程序1**************************/
/******************************************************/
void delaya(uint z)
{
uint x;
for(x=z;x>0;x–);
}
/******************************************************/
/*****************延时子程序2**************************/
/******************************************************/
void delay(uint z)
{
uint x,y;
for(x=200;x>0;x–)
for(y=z;y>0;y–);
}
/******************************************************/
/***************蜂鸣器响一声子程序********************/
/******************************************************/
void bbtsoud()
{
BBT=0;//翻开蜂鸣器
delay(50);//延时
BBT=1;//封闭它
}
/**********************************/
//向1302写一个字节数据//
//进口参数:dat
/*********************************/
void write1302xei(uchar dat)
{
uchar x;
SCLK=0;delaya(2);
for(x=0;x<8;x++)
{
DATA=dat&0x01;//取出最低位,然后完结一位位传送
delaya(2);
SCLK=1;
delaya(2);
SCLK=0;
dat>>=1;//等候传送第二个字节
}
}

/**************************************/
//依据操控字向1302写一个字节数据//
//进口参数:操控参数kong,实践参数can
/*************************************/
void write1302(uchar kong,uchar can)
{
SCLK=0;
RST=0;
RST=1;
delaya(2);
write1302xei(kong);
write1302xei(can);
SCLK=1;
RST=0;
}
/**************************************/
//向1302读一个字节数据//
//进口参数:dat,x
/*************************************/
uchar read1302du()
{
uchar dat,x;
SCLK=0;
for(x=0;x<8;x++)
{
dat>>=1;
if(DATA==1)
dat|=0x80;
SCLK=1;
delaya(2);
SCLK=0;
delaya(2);
}
return dat;
}
/**************************************/
//依据操控字向1302读一个字节数据//
//进口参数:操控参数kong 实践参:dat
/*************************************/
uchar read1302(uchar kong)
{
uchar dat;
RST=0;
SCLK=0;
RST=1;
write1302xei(kong);
dat=read1302du();
SCLK=1;
RST=0;
return dat;
}
/**************************************/
//依据操控字向1302读一个字节数据//
//进口参数:别离写入:日期:2010-03-07 时刻:23:59:54 星期天
/*************************************/
void init1302()
{
/*以下是掉电维护函数经过判别标志位是否为1来判别*/
uchar flag;
flag=read1302(0x81);//读秒数据
if(flag&0x80==1)//判别最高位是否为1,若为1则阐明芯片中止工作了,若为0则阐明没有中止
{
write1302(0x8e,0x00);//去掉维护
write1302(0x80,((12/10)<<4)|(12%10));/*显现54秒/*先将BCD码求模得到高位,然后左移四位,
得到了高四位,然后将BCD码求余这样就得到了低四位,然后相或就转化成了二进制代码了*/
write1302(0x82,((59/10)<<4)|(59%10));//显现59分
write1302(0x84,((23/10)<<4)|(23%10));//显现23点
write1302(0x86,((7/10)<<4)|(7%10));//显现07日
write1302(0x88,((3/10)<<4)|(3%10));//显现03月
write1302(0x8c,((10/10)<<4)|(10%10));//显现10年
write1302(0x8a,((7/10)<<4)|(7%10));//显现星期天
write1302(0x90,0xa5);//翻开充电方法,挑选一个二极管2K电阻
write1302(0x8e,0x80);//翻开维护
}

/*以下是开机复位函数*/
/*
write1302(0x8e,0x00);//去掉维护
write1302(0x80,((12/10)<<4)|(12%10));/*显现54秒/*先将BCD码求模得到高位,然后左移四位,
//得到了高四位,然后将BCD码求余这样就得到了低四位,然后相或就转化成了二进制代码了
write1302(0x82,((59/10)<<4)|(59%10));//显现59分
write1302(0x84,((23/10)<<4)|(23%10));//显现23点
write1302(0x86,((7/10)<<4)|(7%10));//显现07日
write1302(0x88,((3/10)<<4)|(3%10));//显现03月
write1302(0x8c,((10/10)<<4)|(10%10));//显现10年
write1302(0x8a,((7/10)<<4)|(7%10));//显现星期天
write1302(0x90,0xa5);//翻开充电方法,挑选一个二极管2K电阻
write1302(0x8e,0x80);//翻开维护
*/
}
/******************************************************/
/***************DS1302转化成果子程序********************/
/******************************************************/
void value()
{
readvalue=read1302(0x83);//读入分地址
fen=((readvalue&0x70)>>4)*10+(readvalue&0x0f);//将分16进制转化成10进制
readvalue=read1302(0x85);//读入小时地址
shi=((readvalue&0x70)>>4)*10+(readvalue&0x0f);//将小时16进制转化成10进制
readvalue=read1302(0x87);//读入日地址
ri=((readvalue&0x70)>>4)*10+(readvalue&0x0f);//将分日进制转化成10进制
readvalue=read1302(0x89);//读入月地址
yue=((readvalue&0x70)>>4)*10+(readvalue&0x0f);//将分月进制转化成10进制
readvalue=read1302(0x8d);//读入年地址
nian=((readvalue&0xf0)>>4)*10+(readvalue&0x0f);//将分年进制转化成10进制
readvalue=read1302(0x8b);//读入星期地址
xin=((readvalue&0x70)>>4)*10+(readvalue&0x0f);//将分星期进制转化成10进制
}
/********************************/
/**74HC595移位寄存器送数子函数***/
/********************************/
void song(uchar dat)//带参数函数
{
uchar num;//界说变量
for(num=0;num<6;num++)//移动6次将数据发送结束
{
dat>>=1;//将数移走一位
DATA1=CY;//为1就将74HC595数据端置1
CLK=0;//上升沿送走数据
CLK=1;//高电平构成上升沿
}
}
/******************************************************/
/***装一线数据子函数(即一行数据)主时刻装数函数********/
/******************************************************/
void yixian(uchar shi,uchar ge,uchar z)
{
BUF[0]=table[(8*(shi/10))+line];//显现小时十位
BUF[1]=table[(8*(shi%10))+line];//显现小时个位
BUF[2]=table1[z*8+line];//显现两个小数点,留意是不同的数组内哟
BUF[3]=table[(8*(ge/10))+line];//显现分十位
BUF[4]=table[(8*(ge%10))+line];//显现分个位
}
/******************************************************/
/***装一线数据子函数(即一行数据)显现黑屏子程序********/
/******************************************************/
void yixianhei()
{
uchar linee,i;
if(line>8)//假如是显现下半屏,就会大于8
linee=line-8;
else
linee=line;//不然直接给数
for(i=0;i<5;i++)//循环5次得到5个数组的数
BUF[i]=table1[8+linee];//查表得到数,留意是数组1中的数
}
/******************************************************/
/*******主程序显现子程序(包含上半屏与下半屏)********/
/******************************************************/
void xianzhu(uchar nia,uchar ye,uchar rii,uchar xi)
{
uchar temp;//左移数值变量
char i;//有符号变量
for(move=0;move<8;move++)//左移8次让下半屏构成左移
{
for(line=0;line<8+lk;line++)//lk变量为挑选上半屏仍是全屏变量,当它等于0时,只显现上半屏时刻,不然全屏显现
{
if(line<8)//假如它小于8则阐明lk变量为0,只让它显现上半屏的主时刻
{
yixian(shi,fen,dian);//调用主时刻一线数值装载子函数
for(i=4;i>=0;i–)
song(~BUF[i]);//循环5次,将数组4-0的数悉数发数到显现屏上
}
else//假如大于16则就循环左移显现下半屏的”年月日星期等信息”
{
uchar movee;//局部变量
movee=line-8;//line大于16,此刻用它减去8就得到实践要显现的值
BUF[0]=table[16+movee];//显现数字”2″字
BUF[1]=table[movee];//显现数字”0″字
BUF[2]=table[(8*(nia/10))+movee];//显现年十位
BUF[3]=table[(8*(nia%10))+movee];//显现年个位
BUF[4]=table1[16+movee];//显现横线”-“
BUF[5]=table[(8*(ye/10))+movee];//显现月份十位
BUF[6]=table[(8*(ye%10))+movee];//显现月份个位
BUF[7]=table1[16+movee];//显现横线”-“
BUF[8]=table[(8*(rii/10))+movee];//显现日十位
BUF[9]=table[(8*(rii%10))+movee];//显现日个位
BUF[10]=table1[16+movee];//显现横线”-“
BUF[11]=table[(8*(xi%10))+movee];//显现星期几
for(i=4;i>=0;i–)//循环5次将数发送给下半屏
{
temp=((BUF[i+mov]<>(6-move)));//将左半屏数左移x位,然后将右
//半屏数右移6-x位,然后或一下就得到在左移了,此句是左移要害!
song(~temp);//送数出去
}
delaya(1000);//延时一下
}
LINE=table2[line];//翻开行线,即174HC154行线端
CLKR=1;//在74HC595处锁存起来
CLKR=0;
CLKR=1;
delaya(800);//延时一下
}

}
mov++;//显现完一屏后,将移1个字变量加1,这样就完结下一字显现。原理是:显现下一个数组
if(mov>13)//移完14次,就将它清0。原因是,程序悉数定了19个数组,前面显现数用了5个加现在14次,刚好19个数组
mov=0;//清0,重新开始显现
}
/******************************************************/
/**********闪耀连续显现子程序(包含下半屏)************/
/******************************************************/
void xianshan()
{
char ii;//有符号变量
for(line=0;line<8;line++)//扫描8次,即完结一个字的移动
{
if(flag1==0)//假如标志位为0,则以0.5秒速度显现时分钟主界面
yixian(shi,fen,dian);//调用时分秒主界面子程序
if(flag1==1)//假如标志位为1,则以0.5秒速度显现黑屏界面,构成闪耀作用
yixianhei();//调用黑屏子程序
for(ii=4;ii>=0;ii–)//循环5次将数发往显现屏
song(~BUF[ii]);//送数
LINE=table2[line];//翻开行线,即174HC154行线端
CLKR=1;//在74HC595处锁存起来
CLKR=0;
CLKR=1;
delaya(800);
}
}

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/xinpin/jishu/255368.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部