求一个51单片机的简单数字钟。附上汇编程序或C也行

要求如下按键一:暂停开始键,当按下暂停键后,时钟停止不走,可以对时间进行调整,调好表后,可再按下按键,时钟又开始走。

按键二:功能键,当按下后可选择调时分秒中的一个,当一个处于正修改状态时,数码管会闪烁

按键三:增大键,可以对时分秒进行增大调整。

按键四:减小键,可以对时分秒进行减小调整。

学过几天,我自己编过,但是失败了。看看大牛的吧,没有按键功能,只能走动,我的单片机坏了,忘记怎么加监听器了:
---------------------------------------------------------------------------------------------------------------------
/*时钟程序,大家是否想到用定时器,对,也可用定时器的中断来处理,这样的程序我想不用我说了吧!
你们可自己发辉下,本程序采用外元件DS1302时钟IC,使用此IC不增加系统资源,要时钟时直接去读取就可以了
本IC跟ADC0831一样以串口方式传送数据,不同的是协议,只要你读懂它的串口协议,就可以用P口来模拟协议进行
,这样更能使你对传送数据协议的了解,在看本程序之前,先看看芯片的串口协议*/

#include <reg51.h>
#include <intrins.h>

sbit SCL2=P1^3; //SCL2定义为P1口的第3位脚,连接DS1302SCL和ADC0831SCL脚
sbit SDA2=P1^4; //SDA2定义为P1口的第4位脚,连接DS1302SCL和ADC0831SDA脚
//sbit CS2=P1^6; //CS2定义为P1口的第4位脚,连接ADC0831CS脚
sbit RST = P1^5; // DS1302片选脚

unsigned char l_tmpdate[8]={0x00,0x06,0x03,0x18,0x0c,0x07,0x06,0};
unsigned char l_tmpdisplay[8]={0x40,0x40,0x40,0x40,0x40,0x40,0x40,0};
code unsigned char write_rtc_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //地址为:秒分小时月日年
code unsigned char read_rtc_address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};

code unsigned char table[]=
{0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f,
0x40,0x00};
//共阴数码管 0-9 '-' '熄灭‘表

void delay();//延时子函数,5个空指令
void display(unsigned char *lp,unsigned char lc);//数字的显示函数;lp为指向数组的地址,lc为显示的个数

void Write_Ds1302_byte(unsigned char temp);
void Write_Ds1302( unsigned char address,unsigned char dat );
unsigned char Read_Ds1302 ( unsigned char address );

void Read_RTC(void);//read RTC
void Set_RTC(void);//set RTC

void main(void) //入口函数
{
Set_RTC();
while(1){
Read_RTC();
switch (l_tmpdate[0]/5) //设计每个5秒 交替显示 年月日 时分秒
{
case 0:
case 2:
case 4:
case 6:
case 8:
case 10:
l_tmpdisplay[0]=l_tmpdate[2]/16; //数据的转换,因我们采用数码管0~9的显示,将数据分开
l_tmpdisplay[1]=l_tmpdate[2]&0x0f;
l_tmpdisplay[2]=10; //加入"-"
l_tmpdisplay[3]=l_tmpdate[1]/16;
l_tmpdisplay[4]=l_tmpdate[1]&0x0f;
l_tmpdisplay[5]=10;
l_tmpdisplay[6]=l_tmpdate[0]/16;
l_tmpdisplay[7]=l_tmpdate[0]&0x0f;
break;
case 1:
case 3:
case 5:
case 7:
case 9:
case 11:
l_tmpdisplay[0]=l_tmpdate[6]/16;
l_tmpdisplay[1]=l_tmpdate[6]&0x0f;
l_tmpdisplay[2]=10;
l_tmpdisplay[3]=l_tmpdate[4]/16;
l_tmpdisplay[4]=l_tmpdate[4]&0x0f;
l_tmpdisplay[5]=10;
l_tmpdisplay[6]=l_tmpdate[3]/16;
l_tmpdisplay[7]=l_tmpdate[3]&0x0f;
break;
default:
break;
}
display(l_tmpdisplay,8);
}
}

