点阵时钟
- 格式:doc
- 大小:227.50 KB
- 文档页数:24
32*16点阵万年历C程序#include <reg52.h>#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个字移完后加1uchar 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,//00x00,0x04,0x0C,0x04,0x04,0x04,0x04,0x0E,//10x00,0x0E,0x11,0x01,0x02,0x04,0x08,0x1F,//20x00,0x0E,0x11,0x01,0x06,0x03,0x11,0x0E,//30x00,0x06,0x06,0x0A,0x0A,0x12,0x1F,0x02,//40x00,0x1F,0x10,0x10,0x1E,0x01,0x01,0x1E,//50x00,0x0E,0x11,0x10,0x1E,0x11,0x11,0x0E,//60x00,0x1F,0x01,0x02,0x02,0x04,0x04,0x08,//70x00,0x0E,0x11,0x11,0x0E,0x11,0x11,0x0E,//80x00,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数据端置1CLK=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)//如果是显示下半屏,就会大于8linee=line-8;elselinee=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]<<move)|(BUF[(i+1)+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,这样就完成下一字显示。