急求一个用AT89C52控制,2个4位数码管(用74HC595驱动)显示的简易时分秒的电子钟。需要c语言程序。附图
你好!显示时分秒,然后通过按键调节时间?
主要看你的数码管是共阴还是共阳的,如果是共阳那就好办,595的8个输出连数码管的7段和小数点,然后两个位选直接用8550驱动就行了,程序的思路就是先选通位,然后给595段码,然后延时再选通另外一位再给595段码延时,一直重复这个就行了。
/************************************************/
/*******************数字电子钟*******************/
/************************************************/
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit qingling=P1^0; //清零
sbit tiaofen=P1^1; //调分
sbit tiaoshi=P1^2; //调时
sbit sounder=P1^7; //naozhong
sbit ds = P3^5; // 595
sbit st_cp = P3^7;
sbit sh_cp = P3^4;
uint a,b;
uchar hour,minu,sec, //时钟
hour0,minu0,sec0, //秒表
hour1,minu1,sec1;
h1,h2,m1,m2,s1,s2,//显示位
k,s; //状态转换标志
uchar j,datah,datal;
uchar code select[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
/*****************函数声明***********************/
void keyscan();
void init();
void delay(uchar z);
void display(uchar,uchar,uchar);
void sounde();
void disp595();
/*****************主函数*************************/
void main()
{
init();
while(1)
{
while(TR1)
{
keyscan(); //扫描函数
while(s==1) //s是状态标志,当s=0时,闹钟取消。s=1时,设定闹钟时间
{ //s=2时,闹钟工作,时间与设定时刻一致时,闹钟响
keyscan(); //s状态切换(0-》1-》2-》0)通过外部中断1实现。
display(hour1,minu1,sec1); //闹钟时刻显示
}
display(hour0,minu0,sec0);//时钟表显示
while(k) /*k是秒表状态(0-》1-》2-》0)通过外部中断0实现。*/
{
display(hour,minu,sec); //秒表显示
}
}
}
}
/*****************初始化函数***********************/
void init()
{
a=0;
b=0;
k=0;
s=0;
hour0=0;
minu0=0;
sec0=0;
hour=0;
minu=0;
sec=0;
hour1=0;
minu1=0;
sec1=0;
TMOD=0x11; //定时器0,1工作于方式1;赋初值
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
EA=1;
EX0=1; //秒表中断
EX1=1; //闹钟设定中断
ET0=1;
ET1=1;
IT0=1; //边沿触发方式
IT1=1;
PX0=1;
PX1=1;
TR0=0; //初始,秒表不工作
TR1=1; //时钟一开始工作
}
/*****************定时器0中断*************/
void timer0_int() interrupt 1 //秒表
{
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
a++;
if(a==2)
{
a=0;
sec++;
if(sec==100)
{
sec=0; //毫秒级
minu++;
if(minu==60)
{
minu=0; //秒
hour++;
if(hour==60) //分
{
hour=0;
}
}
}
}
}
/*************外部中断0中断函数************/
void ex0_int() interrupt 0
{
k++;
if(k==3)
k=0;
if(k==1)
{
TR0=~TR0;
if(TR0==1)
{
hour=0;
minu=0;
sec=0;
}
}
if(k==2)
{
TR0=~TR0;
}
}
/*************外部中断1中断函数************/
void ex1_int() interrupt 2
{
s++;
if(s==3)
s=0;
}
/*************定时器1中断****************/
void timer1_int() interrupt 3 //控制时钟工作
{
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
if(s==2)
{
if(hour1==hour0 && minu0==minu1)
sounde();
}
b++;
if(b==20)
{
b=0;
sec0++;
if(sec0==60)
{
sec0=0;
minu0++;
if(minu0==60)
{
minu0=0;
hour0++;
if(hour0==24)
hour0=0;
}
}
}
}
/*************键盘扫描****************/
void keyscan()
{
if(s==1)
{
if(qingling==0)
{
delay(10);
if(qingling==0)
{
sec1=0;
minu1=0;
hour1=0;
}
}
if(tiaofen==0)
{
delay(10);
if(tiaofen==0)
{
minu1++;
if(minu1==60)
{
minu1=0;
}
while(!tiaofen);
}
}
if(tiaoshi==0)
{
hour1++;
if(hour1==24)
{
hour1=0;
}
while(!tiaoshi);
}
}
else //调整时钟时间
{
if(qingling==0)
{
delay(10);
if(qingling==0)
{
sec0=0;
minu0=0;
hour0=0;
}
}
if(tiaofen==0)
{
delay(10);
if(tiaofen==0)
{
minu0++;
if(minu0==60)
{
minu0=0;
}
while(!tiaofen);
}
}
if(tiaoshi==0)
{
hour0++;
if(hour0==24)
{
hour0=0;
}
while(!tiaoshi);
}
}
}
/*************显示函数****************/
void display(uchar hour,uchar minu,uchar sec)
{
h1=hour/10;
h2=hour%10;
m1=minu/10;
m2=minu%10;
s1=sec/10;
s2=sec%10;
datah=table[h1];
datal=select[7];
disp595();
delay(5);
datah=table[h2];
datal=select[6];
disp595();
delay(5);
datah=0x40;
datal=select[5];
disp595();
delay(5);
datah=table[m1];
datal=select[4];
disp595();
delay(5);
datah=table[m2];
datal=select[3];
disp595();
delay(5);
datah=0x40;
datal=select[2];
disp595();
delay(5);
datah=table[s1];
datal=select[1];
disp595();
delay(5);
datah=table[s2];
datal=select[0];
disp595();
delay(5);
}
/*************disp595()函数****************/
void disp595()
{
for(j=0;j<8;j++)
{
sh_cp=0;
datal<<=1;
ds=CY;
sh_cp=1;//sh_cp上升沿 移位
}
for(j=0;j<8;j++)
{
sh_cp=0;
datah<<=1;
ds=CY;
sh_cp=1;//sh_cp上升沿 移位
}
st_cp=0;
st_cp=1;//st_cp上升沿 存储
}
/*************闹钟函数****************/
void sounde()
{
sounder=~sounder;
}
/*************延时函数****************/
void delay(uchar z)
{
int x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
貌似可以做定时砸蛋滴哦
答:这种最基本的程序随便拿本书或网上一搜都是啊 include <AT89X51.H> sbit K1=P3^0;sbit L1=P1^0;void main(void){ while(1){ if(K1==0) //开关闭合 { L1=0;//灯亮 ---p1.0输出低电平 ,L1有电势差。} else { L1=1;//灯灭 } } } ...
答:j++);}main(){uchar i,key; P2=0xff; while(1) { i=0; P1=table[i]; while(1) { key=P3; if(key!=0)break; } switch(key) { case 0x01:i=1;break; case 0x02:i=2;break; case 0x04:i=3;break; case 0x08:i=4;break; case 0x10:i=5;break; case 0x20:...
答:设置一个按键位置变量,如用012345对应年月日时分秒,对就位置修改对应时间,超过5就循环回0。if(进入修改时间){ switch(按到修改的位置){ case 0: 调用按键扫描,如有修改再调用 更改年份程序,保存 case 1: 调用按键扫描,如有修改再调用 更改月份程序,保存 case 2: 调用按键扫描,如有修改再...
答:这个与兼空与否没太大关系,我的是11.0592MH的时钟,你只需要程序中将定义的通信管脚改一下就可以使用了。很简单。里面可以读取2个DHT11,你随便选一个用就行了。已发送。
答:include<reg52.h> include<define.h> void delay(uint z){ uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);} void didi(){ beep=0;delay(50);beep=1;delay(100);beep=0;delay(50);beep=1;} void write_com(uchar com){ rs=0;lcden=0;P0=com;delay(5);lcden=1;delay...
答:你的89C52集成块电源供电系统抗干扰较差造成,1.加大5V电源输出功率。2.加大5V电源滤波电容。3.加大89C52集成块复位电容,最大可至1uF(此时,集成块上电时有1S左右的复位时间),4,.检查89C52集成块的晶振在线路板上的走线是否太长,并用大面积覆铜与地连接,将此处与其他布线隔离,确保该震荡信号不...
答:AT89C52是没有SCL和SDA的,但可以用32个IO口中的任意两个来模拟。所以楼主的定义方法是可以的。
答:在低功耗操作中,AT89C52提供了两种节能模式:空闲节电模式和掉电模式。在空闲节电模式下,CPU进入休眠状态,但片内所有的外设仍保持激活。这个模式由软件控制,当系统进入空闲状态时,会将片内RAM和特殊功能寄存器的内容暂时冻结。任何允许的中断请求或硬件复位都能结束这种状态。值得注意的是,当从空闲模式...
答:我手工画的八个led是一个共阴数码管的原理图 a b c d e f g 分别是数码管的每一个段,dp是数码管的小数点(这些都称为段选)。他们的阴极连到一块,称为公共端(为什么叫共阴数码管就是这样来的)。数码管显示不同的数字,是通过让数码管的不同段的亮灭组合实现的。比如说要显示0,需要使...
答:单片机驱动一个三极管,三极管驱动一个继电器,继电器常开触点串联风扇接220V,就可以了。还可以是单片机通过光电耦合器驱动双向可控硅,再驱动电扇,这样甚至可以调速。