本文件是单片机技术时钟震荡的仿真图,是我设计所作的,需要的可以来自取
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include<reg52.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define play P0 //数据输出口
- sbit LSA=P1^0;
- sbit LSB=P1^1;
- sbit LSC=P1^2;
- sbit led=P2^2; //闹钟检测
- sbit k1=P2^7;// 功能切换
- sbit k2=P2^6;//设置加
- sbit k3=P2^5;// 设置减
- sbit k4=P2^4; //设置位选
- sbit beet=P1^5; //蜂鸣器输出口
- uchar y;//按键松开
- uchar kai;//闹钟开启标志
- uchar she;// 位选标志 取值范围0 1 2 3
- uchar t;//时间计数
- uchar num;//功能切换 取值范围 0 1 2 。0时钟设置,1日期设置,2闹钟设置
- uchar fen;
- uchar shi;
- uchar miao;
- uchar yue;
- uchar nian;
- uchar ri;
- uchar shijian[8];//用来临时存放数据的数组 ,存放的是要显示的内容
- uchar shi1; //闹铃时
- uchar fen1; //闹铃分
- unsigned char code shuma[16]={
- 0x3f,0x06,0x5b,0x4f,
- 0x66,0x6d,0x7d,0x07, //数码管显示数组0到9, - ,和学号
- 0x7f,0x6f,0x40,0x00, //8 9 10 11
- 0x40,0x40,0x40 };
- uchar brunyue[12]={31,28,31,30,31,30,31,31,30,31,30,31};
- uchar runyue[12]={31,29,31,30,31,30,31,31,30,31,30,31};
- void zhongshe();
- void qishe();
- void naoshe();
- void shezhi();
- void delay10ms(void) //误差 0us
- {
- unsigned char a,b,c;
- for(c=1;c>0;c--)
- for(b=38;b>0;b--)
- for(a=130;a>0;a--);
- }
- void delay(unsigned int a) //
- {
- unsigned int b,c;
- for(c=a;c>0;c--)
- for(b=500;b>0;b--);
-
- }
- void naozhong()
- { uint a,m;
- if((shi1==shi)&&(fen1==fen)&&(kai%2))
- { for(m=20;m>0;m--)
- for(a=10;a>0;a--)
- if((k1==0)||(k2==0)||(k3==0)||(k4==0))//按任意键 停止闹铃
- { kai=0;break; }
- else
- beet=~beet;
- }
- }
- void plays() //输出显示数组中的值***********************************************************************************
- {
- unsigned char i;
- unsigned int j;
- for(i=0;i<8;i++)
- {
- switch(i) //位选,选择点亮的数码管,
- {
- case(0):
- LSA=0;LSB=0;LSC=0; break;//选中第0位
- case(1):
- LSA=1;LSB=0;LSC=0; break;//选中第1位
- case(2):
- LSA=0;LSB=1;LSC=0; break;//选中第2位
- case(3):
- LSA=1;LSB=1;LSC=0; break;//选中第3位
- case(4):
- LSA=0;LSB=0;LSC=1; break;//选中第4位
- case(5):
- LSA=1;LSB=0;LSC=1; break;//选中第5位
- case(6):
- LSA=0;LSB=1;LSC=1; break;//选中第6位
- case(7):
- LSA=1;LSB=1;LSC=1; break;//选中第7位
- }
- play=shuma[shijian[i]]; //显示数组中选中的元素代表的值
- if(t>50)
- { switch(she)
- {
- case(3):
- if((i==0)||(i==1))
- play=0x00; break;
- case(2):
- if((i==3)||(i==4))
- play=0x00; break;
- case(1):
- if((i==6)||(i==7))
- play=0x00; break;
- }
- }
- j=10; //扫描间隔时间设定
- while(j--);
- play=0x00;//消隐
- }
- }
- void nao() //把闹钟赋值给数组
- { shijian[7]=kai; //闹钟开启标志
- shijian[6]=11;
- shijian[5]=11;
- shijian[4]=fen1%10;
- shijian[3]=fen1/10;
- shijian[2]=10;
- shijian[1]=shi1%10;
- shijian[0]=shi1/10;
- }
- void rili() //日期赋值给数组
- { shijian[7]=ri%10;
- shijian[6]=ri/10;
- shijian[5]=10;
- shijian[4]=yue%10;
- shijian[3]=yue/10;
- shijian[2]=10;
- shijian[1]=nian%10;
- shijian[0]=nian/10;
- }
- void zhong() //电子钟赋值给数组
- { shijian[7]=miao%10;
- shijian[6]=miao/10;
- shijian[5]=10;
- shijian[4]=fen%10;
- shijian[3]=fen/10;
- shijian[2]=10;
- shijian[1]=shi%10;
- shijian[0]=shi/10;
- }
- void xuehao() //学号赋值给数组************************************************************************
- { shijian[0]=10;
- shijian[1]=2;
- shijian[2]=3;
- shijian[3]=12;
- shijian[4]=13;
- shijian[5]=14;
- shijian[6]=2;
- shijian[7]=8;
- }
- void chushizhuangtai()//初始状态设置 上电复位后 依次显示学号 和制造日期************************************************************************************************
- {
- uint csj;
- for(csj=500;csj>1;csj--)
- { xuehao();
- plays();
- delay(1);
- plays();//显示学号
- }
- for(csj=300;csj>1;csj--)
- { rili();
- plays();
- delay(1);//显示日期
- plays();
- }
- }
- void InitTimer0(void)//开定时器0中断 设定10ms**************************************************************************
- {
- TMOD = 0x01;
- TH0 = 0x0D8;
- TL0 = 0x0F0;
- EA = 1;
- ET0 = 1;
- TR0 = 1;
- } //*****************************************************************************************************************
- void shezhi()//在有位选信号(也就是she不等于零)的条件下,判断k2,k3是否有键按下,并根据当前所处的模式切换到对应的处理函数
- { if((she!=0)&&((k2==0)||(k3==0))) //
- { delay10ms();
- if((she!=0)&&((k2==0)||(k3==0))) //如果 有加减键按下 且标志位 she 在不在 0 状态
- {
- switch(num)
- { case(0):
- zhongshe(); break;
- case(1):
- qishe(); break;
- case(2):
- naoshe();break;
- }
- }
- }
- }
- //*******************************************************************************************
- void main()
- {
-
- num=0;kai=1;she=0;
- fen1=1;shi1=12;
- miao=0;fen=0; shi=12;
- ri=21; yue=6; nian=16;
- chushizhuangtai();
- InitTimer0();
- while(1)
- {
- if(k1==0)
- {delay10ms();
- if(k1==0)
- {num=(num+4)%3;
- she=0;}
- led=~led;
- while(!k1) ;}
- if(k4==0)
- {delay10ms();
- if(k4==0)
- she=(she+5)%4;
- while(!k4) ;
- }
- shezhi();
- naozhong();
- plays();
-
- }
- }
- //**********************************************************************************************************************
- void Timer0Interrupt(void) interrupt 1 //作用。 1,每秒加一计数。2,处理模式转换标志 实现模式切换
- {
- TH0 = 0x0D8;
- TL0 = 0x0F0; //初值 55536 一次中段时间 10ms
- t++;
- if(t==100)
- { t=0;
- miao++;
- if(miao>59)
- { miao=0;
- fen++;
- if(fen>59)
- {
- fen=0;
- shi++;
- if(shi>23)
- {
- shi=0;
- ri++;
- if(nian%4==0)
- { if(ri>runyue[yue-1])
- { ri=1;
- yue++; }
- if(yue>12)
- { yue=1;
- nian++; }
- }
- else
- {if(ri>brunyue[yue-1])
- {
- ri=0;
- yue++;
- }
- if(yue>12)
- {
- yue=0;
- nian++ ;
- }
- }
- }
- }
- }
- }
- switch(num)
- {
- case(0):
- zhong();break; // 把时钟的值装入数组。
- case(1):
- rili();break;// 把日期的值装入数组。
- case(2):
- nao();break; // 把闹钟的值装入数组。
- default:
- zhong();//
- }
- }
- //***********************************************************************************************************************
- void zhongshe()//处于时钟状态下,当有加减信号时的处理
- {
- switch(she)
- {
- case(1):
- miao=0;InitTimer0();break;
- case(2): // 位选信号为分
- if(k2==0)
- fen=(fen+61)%60;//如果加信号,则分加一。否则减一
- else
- fen=(fen+59)%60;
- break;
- case(3): //位选信号为时
- if(k2==0)
- shi=(shi+25)%24;
- else
- shi=(shi+23)%24;
- break;
- }
- while((!k2)||(!k3)) ; //松手检测
- }
- void naoshe() //同上
- {
- switch(she)
- {
- case(1):
- if(kai==1)
- kai=0;
- else kai=1; break;//闹钟的开关
- case(2):
- if(k2==0)
- fen1=(fen1+61)%60;
- else
- fen1=(fen1+59)%60;
- break;
- case(3):
- if(k2==0)
- shi1=(shi1+25)%24;
- else
- shi1=(shi1+23)%24;
- break;
- }
- while((!k2)||(!k3)) ;
- }
- void qishe() //同上
- {
- switch(she)
- {
- case(1):
- if(k2==0)
- {
- if(nian%4==0)
- ri=(ri+runyue[yue-1]+2)%(runyue[yue-1]+1) ;
- else
- ri=(ri+brunyue[yue-1]+2)%(brunyue[yue-1]+1);
- }
-
- else
- {
- if(nian%4==0)
- ri=(ri+runyue[yue-1])%(runyue[yue-1]+1) ;
- else
- ri=(ri+brunyue[yue-1])%(brunyue[yue-1]+1);
- }
- break;
- case(2):
- if(k2==0)
- yue=(yue+14)%13;
- else
- yue=(yue+12)%13;
- break;
- case(3):
- if(k2==0)
- nian++;
- else
- nian--;
- }
- while((!k2)||(!k3)) ;
- }
复制代码
所有资料51hei提供下载:
数字电路设计.rar
(720.29 KB, 下载次数: 77)
|