void display(unsigned char *lp,unsigned char lc)//显示
{
unsigned char i; //定义变量
P2=0; //端口2为输出
P1=P1&0xF8; //将P1口的前3位输出0,对应138译门输入脚,全0为第一位数码管
for(i=0;i<lc;i++){ //循环显示
P2=table[lp[i]]; //查表法得到要显示数字的数码段
delay(); //延时
P2=0; //清0端口,准备显示下位
if(i==7) //检测显示完8位否,完成直接退出,不让P1口再加1,否则进位影响到第四位数据
break;
P1++; //下一位数码管
}
}
void delay(void) //空5个指令
{
unsigned char i=10;
while(i)
i--;
}
void Write_Ds1302_Byte(unsigned char temp)
{
unsigned char i;
for (i=0;i<8;i++) //循环8次 写入数据
{
SCL2=0;
SDA2=temp&0x01; //每次传输低字节
temp>>=1; //右移一位
SCL2=1;
}
}

/****************************************************************************/
void Write_Ds1302( unsigned char address,unsigned char dat )
{
RST=0;
_nop_();
SCL2=0;
_nop_();
RST=1;
_nop_(); //启动
Write_Ds1302_Byte(address); //发送地址
Write_Ds1302_Byte(dat); //发送数据
RST=0; //恢复
}
/****************************************************************************/
unsigned char Read_Ds1302 ( unsigned char address )
{
unsigned char i,temp=0x00;
RST=0;
_nop_();
SCL2=0;
_nop_();
RST=1;
_nop_();
Write_Ds1302_Byte(address);
for (i=0;i<8;i++) //循环8次 读取数据
{
if(SDA2)
temp|=0x80; //每次传输低字节
SCL2=0;
temp>>=1; //右移一位
SCL2=1;
}
RST=0;
_nop_(); //以下为DS1302复位的稳定时间
RST=0;
SCL2=0;
_nop_();
SCL2=1;
_nop_();
SDA2=0;
_nop_();
SDA2=1;
_nop_();
return (temp); //返回
}
/****************************************************************************/
void Read_RTC(void) //读取 日历
{
unsigned char i,*p;
p=read_rtc_address; //地址传递
for(i=0;i<7;i++) //分7次读取 年月日时分秒星期
{
l_tmpdate[i]=Read_Ds1302(*p);
p++;
}
}
/***********************************************************************/
void Set_RTC(void) //设定 日历
{
unsigned char i,*p,tmp;
for(i=0;i<7;i++){
tmp=l_tmpdate[i]/10;
l_tmpdate[i]=l_tmpdate[i]%10;
l_tmpdate[i]=l_tmpdate[i]+tmp*16;
}
Write_Ds1302(0x8E,0X00);

p=write_rtc_address; //传地址
for(i=0;i<7;i++) //7次写入 年月日时分秒星期
{
Write_Ds1302(*p,l_tmpdate[i]);
p++;
}
Write_Ds1302(0x8E,0x80);
}
温馨提示:内容为网友见解,仅供参考
第1个回答  2014-11-13
当小姑娘们长大成人
不该实现选择痛苦的美好目标,
如果你一心要爱我,那就别为了么,
它窥视充满空缺的巢穴
而亚历山大的人,像平常一样,
你是秋收金黄遍的哈哈本回答被提问者采纳
第2个回答  2012-03-06
是用简单的单片机定时器还是要加时钟芯片啊。追问

就是用51单片机,用三极管驱动6个共阳数码管。用三个按钮可以调节时分秒的时间。12小时制或24的也行,想再用一个按键,加一个DS18B20温度传感器。按一下,测下室温。给个程序。加个简易示意图

追答

这样的话二楼的就是1302的了啊,你再加个18b20就Ok啦。空间Q联系,具体聊

第3个回答  2012-03-09
给邮箱
相似回答