一生有你llx 阅读(152) 评论(0)
1、原理图

2、源代码
/***************************************************
*   *
*    Project: clock   *
* Author:  DDDDD   *
* QQ:  78080458   *
* Q-Group: 150633458     *
* Date:    2014-3-30   *
*       *
***************************************************/


#include <reg51.h>


unsigned int second = 0;   //全局变量  小时、分钟、秒
unsigned int minute = 0;
unsigned int hour = 0;


sbit DU = P2^0;    //数码管段选74HC573开关
sbit WE = P2^1; //数码管位选74HC573开关
sbit RUN = P3^0; //开始暂停
sbit RESET = P3^1;   //复位


sbit CS288 = P2^2;
sbit DS1302=P2^7; //HJ-C52主板 时钟复位 关掉DS1302 以免影响其他IO口实验。
sbit LCD1602=P2^5;//HJ-C52主板 LCD1602复位 关掉LCD1602显示 以免影响其他IO口实验。


unsigned char SEG_CC[10] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};


int count = 0;
long int cc = 0;
unsigned int run_c = 0;   //控制暂停,奇数暂停,偶数开始


void timer_init();
void display(unsigned int num, unsigned int shi, unsigned int ge);
void sec_to_time(unsigned int num);
void delay_us();
void delay_ms();


void main()
{
LCD1602=0; //关掉LCD1602 以免影响点阵管IO口电评
DS1302=0; //关掉DS1302 以免影响点阵管IO口电评
CS288 = 0;  //关掉点阵
P3 = 0xff;  //设置P3口为输入口
timer_init();


while(1)
{
sec_to_time(cc);
display(second, 0xbf, 0x7f);
display(minute, 0xf7, 0xef);
display(hour, 0xfe, 0xfd);
if(!RUN) //按下暂停键
{
delay_ms(); //延时消除抖动
if(!RUN)
{
run_c++; //记录按下的次数
if(run_c%2 == 1)
TR1 = 0; //奇数暂停
else
TR1 = 1; //偶数开始
}
}
if(!RESET)   //按下复位键
{
delay_ms();   //延时消除抖动
if(!RESET)
{
TR1 = 0;
cc = 0;
count = 0;
TR1 = 1;
}
}
}
}
/***********************************************
定时器初始化函数,定时100us,使用定时器1
***********************************************/
void timer_init()
{
EA = 0;  //关闭中断
TMOD = 0x20;  //使用定时器 1,工作方式 2,门控 TR1
TH1 = 0xA4;
TL1 = 0xA4;   //T1 = 163,  100us后溢出,产生中断
ET1 = 1;  //开启总中断
EA = 1;
TR1 = 1;  //开启定时器 1
}
/*********************************************
定时器1中断处理函数, 定时器 1 是第 3号中断
100us来一次中断, count++, 1s之后清零count
********************************************/
void timer1_int() interrupt 3
{
count++;     //每次中断count 加1
if(count == 10000)
{
cc++;
count = 0; //count= 10000时经历了10000*100us=1s,此时清零count
}
}


/**********************************************
数码管显示函数,可以显示一个四位数
数码管段选abcdefgh由P0来控制,也就是说P0将要
据顶数码管显示几
数码管位选开关也由P0来控制,那么要决定让哪个
数码管显示,也有P0来决定了
DU=1时,P0的数据被传送到74HC573-1,DU=0时,数据仍然
在74HC573-1锁存,此时P0变化时,74HC573-1的输出端口不
在变化
WE=1时,P0的数据被传送到74HC573-2,WE=0时,数据仍然
在74HC573-2锁存,而74HC573-1内的数据没有变化。此时
P0变化时,74HC573-2的输出端口不在变化
上述操作完成之后,要显示的数据锁存在 74HC573-1内,
要让哪一位数码管显示锁存在74HC573-2
**********************************************/
void display(unsigned int num, unsigned int shi, unsigned int ge)
{
//显示个位数
DU = 0;
WE = 0;
P0 = SEG_CC[num%1000%100%10];
DU = 1;     //段选74hc573输出使能
DU = 0;      //段选74hc573锁存使能,将P0输出的数据保存


WE = 0;
P0 = ge;   //关闭所有数码管
WE = 1;     //位选 74hc573 输出使能
WE = 0;     //位选74hc573 锁存使能  
delay_us();


/**********************************************/
//显示十位数
/**********************************************/
DU = 0;
P0 = SEG_CC[(num%1000%100)/10];
DU = 1;     //段选74hc573输出使能
DU = 0;      //段选74hc573锁存使能,将P0输出的数据保存

P0 = shi; //关闭所有数码管
WE = 1;     //位选 74hc573 输出使能
WE = 0;     //位选74hc573 锁存使能
delay_us();
}


void sec_to_time(unsigned int num)
{
hour = num/3600;
minute = (num%3600)/60;
second = num%3600%60;
}


void delay_us()
{
unsigned int i;
for(i = 0; i < 50; i++);
}


void delay_ms()
{
unsigned int i;
for(i = 0; i < 2500; i++);
}

3、实物图