求一个简单的单片机时钟程序
最好能带上电路图,大一新生自改程序的能力太弱,只能跟着程序焊接。 展开
#include<reg51.h>
#define uchar unsigned char
uchar code ledtab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//0-9
unsigned char sec=0,min=0,hour=0,scanled;
unsigned char key,time;
unsigned char disdat[6];
sbit K=P1^0;
void dischg()
{
disdat[0]=sec%10;
disdat[1]=sec/10;
disdat[2]=min%10;
disdat[3]=min/10;
disdat[4]=hour%10;
disdat[5]=hour/10;
}
void t0isr() interrupt 1 //秒计时
{
TR0=0;
TH0=0x3c;
TL0=0xb0;
TR0=1;
time++;
if(time==20)
{
time=0;
sec++;
if(sec>59)
{
sec=0;
min++;
if(min>59)
{
min=0;
hour++;
if(hour>23)hour=0;
}
}
}
dischg();
}
void t1isr() interrupt 3 //显示
{
TH1=0xec;
TL1=0x78;
switch(scanled)
{
case 0:
P2=0x01;
P0=~ledtab[disdat[5]];
break;
case 1:
P2=0x02;
P0=~ledtab[disdat[4]]&0x7f;
break;
case 2:
P2=0x04;
P0=~ledtab[disdat[3]];
break;
case 3:
P2=0x08;
P0=~ledtab[disdat[2]]&0x7f;
break;
case 4:
P2=0x10;
P0=~ledtab[disdat[1]];
break;
case 5:
P2=0x20;
P0=~ledtab[disdat[0]];
break;
default:break;
}
scanled++;
scanled%=6;
}
main()
{
TMOD=0x11;
TH0=0x3c;
TL0=0xb0;
TH1=0xec;
TL1=0x78;
EA=1;
TR1=1;
ET0=1;
ET1=1;
sec=0;
min=0;
hour=0;
scanled=0;
time=0;
key=0;
dischg();
while(1)
{
if(K==0)
{
while(K==0);
key++;
key%=2;
}
switch(key)
{
case 0:
TR0=1;
break;
case 1:
TR0=0;
break;
}
}
}
你可以把电路也给我吗?
2018-11-13 · 知道合伙人互联网行家
#include <intrins.h>
unsigned char data dis_digit;
unsigned char key_s, key_v;
unsigned char code dis_code[11]={ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0xff};//0,1,2,3,4,5,6,7,8,9,关显示,数码管码表
unsigned char data dis_buf[8];
unsigned char data dis_index;
unsigned char hour,min,sec;
unsigned char sec100;
sbitK1 = P3^6;
sbitK2 = P3^7;
bit scan_key();
void proc_key();
void inc_sec();
void inc_min();
void inc_hour();
void display();
void delayms(unsigned char ms);
char code SST516[3] _at_ 0x003b;
void main(void)
{
P0 = 0xff;
P2 = 0xff;
TMOD = 0x11;// 定时器0, 1工作模式1, 16位定时方式
TH1 = 0xdc;
TL1 = 0;
TH0 = 0xFC;
TL0 = 0x17;
hour = 12;
min = 00;
sec = 00;
sec100 = 0;
dis_buf[0] = dis_code[hour / 10];// 时十位
dis_buf[1] = dis_code[hour % 10];// 时个位
dis_buf[3] = dis_code[min / 10];// 分十位
dis_buf[4] = dis_code[min % 10];// 分个位
dis_buf[6] = dis_code[sec / 10];// 秒十位
dis_buf[7] = dis_code[sec % 10];// 秒个位
dis_buf[2] = 0xf7;// 显示"-"
dis_buf[5] = 0xf7;// 显示"-"
dis_digit = 0xfe;
dis_index = 0;
TCON = 0x01;
IE = 0x8a;// 使能timer0,1 中断
TR0 = 1;
TR1 = 1;
key_v = 0x03;
while(1)
{
if(scan_key())
{
delayms(10);
if(scan_key())
{
key_v = key_s;
proc_key();
}
}
}
}
bit scan_key()
{
key_s = 0x00;
key_s |= K2;
key_s <<= 1;
key_s |= K1;
return(key_s ^ key_v);
}
void proc_key()
{
EA = 0;
if((key_v & 0x01) == 0)// K1
{
inc_hour();
}
else if((key_v & 0x02) == 0)// K2
{
min++;
if(min > 59)
{
min = 0;
}
dis_buf[3] = dis_code[min / 10];// 分十位
dis_buf[4] = dis_code[min % 10];// 分个位
}
EA = 1;
}
void timer0() interrupt 1
// 定时器0中断服务程序, 用于数码管的动态扫描
// dis_index --- 显示索引, 用于标识当前显示的数码管和缓冲区的偏移量
// dis_digit --- 位选通值, 传送到P2口用于选通当前数码管的数值, 如等于0xfe时,
//选通P2.0口数码管
// dis_buf --- 显于缓冲区基地址
{
TH0 = 0xFC;
TL0 = 0x17;
P2 = 0xff;// 先关闭所有数码管
P0 = dis_buf[dis_index];// 显示代码传送到P0口
P2 = dis_digit;//
dis_digit = _crol_(dis_digit,1);// 位选通值左移, 下次中断时选通下一位数码管
dis_index++;//
dis_index &= 0x07;// 8个数码管全部扫描完一遍之后,再回到第一个开始下一次扫描
}
void timer1() interrupt 3
{
TH1 = 0xdc;
sec100++;
if(sec100 >= 100)
{
sec100 = 0;
inc_sec();
}
}
void inc_sec()
{
sec++;
if(sec > 59)
{
sec = 0;
inc_min();
}
dis_buf[6] = dis_code[sec / 10];// 秒十位
dis_buf[7] = dis_code[sec % 10];// 秒个位
}
void inc_min()
{
min++;
if(min > 59)
{
min = 0;
inc_hour();
}
dis_buf[3] = dis_code[min / 10];// 分十位
dis_buf[4] = dis_code[min % 10];// 分个位
}
void inc_hour()
{
hour++;
if(hour > 23)
{
hour = 0;
}
if(hour > 9)
dis_buf[0] = dis_code[hour / 10];// 时十位
else
dis_buf[0] = 0xff;// 当小时的十位为0时不显示
dis_buf[1] = dis_code[hour % 10];// 时个位
}
void delayms(unsigned char ms)
// 延时子程序
{
unsigned char i;
while(ms--)
{
for(i = 0; i < 120; i++);
}
}
* 描述: 简易电子时钟,LED数码管显示,K1---时调整 (p36), K2---分调整 (p37),数码管数据p0,数码管控制p2, 上电时初始化显示: 12-00-00 *
/************************************************/
/**数字电子钟**/
/************************************************/
#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
uint a,b;
uchar hour,minu,sec, //时钟
hour0,minu0,sec0, //秒表
hour1,minu1,sec1;
h1,h2,m1,m2,s1,s2, //显示位
k,s; //状态转换标志
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 main()
{
init();
while(1)
{
while(TR1)
{
keyscan(); // 扫描函数
while(s==1) // s是状态标志,当s=0时,闹钟取消。s=1时,设定闹钟时间
//(也是通过调时,调分函数);
{ //s=2时,闹钟工作,时间与设定时刻一致时,闹钟响
// (一分钟后自动关闭,可手动关闭)。再次切换,s=0.
keyscan(); //s状态切换(0-》1-》2-》0)通过外部中断1实现。
display(hour1,minu1,sec1); //闹钟时刻显示
}
display(hour0,minu0,sec0);//时钟表显示
while(k) /*k是秒表状态(0-》1-》2-》0)通过外部中断0实现。
0秒表关;1秒表从零计时;2秒表停,显示计时时间*/
{
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;
P0=0xff;
P2=table[h1];
P0=select[7];
delay(5);
P0=0xff;
P2=table[h2];
P0=select[6];
delay(5);
P0=0xff;
P2=0x40;;
P0=select[5];
delay(5);
P0=0xff;
P2=table[m1];
P0=select[4];
delay(5);
P0=0xff;
P2=table[m2];
P0=select[3];
delay(5);
P0=0xff;
P2=0x40;
P0=select[2];
delay(5);
P0=0xff;
P2=table[s1];
P0=select[1];
delay(5);
P0=0xff;
P2=table[s2];
P0=select[0];
delay(5);
}
/*************闹钟函数****************/
void sounde()
{
sounder=~sounder;
}
/*************延时函数****************/
void delay(uchar z)
{
int x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}