单片机时分秒C编程
C51单片机秒表计时(C语言)

{ cout++;
mm=0;}
}
效果显示
图一(电路总图)
图二(效果显示)注:第四位显示为单位:S
程序清单
#include<reg51.h>
#include<stdio.h>
unsigned char Tab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F };
sbit P37=P3^7;
}
/*********显示程序*****************/
void display()
{
x=cout/10;//秒十位
P34=0;
P1=Tab[x]; delay();
P34=1;
y=cout-x*10; //秒各位
P35=0;
P1=Tab[y]; delay();
P1=做任何修改或编辑并不能对任何下载内容负责
南开大学滨海学院
C51嵌入式软件设计(C语言)
题目:计时秒表
功能描述:本设计实现在99秒内的秒表计时,一个按键实现开始、暂停、复位。
原理概述:P1接四位七段数码管,P3.2接一按键产生外部中断0,P3.4-P3.7控制扫描显示。计时使用定时器0产生10ms中断累计。按键不同次序决定了对应的控制功能,因为第一次按键必定为开始计时,所以第二次按键判断为暂停,依次第三次为置零。主程序调用显示程序,显示程序实时显示计时时间。
sbit P36=P3^6;
sbit P35=P3^5;
sbit P34=P3^4;
unsigned int a=0,cout=0,mm=0;x,y,p,q;
单片机-数码管-时分秒显示

#include<>#define uchar unsigned char#define uint unsigned intuchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//0~9的数码管显示sbit dula=P2^6;//声明段选sbit wela=P2^7;//声明位选uchar h,m,s,num1;//定义变量void delay(uint xms)//延时函数{uint i,j;for(i=xms;i>0;i--)for(j=110;j>0;j--);}void init()//初始化{TMOD=0x10;// 0001 0001 定时器0的工作方式1,定时器1的工作方式1 TH1=(65536-45872)/256;TL1=(65536-45872)%256;EA=1;//开总中断ET1=1;//开定时器1中断TR1=1;//启动定时器1}void main()//主函数{init(); //初始化while(1) //while循环{wela=1; //打开位选P0=0xfe; //点亮数码管wela=0; //关闭位选dula=1; //打开段选P0=table[h/10];//送入数据dula=0; // 关闭段选delay(1); //延时5mswela=1; //打开位选P0=0xfd; //点亮数码管wela=0; //关闭位选dula=1; //打开段选P0=table[h%10];//送入数据dula=0; // 关闭段选delay(1); //延时5mswela=1; //打开位选P0=0xfb; //点亮数码管wela=0; //关闭位选dula=1; //打开段选P0=table[m/10];//送入数据dula=0; // 关闭段选delay(1); //延时5mswela=1; //打开位选P0=0xf7; //点亮数码管wela=0; //关闭位选dula=1; //打开段选P0=table[m%10];//送入数据dula=0; // 关闭段选delay(1); //延时5mswela=1; //打开位选P0=0xef; //点亮数码管wela=0; //关闭位选dula=1; //打开段选P0=table[s/10];//送入数据dula=0; // 关闭段选delay(1); //延时5mswela=1;P0=0xdf;wela=0;dula=1;P0=table[s%10];dula=0;delay(1);}}void T1_time()interrupt 3 //中断3{TH1=(65536-45872)/256; //重装初值TL1=(65536-45872)%256; //num1++; //num2每加一次判断一次是否到20次了if(num1==20) //如果到了20次,说明1秒钟到了{num1=0; //把num1清零,重新再计20次s++; //s每加一次判断一次,是否到60次了if(s==60) //如果到了60次,说明1分钟到了{s=0; //把s清零,重新再计60次m++; //m每加一次判断一次是否到60次了if(m==60) //如果到了60次,说明1小时到了{m=0; //把m清零,重新再计60次h++; //h每加一次判断一次是否到24次了if(h==24)//如果h到了24次,说明24小时到了{h=0; //把m清零,重新再计60次}}}}}。
C语言数字钟(单片机)

Fax:86-0731-******* Mail:dsc52@ Web: 源点教育项目报告一、功能要求:(1)、电路图对学员要求是一样,完整电路图请见原理图。
(2)、由图1所示:正常显示(上电显示)如下:星期时分两红灯亮秒闪(3)、●按下key1第一次,显示如下:年月{阳历}日{阳历}两红灯亮两灯亮●再按下key1,则回到正常显示,依次类推。
(4)、在任何显示状态下,按下key1超过2秒,则进入设置状态,同时显示“时、分、秒”闪烁。
此时按下key2,“秒”闪,进入设置状态。
再按下key2,“分”闪,进入设置状态。
再按下key2,“时”闪,进入设置状态。
再按下key2,显示“星期、月{阳历}、日{阳历}”,同时“日{阳历}”闪,进入设置状态。
再按下key2,“月{阳历}”闪,进入设置状态。
再按下key2,“星期”闪,进入设置状态。
再按下key2,显示“年(四个数码管显示)”,同时“年”闪,进入设置状态。
再按下key2,则回到“秒”重复设计置。
注:进入设置状态时,key3作减键,key4作加键,并且key3,key4具有连动功能(如果key3或者key4按下持续1秒后,以0.5秒时间连减或者连加)(5)、在(2)的任何状态下,按下key5,则回正常显示。
(6)、在正常显示状态下:按下key5超过2秒,则进入闹钟设置状态。
Fax:86-0731-******* Mail:dsc52@ Web: 再按key5则回正常显示。
三、扩展功能要求。
(1)、按下key6,把闹钟时间存于AT24C16里。
(2)、由图1所示:正常显示(上电显示)如下:星期时分两红灯亮秒闪(3)、●按下key1第一次,显示如下:年月{阳历}日{阳历}两红灯亮两灯亮●按下key1第二次,显示如下:年月{阴历}日{阴历}两红灯闪两灯闪●再按下key1,则回到正常显示,依次类推。
(4)、在任何显示状态下,按下key1超过2秒,则进入设置状态,同时显示“时、分、秒”闪烁。
用c语言实现钟表

1. 引入所需的头文件:你需要引入一些头文件来实现程序的功能,例如 stdio.h、stdlib.h、time.h 等。
2. 定义程序的数据结构:你可以定义一个结构体来表示钟表的时间,包括时、分、秒等字段。
3. 获取当前时间:使用 time 函数获取当前系统时间,并将其转换为时、分、秒等字段。
localTime->tm_sec);
22.
23.
// 暂停一秒钟
Байду номын сангаас
24.
sleep(1);
25. }
26.
27. return 0;
28. }
29. 这个程序会不断获取当前系统时间,并输出格式为"时:分:秒"的钟表界面。程序会每 秒钟更新一次时间,并在终端上显示。你可以根据需要进行适当的修改和扩展,例
time_t currentTime = time(NULL);
17.
struct tm *localTime = localtime(¤tTime);
18.
19.
// 输出钟表界面
20.
system("clear"); // 清屏(适用于 Linux 和 Mac)
21.
printf("%02d:%02d:%02d\n", localTime->tm_hour, localTime->tm_min,
7. 下面是一个简单的 C 语言实现钟表的代码示例:
8. c 复制代码
9. #include <stdio.h>
10. #include <stdlib.h>
单片机C语言_电子时钟程序

#include<AT89X52.H>#define uint unsigned int#define uchar unsigned charunsigned char key2;bit ding=1;unsigned char Getkey(void);uchar a,n=0,shi,fen,miao;void delay01s(void);uchar LED[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};uchar LED1[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//有小数点的void init(); //函数声明void Delay(unsigned char z);//函数声明void display(); //函数声明//函数声明void main() //函数声明{P1=0xfe;//对P1口赋初值init(); //函数调用while(1){//函数调用key2=Getkey();switch(key2){case 1:shi++;if(shi==24){shi=0;}break;case 2:fen++;if(fen==60){fen=0;}break;case 3:if(fen!=0)fen--;if(fen==24){fen=0;}break;case 4:ding=~ding;default:break;}display(); //函数调用}}void init(){TMOD=0x01; //定时器工作方式选择和赋初值TH0=(65536-50000)/256;TL0=(65536-50000)%256;EA=1; //开总中断ET0=1; //开定时器中断TR0=1; //启动定时器}void timer0() interrupt 1 //中断服务程序{if(ding==1){TH0=(65536-50000)/256;//中断时间50msTL0=(65536-50000)%256; //定时器重新赋初值a++;if(a==10){n=~n;}if(a==20){n=~n;a=0;P1=P1<<1|P1>>7;miao++;if(miao==60){miao=0;fen++;if(fen==60){fen=0;shi++;if(shi==24){shi=0;}}}}}}void display()//显示程序{P0=LED[shi/10];P2=((P2&0x0f)|0x70); Delay(4);if(n==0){P0=LED[shi%10];}else{P0=LED1[shi%10];}P2=((P2&0x0f)|0xb0);Delay(4);P0=LED[fen/10];P2=((P2&0x0f)|0xd0);Delay(4);P0=LED[fen%10];P2=((P2&0x0f)|0xe0);Delay(4);}/**********获得键值子程序**********************/ unsigned char bool;//bool 是否松键的标志unsigned char Getkey(void){unsigned char temp,key=0;P2=(P2&0xff)|0x0f;if((P2&0xff)!=((P2&0xff)|0x0f)) // 有键按下{//delay01s();if(((P2&0xff)!=((P2&0xff)|0x0f)) &&(bool==0)) // 有键按下{temp=~(P2|0xf0);if(temp==1) key=1;else if(temp==2) key=2;else if(temp==4) key=3;else if(temp==8) key=4;bool=1;}}if(((P2&0xff)==((P2&0xff)|0x0f)) &&(bool==1)){bool=0;}return key; //返回1~16键值}/********延时程序******/void delay01s(void){unsigned char j,k;for(j=5;j>0;j--) //198{for(k=15;k>0;k--)//248{;}}}void Delay(unsigned char z){unsigned char i,j,k; //定义变量for(i=z;i>0;i--)for(j=25;j>0;j--)for(k=20;k>0;k--);}#include<reg52.h>//头文件#define uchar unsigned char//宏定义#define uint unsigned intsbit P31=P3^1;//位声明sbit P32=P3^2;sbit P33=P3^3;uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//共阴段码表uint hou1,hou2,min1,min2,sec1,sec2,numhou,nummin,numsec,yue1,yue2,ri1,ri2,numyue,numri; uint num,m,n;void delayms(uint xms)//延时函数{uint i,j;for(i=xms;i>0;i--)for(j=110;j>0;j--);}void p31xd()//按键P31消抖{ delayms(2);while(P31!=1);delayms(2);}void p32xd()//按键P32消抖{ delayms(1);while(P32!=1);delayms(1);}void p33xd()//按键P33消抖{ delayms(1);while(P33!=1);delayms(1);}void displaysj()//显示时间{P2=0x00;P0=table[hou1];//显示时的第一位P2=0X20;delayms(1);P2=0xff;P0=table[hou2]&0x7f;//显示时的第二位与小数点P2=0X10;delayms(1);P2=0xff;P0=table[min1];//显示分的第一位P2=0X08;delayms(1);P2=0xff;P0=table[min2]&0x7f;//显示时的第二位与小数点P2=0X04;delayms(1);P2=0xff;P0=table[sec1];//显示秒的第一位P2=0X02;delayms(1);P2=0xff;P0=table[sec2];//显示秒的第二位P2=0X01;delayms(1);}void displayrq()//显示日期{ P2=0x00;P0=table[yue1];//显示月的第一位P2=0X20;delayms(1);P2=0x00;P0=table[yue2]&0x7f;//显示月的第二位P2=0X10;delayms(1);P2=0x00;P0=table[ri1];//显示日的第一位P2=0X08;delayms(1);P2=0x00;P0=table[ri2];//显示日的第二位P2=0X04;delayms(1);}void houqh()//时针切换函数{hou1=numhou/10;hou2=numhou%10;}void minqh()//分针切换函数{min1=nummin/10;min2=nummin%10;}void secqh()//秒针切换函数{sec1=numsec/10;sec2=numsec%10;}void yueqh()//月切换函数{yue1=numyue/10;yue2=numyue%10;}void riqh()//日切换函数{ri1=numri/10;ri2=numri%10;}void start()//初始化函数{num=0;TMOD=0x01;TH0=(65532-45872)/256;TL0=(65532-45872)%256;EA=1;IT0=0;//电平触发(低电平有效)EX0=1;ET0=1;TR0=1;yueqh(),riqh();//初始化日月切换}void ritiao()//日期的调节函数{ if(P32==0)//日期加一调节键{p32xd();if((numyue==1)||(numyue==3)||(numyue==5)||(numyue==7)||(numyue==8)||(numyue==10)||( numyue==12)){numri+=1;if(numri>=31)//如果是大月,日期有31号,等于符号是防止日期大于31号而乱码{numri=1;}}if((numyue==4)||(numyue==6)||(numyue==9)||(numyue==11)){numri+=1;if(numri>=30)//如果是小月,日期有30号{numri=1;}}if(numyue==2){numri+=1;if(numri>=28)//如果是小月,日期有28号{numri=1;}}riqh();//日期调节后切换一下}if(P33==0)//日期减一调节键{p33xd();if((numyue==1)||(numyue==3)||(numyue==5)||(numyue==7)||(numyue==8)||(numyue==10)||( numyue==12)){numri-=1;if(numri==0){numri=31;}}if((numyue==4)||(numyue==6)||(numyue==9)||(numyue==11)){numri-=1;if(numri==0){numri=30;}}if(numyue==2){numri-=1;if(numri==0){numri=28;}}riqh();}}void yuetiao()//月份的调节函数{if(P32==0){p32xd();numyue+=1;if(numyue==13)//月份为12时再加一马上为一月{numyue=1;}yueqh();}if(P33==0){p33xd();numyue-=1;if(numyue==0){numyue=12;}yueqh();}}void int0() interrupt 0{p31xd();while(P31!=0)//第一次按下p31时,进行秒调时{for(m=0;m<40;m++)//此for循环不显示秒,为的是使秒闪烁{P2=0x00;P0=table[hou1];P2=0X20;delayms(1);P2=0x00;P0=table[hou2]&0x7f;P2=0X10;delayms(1);P2=0x00;P0=table[min1];P2=0X08;delayms(1);P2=0x00;P0=table[min2]&0x7f;P2=0X04;delayms(1);if(P32==0)//如果按一下P32,则秒加一{p32xd();numsec+=1;if(numsec==60){numsec=0;}secqh();}if(P33==0)//如果按一下P33,则秒减一{p33xd();numsec-=1;if(numsec==-1){numsec=59;}secqh();}};for(n=0;n<40;n++)//此循环时分秒全显示,也为的是使秒闪烁{ displaysj();if(P32==0){p32xd();numsec+=1;if(numsec==60){numsec=0;}secqh();}if(P33==0){p33xd();numsec-=1;if(numsec==-1){numsec=59;}secqh();}}};p31xd();while(P31!=0)//第二次按下p31时,进行分调时{for(m=0;m<40;m++){P2=0x00;P0=table[hou1];P2=0X20;delayms(1);P2=0x00;P0=table[hou2]&0x7f;P2=0X10;delayms(1);P2=0x00;P0=table[sec1];P2=0X02;delayms(1);P2=0x00;P0=table[sec2];P2=0X01;delayms(1);if(P32==0){p32xd();nummin+=1;if(nummin==60){nummin=0;}minqh();}if(P33==0){p33xd();nummin-=1;if(nummin==-1){nummin=59;}minqh();}}for(n=0;n<40;n++){ displaysj();if(P32==0){p32xd();nummin+=1;if(nummin==60){nummin=0;}minqh();}if(P33==0){nummin-=1;if(nummin==-1){nummin=59;}minqh();}}};p31xd();while(P31!=0)//第三次按下p31时,进行时调时{for(m=0;m<40;m++){P2=0x00;P0=table[min1];P2=0X08;delayms(1);P2=0x00;P0=table[min2]&0x7f;P2=0X04;delayms(1);P2=0x00;P0=table[sec1];P2=0X02;delayms(1);P2=0x00;P0=table[sec2];P2=0X01;delayms(1);if(P32==0){p32xd();numhou+=1;if(numhou==24){numhou=0;}}if(P33==0){p33xd();numhou-=1;if(numhou==-1){numhou=23;}houqh();}}for(n=0;n<40;n++){ displaysj();if(P32==0){p32xd();numhou+=1;if(numhou==24){numhou=0;}houqh();}if(P33==0){p33xd();numhou-=1;if(numhou==-1){numhou=23;}houqh();}}}p31xd();while(P31!=0)//第四次按下p31时,进行日期调节{for(m=0;m<50;m++){ P2=0x00;P0=table[yue1];P2=0x20;delayms(1);P2=0x00;P0=table[yue2]&0x7f;P2=0x10;delayms(1);ritiao();}for(n=0;n<50;n++){ displayrq();ritiao();}}p31xd();while(P31!=0)//第五次按下p31时,进行月调节{for(m=0;m<50;m++){P2=0xff;P0=table[ri1];P2=0xf7;delayms(1);P2=0xff;P0=table[ri2];P2=0xfb;delayms(1);yuetiao();}for(n=0;n<50;n++){ displayrq();yuetiao();}}p31xd();}void yuejia(){ numri=1;numyue+=1;if(numyue==13){numyue=1;}}void timer0() interrupt 1{TH0=(65532-46100)/256;TL0=(65532-46100)%256;num++;if(num==20){num=0;TH0=(65532-46100)/256;TL0=(65532-46100)%256;numsec=numsec+1;if(numsec==60){numsec=0;nummin=nummin+1;if(nummin==60){nummin=0;numhou=numhou+1;if(numhou==24){numhou=0;numri+=1;if((numyue==1)||(numyue==3)||(numyue==5)||(numyue==7)||(numyue==8)||(numyue==10)||( numyue==12)){numri+=1;if(numri>=31){numri=1;numyue+=1;if(numyue==13){numyue=1;}}}if((numyue==4)||(numyue==6)||(numyue==9)||(numyue==11)){numri+=1;if(numri>=31){numri=1;numyue+=1;if(numyue==13){numyue=1;}}}if(numyue==2){numri+=1;if(numri>=29){numri=1;numyue+=1;if(numyue==13){numyue=1;}}}}}}}}void main(){numhou=12;//初始化时间设为12点,日期设为1月1日nummin=0;numsec=0;numyue=1;numri=1;start();while(1){if(P32==1)//默认(没有按下p32时)显示时间{houqh(),minqh(),secqh();displaysj();}if(P32==0)//当按下p32键时显示日期{yueqh(),riqh();displayrq();}}}。
单片机基于c语言编写时钟

单片机基于c语言编写时钟#include <REGX51.H>#define uint unsigned int#define uchar unsigned charchar led[10]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xe6};//共阴数码管数字码#define weixuan P0 //P0为数码管的段选sbit sck=P2^7; //移位时钟sbit tck=P2^6; //锁存时钟sbit data1=P2^5; //串行数据输入sbit x1=P1^0;sbit x2=P1^1;sbit x3=P1^2;sbit bee=P3^5;sbit time_change=P1^5; //P3^0为"调时"按键sbit time_choose=P1^6; //P3^1为"选择时分秒"按键sbit time_inc=P1^7; //P3^2为"增加"按键sbit time_ok=P3^3; //P3^3为"完成"按键uint t;uchar sec,min,hour,sec_ge,sec_shi,min_ge,min_shi,hour_ge,hour_shi; //定义秒,分,时,秒的个位,十位,分的个位,十位,时的个位,十位int choose_n; //按下"选择时分秒"按键的次数int flag; //定义"调时"按键的标志位//---------------------------------------------------------------------void init();void display();void delay(int x);void time_modify();void send(uchar data8);void naozhong();//---------------------------------------------------------------------void main(){init();while(1){TR0=1;display();time_modify();}}//---------------------------------------------------------------------void init(){t=choose_n=0;sec_ge,sec_shi,min_ge,min_shi,hour_ge,hour_shi,sec=min=hour=flag=0;TMOD=0x01; //定义定时器0工作与方式1TH0=(65536-60000)/256; //定时器赋初值TL0=(65536-60000)%256;EA=1; //开总中断和T0中断ET0=1;}//---------------------------------------------------------------------void send(uchar data8) // 数据发送{uchar i;//设置循环变量sck=1;tck=1;for(i=0;i<=7;i++){if((data8>>i)&0x01)data1=1;elsedata1=0;sck=0;sck=1;}tck=0;tck=1;}//--------------------------------延时子函数------------------------------------void delay(int x){int i,j;for(i=0;i<=x;i++)for(j=0;j<=100;j++);}//-------------------------------显示子函数---------------------------------------void display(){int i=0;if(TF0==1) //如果定时器溢出{TF0=0; //清中断标志位t++;if(t==18){t=0;sec++; //秒加1if(sec==60) //如果秒为60,则清零,分加1{sec=0;min++;}if(min==60) //如果分为60,则清零,时加1{min=0;hour++;}if(hour==24) //如果时为24,则清零{hour=0;}}}sec_ge=sec%10; //秒的个位和十位sec_shi=sec/10;min_ge=min%10; //分的个位和十位min_shi=min/10;hour_ge=hour%10; //时的个位和十位hour_shi=hour/10;weixuan = 0xff; // p0口为1111 1111send(led[hour_shi]); // 显示第一位时weixuan= 0xfe; // p0口为1111 1110delay(1);weixuan=0xff; // 消影send(led[hour_ge]); // 显示第二位时weixuan= 0xfd; // p0口为1111 1101delay(1);weixuan=0xff; // 消影send(0x02); // 显示第三位weixuan= 0xfb; // p0口为1111 1011delay(1);weixuan=0xff; // 消影send(led[min_shi]); // 显示第四位分weixuan= 0xf7; // p0口为1111 0111delay(1);weixuan=0xff; // 消影send(led[min_ge]); // 显示第5位分weixuan= 0xef; // p0口为1110 1111delay(1);weixuan=0xff; // 消影send(0x02); // 显示第6位weixuan= 0xdf; // p0口为1101 1111delay(1);weixuan=0xff; // 消影send(led[sec_shi]); // 显示第7位秒weixuan= 0xbf; // p0口为1011 1111delay(1);weixuan=0xff; // 消影send(led[sec_ge]); // 显示第8位秒weixuan= 0x7f; // p0口为0111 1111delay(1);weixuan=0xff; // 消影}//----------------------------调时子程序-------------------------------void time_modify(){if(time_change==0) //如果"调时"按键按下{delay(5); //延时去抖if(time_change==0){flag=1; //标志位置1while(flag) //当标志位为1时才能进行时间调整{TR0=0; //定时器停止display(); //显示停止时的时间if(time_ok==0) //如果"完成"按键按下{delay(15); //延时去抖if(time_ok==0){flag=0; //标志位清零x1=1;x2=1;x3=1;}}if(time_choose==0) //如果"时分秒选择"按键按下{delay(30); //延时去抖if(time_choose==0){while(!time_choose);choose_n++; //按下的次数增加if(choose_n==4) //如果次数达到4次{choose_n=1; //次数清零}if(choose_n==1) //如果次数为1,秒指示灯亮{x1=0;x2=1;x3=1;}else if(choose_n==2) //如果次数为2,分指示灯亮{x1=1;x2=0;x3=1;}else if(choose_n==3) //如果次数为3,时指示灯亮{x1=1;x2=1;x3=0;}}}if(time_inc==0) //如果"增加"按键按下{delay(30); //延时去抖if(time_inc==0){switch(choose_n) //分支结构,根据choose_n的值来判断哪一位加1 {case 1: //如果choose_n为1,秒加1,到60清零{while(!time_inc);sec++;if(sec==60)sec=0;break;}case 2: //如果choose_n为2,分加1,到60清零{while(!time_inc);min++;if(min==60)min=0;break;}case 3: //如果choose_n为3,时加1,到24清零{while(!time_inc);hour++;if(hour==24)hour=0;break;}default:break;}}}}}}}。
基于51单片机的时钟C语言代码

基于51单⽚机的时钟C语⾔代码#include#define uint unsigned int#define uchar unsigned charsbit dula=P2^6; //定义锁存器锁存端sbit wela=P2^7;sbit rs=P3^5; //定义1602液晶RS端sbit lcden=P3^4; //定义1602液晶LCDEN端sbit s1=P3^0; //按键功能键sbit s2=P3^1; //增⼤键sbit s3=P3^2; //减⼩键sbit rd=P3^7;sbit beep=P2^3;sbit sda=P2^0;sbit scl=P2^1;uchar a;void delay21(){ ;; }void start() //{sda=1;delay21();scl=1;delay21();sda=0;delay21();}void stop() //{sda=0;delay21();scl=1;delay21();sda=1;delay21();{uchar i;scl=1;delay21();while((sda==1)&&(i<250))i++; scl=0;delay21();}void init_24c02(){sda=1;delay21();scl=1;delay21();}void write_byte(uchar date) { uchar i,temp;temp=date;for(i=0;i<8;i++){temp=temp<<1;scl=0;delay21();sda=CY;delay21();scl=1;delay21();// scl=0;// delay21();}scl=0;delay21();sda=1;delay21();uchar read_byte(){uchar i,k;scl=0;delay21();sda=1;delay21();for(i=0;i<8;i++){scl=1;delay21();k=(k<<1)|sda;scl=0;delay21();}return k;}void write_add(uchar address,uchar date) { start();write_byte(0xa0);respons();write_byte(address);respons();write_byte(date);respons();stop();}uchar read_add(uchar address){uchar date;start();write_byte(0xa0);respons();write_byte(address);write_byte(0xa1);respons();date=read_byte();stop();return date;}uchar count,s1sum;char miao,shi,fen;uchar code table[]="2016-11-10 xiao";//定义初始上电时液晶默认显⽰状态void delay(uint z) {uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void di(){beep=0;delay(100);beep=1;}void write_com(uchar com)//写指令{rs=0;lcden=0;P0=com;delay(5);lcden=1;delay(5);lcden=0;}void write_date(uchar date)//写数据{rs=1;delay(5);lcden=1;delay(5);lcden=0;}void write_sfm(uchar add,uchar date){uchar shi,ge;shi=date/10;ge=date%10;write_com(0x80+0x40+add); //设置显⽰位置write_date(0x30+shi);write_date(0x30+ge);}void init()//初始化函数{uchar num;rd=0; //软件将矩阵按键第四列⼀端置低⽤以分解出独⽴按键dula=0; //关闭两锁存器锁存端;防⽌操作液晶时数码管出现乱码wela=0;lcden=0;fen=0;miao=0;shi=0;count=0;s1sum=0;init_24c02(); //write_com(0x38); //初始化1602液晶write_com(0x0c);write_com(0x06);write_com(0x01);write_com(0x80); //设置显⽰初始坐标for(num=0;num<16;num++){write_com(0x80+0x40+6); //显⽰时间的冒号write_date(':');delay(5);write_com(0x80+0x40+9);write_date(':');delay(5);miao=read_add(1);//⾸次上电从AT24C02中读出的存储的数据fen=read_add(2);shi=read_add(3);write_sfm(10,miao); //分别送去液晶显⽰write_sfm(7,fen);write_sfm(4,shi);TMOD=0x01;//设置定时器0为⼯作⽅式1TH0=(65536-50000)/256;TL0=(65536-50000)%256;EA=1;//开总中断ET0=1;//开定时器0中断TR0=1;//启动定时器0}void keyscan() //按键扫描函数{if(s1==0){delay(5);if(s1==0) //确认功能键被按下{s1sum++; //功能键按下记录次数while(!s1); //释放确认di(); //每当有按键释放蜂鸣器发出滴声if(s1sum==1) //第⼀次被按下时{TR0=0; //关闭定时器write_com(0x80+0x40+10); //光标定位到秒位置if(s1sum==2) //第⼆次按下光标定位到分位置{write_com(0x80+0x40+7);}if(s1sum==3) //第⼆次按下光标定位到时位置{write_com(0x80+0x40+4);}if(s1sum==4) //第四次按下{s1sum=0; //记录按键数清零write_com(0x0c); //取消光标闪烁TR0=1; //启动定时器使时钟开始⾛}}}if(s1sum!=0) //只有功能键被按下后,增⼤和减⼩键才有效{ if(s2==0){delay(5);if(s2==0) //增加键确认被按下{while(!s2); //按键释放di();if(s1sum==1) //若功能键第⼀次按下{miao++; //+1秒if(miao==60) miao=0;write_sfm(10,miao);//调节⼀次送液晶显⽰⼀次write_com(0x80+0x40+10);//显⽰位置重新回到调节处write_add(1,miao); //数据改变⼀次⽴即存⼊24C02 }if(s1sum==2){if(fen==60) fen=0;write_sfm(7,fen);write_com(0x80+0x40+7);write_add(2,fen);}if(s1sum==3){shi++;if(shi==24) miao=0;write_sfm(4,shi);write_com(0x80+0x40+4);write_add(3,shi);}}}if(s3==0){delay(5);if(s3==0) //增加键确认被按下{while(!s3); //按键释放di();if(s1sum==1) //若功能键第⼀次按下{miao--; //+1秒if(miao==-1) miao=59;write_sfm(10,miao);//调节⼀次送液晶显⽰⼀次write_com(0x80+0x40+10);//显⽰位置重新回到调节处write_add(1,miao); //数据改变⼀次⽴即存⼊24C02 } if(s1sum==2){fen--;if(fen==-1) fen=59;write_sfm(7,fen);write_add(2,fen);}if(s1sum==3){shi--;if(shi==-1) miao=23;write_sfm(4,shi);write_com(0x80+0x40+4);write_add(3,shi);}}}}}void main(){init(); //初始化各数据while(1){keyscan(); //不停地检测按键是否被按下}}void time0() interrupt 1 //定时器0中断服务程序{TH0=(65536-50000)/256;TL0=(65536-50000)%256;count++;if(count==20) //20次50毫秒为⼀秒{count=0;miao++;if(miao==60){miao=0;fen++;{fen=0;shi++;if(shi==24){shi=0;}write_sfm(4,shi); //⼩时若变化则重新写⼊write_add(3,shi); //数据改变⽴即存⼊24C02 }write_sfm(7,fen);write_add(2,fen);}write_sfm(10,miao);write_add(1,miao);}}。
单片机数码秒表设计C语言程序

//实例65:数码秒表设计#include<reg51.h> // 包含51单片机寄存器定义的头文件unsigned char code Tab[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//数码管显示0~9的段码表unsigned char int_time; //记录中断次数unsigned char second; //储存秒/*********************************************************************** 函数功能:快速动态扫描延时,延时约0.6毫秒************************************************************************/ void delay(void){unsigned char i;for(i=0;i<200;i++);}/*********************************************************************** 函数功能:显示秒入口参数:k出口参数:无************************************************************************/ void DisplaySecond(unsigned char k){P2=0xfb; //P2.6引脚输出低电平,DS6点亮P0=Tab[k/10]; //显示十位delay();P2=0xf7; //P2.7引脚输出低电平,DS7点亮P0=Tab[k%10]; //显示个位delay();P2=0xff; //关闭所有数码管}void main(void) //主函数{TMOD=0x01; //使用定时器T0TH0=(65536-46083)/256; //将定时器计时时间设定为46083×1.085微秒//=50000微秒=50毫秒TL0=(65536-46083)%256;EA=1; //开启总中断ET0=1; //定时器T0中断允许TR0=1; //启动定时器T0开始运行int_time=0; //中断次数初始化second=0; //秒初始化while(1){DisplaySecond(second); //调用秒的显示子程序}}//********************************************************//函数功能:定时器T0的中断服务程序//*******************************************************void interserve(void ) interrupt 1 using 1{TR0=0; //关闭定时器T0int_time ++; //每来一次中断,中断次数int_time自加1if(int_time==20) //够20次中断,即1秒钟进行一次检测结果采样{int_time=0; //中断次数清0second++; //秒加1if(second==60)second =0; //秒等于60就返回0}TH0=(65536-46083)/256; //重新给计数器T0赋初值TL0=(65536-46083)%256;TR0=1; //启动定时器T0}。