51单片机学习2——DS1302制作简易数码管电子时钟

目录

一、硬件电路

二、DS1302

1.DS1302概述

2.ds1302控制寄存器

 3.DS1302时序图

(1)读字节程序:

(2)写字节程序

(3)初始化程序

(4)转换时间程序

 三、数码管

 四、主程序


一、硬件电路

 

二、DS1302

1.DS1302概述

        DS1302 是 DALLAS 公司推出的涓流充电时钟芯片,内含有一个实时时钟/日 历和 31 字节静态 RAM,通过简单的串行接口与单片机进行通信。实时时钟/日 历电路提供秒、分、时、日、周、月、年的信息,每月的天数和闰年的天数可自 动调整。时钟操作可通过 AM/PM 指示,DS1302 与 单片机之间能简单地采用同步串行的方式进行通信,简易三线SPI通信模式:①RES 复位②I/O 数据线③SCLK 串行时钟。

1,VCC2:主电源引脚

2,X1、X2:DS1302 外部晶振引脚,通常需外接 32.768K 晶振

3,GND:电源地

4,CE:使能引脚,也是复位引脚(新版本功能变)。

5,I/O:串行数据引脚,数据输出或者输入都从这个引脚

6,SCLK:串行时钟引脚

7,VCC1:备用电源

2.ds1302控制寄存器

        用于存放控制DS1302命令,可以控制该寄存器以控制选择读或写等操作。

        

1.第7位,固定为1

2.第6位,1为寻址内部存储器地址RAM,0为寻址内部寄存器,即年月日所在存储器,一般设置为0

3.第5到1位,第6位存储器的地址

4.第0位,1位读操作,0为写操作

        具体由下图所示。

  

 3.DS1302时序图

                CE:复位时序

                SCLK:时钟时序

                IO:数据传输时序

                注:DS1302与DS18B20都是从低位到高位传输(读/写)数据,编程时要注意。

(1)读字节程序:

/*读字节*/
u8 ds1302_read_byte(u8 addr) //addr含义:用户需要从某个寄存器里读取数据,addr即为这个寄存器的地址
{
	u8 i=0,t=0,dat=0,x=0;
	CE=0;
	_nop_();
	SCLK=0;
	_nop_();
	CE=1;
	for(i=0;i<8;i++)
	{
		t=addr<<7;
		IO=t>>7;
		SCLK=1;
		_nop_();
		SCLK=0;
		_nop_();
		addr>>=1;			 	
	}
	for(i=0;i<8;i++)
	{
		SCLK=1;
		_nop_();
		dat>>=1;
		x=IO;	
		SCLK=0;
		_nop_();
		dat=dat|(x<<7);
	
	}
	CE=0;
	_nop_();
//以下代码的含义:因为作者所使用的单片机IO口没有上拉电阻,需要人为上拉电平。
	IO=0;
	_nop_();
	IO=1;
	_nop_();
	return dat;
}

(2)写字节程序

/*写字节*/
void ds1302_write_byte(u8 addr,u8 dat)//dat含义:要写入的数据
{                                     //addr含义:用户需要把数据写到某个寄存器,addr为这个寄存器的地址
	u8 i=0,t=0;
	CE=0;
	_nop_();
	SCLK=0;	   
	_nop_();
	CE=1;
	_nop_();
	for(i=0;i<8;i++)
	{
		t=addr<<7;
		IO=t>>7;
		SCLK=1;
		_nop_();
		SCLK=0;
		_nop_();
		addr>>=1;		 	
	}
		for(i=0;i<8;i++)
	{
		t=dat<<7;
		IO=t>>7;
		SCLK=1;
		_nop_();
		SCLK=0;
		_nop_();
		dat>>=1;		 	
	}
	CE=0;
}

(3)初始化程序

/*本函数用于设定初始时间,比如13:30:59*/
void ds1302_init(void)
{
	u8 i=0;
	ds1302_write_byte(0x8e,0x00);
	for(i=0;i<7;i++)//写入初始时间
	{
		ds1302_write_byte(gWRITE_RTC_ARRD[i],gDS1302_TIME[i]);		
	}
	ds1302_write_byte(0x8e,0x80);
}
gWRITE_RTC_ARRD[]为读寄存器的地址

(4)转换时间程序

void ds1302_read_time(void)
{
	u8 i=0;
	for(i=0;i<7;i++)
	{
		gDS1302_TIME[i]=ds1302_read_byte(gREAD_RTC_ARRD[i]);		
	}

}
//gDS1302_TIME[]为时间对应BCD码
//gREAD_RTC_ARRD[]为读寄存器的地址

 三、数码管

void smg_display(u8 dat[],u8 pos)//dat数组元素是数字对应16进制数
{                                //pos是从第几个数码管开始亮
	u8 i=0;
	u8 pos_temp=pos-1;
	for(i=pos_temp;i<8;i++)
	{
	   	switch(i)//位选
		{
			case 0: LSC=1;LSB=1;LSA=1;break;
			case 1: LSC=1;LSB=1;LSA=0;break;
			case 2: LSC=1;LSB=0;LSA=1;break;
			case 3: LSC=1;LSB=0;LSA=0;break;
			case 4: LSC=0;LSB=1;LSA=1;break;
			case 5: LSC=0;LSB=1;LSA=0;break;
			case 6: LSC=0;LSB=0;LSA=1;break;
			case 7: LSC=0;LSB=0;LSA=0;break;
		}
		SMG_A_DP_PORT=dat[i-pos_temp];
		delay_10us(100);
		SMG_A_DP_PORT=0x00;
	}
}

 四、主程序

void main()
{
	u8 num[8];
	ds1302_init();
	while(1)
	{
	 	ds1302_read_time();

		
		num[0]=gsmg_code[gDS1302_TIME[2]/16];
		num[1]=gsmg_code[gDS1302_TIME[2]%16];
		num[2]=0x40;
		num[3]=gsmg_code[gDS1302_TIME[1]/16];
		num[4]=gsmg_code[gDS1302_TIME[1]%16];
		num[5]=0x40;
		num[6]=gsmg_code[gDS1302_TIME[0]/16];
		num[7]=gsmg_code[gDS1302_TIME[0]%16];
		smg_display(num,1);
	}
		
}

       

 

 

  • 9
    点赞
  • 86
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 以下是用51单片机DS1302控制4位共阴极数码管显示时钟的代码: ``` #include <reg51.h> #include <intrins.h> sbit SCLK = P3^7; // DS1302 SCLK sbit IO = P3^6; // DS1302 IO sbit RST = P3^5; // DS1302 RST unsigned char code table[]={ // 数码管码表 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; void delay(unsigned int t) { while(t--); } void Write_Ds1302(unsigned char address,unsigned char dat) { unsigned char i; RST = 0; delay(10); RST = 1; delay(10); SCLK = 0; IO = 0; delay(10); SCLK = 1; delay(10); SCLK = 0; delay(10); IO = 1; delay(10); SCLK = 1; delay(10); SCLK = 0; delay(10); IO = 0; delay(10); SCLK = 1; delay(10); SCLK = 0; delay(10); IO = 1; delay(10); SCLK = 1; delay(10); SCLK = 0; for(i=0;i<8;i++) { IO=address&0x01; address=address>>1; SCLK=1; delay(10); SCLK=0; delay(10); } for(i=0;i<8;i++) { IO=dat&0x01; dat=dat>>1; SCLK=1; delay(10); SCLK=0; delay(10); } RST = 1; } unsigned char Read_Ds1302(unsigned char address) { unsigned char i,dat=0; RST=0; delay(10); RST=1; delay(10); SCLK=0; IO=0; delay(10); SCLK=1; delay(10); SCLK=0; delay(10); IO=1; delay(10); SCLK=1; delay(10); SCLK=0; delay(10); IO=0; ### 回答2: 51单片机DS1302时钟代码 使用51单片机DS1302实现4位共阴极数码管时钟的代码如下: #include<reg51.h> #define uchar unsigned char #define uint unsigned int sbit DSPORT=P2^3; //定义DS1302时钟引脚 uchar code table[]={ 0x3f,0x06,0x5b,0x4f, //数码管0-3 0x66,0x6d,0x7d,0x07, //数码管4-7 0x7f,0x6f,0x77,0x7c, //数码管8-11 0x39,0x5e,0x79,0x71 //数码管12-15 }; //DS1302通信函数 void Ds1302Write(uchar dat) { uchar i; for(i=0;i<8;i++) //发送8位数据 { DSPORT=0; //使能信号 DSPORT=dat&0x01; //发送数据 dat>>=1; DSPORT=1; //停止发送 } } //DS1302读取函数 uchar Ds1302Read() { uchar i,dat=0x00; for(i=0;i<8;i++) //读取8位数据 { DSPORT=0; //使能信号 dat>>=1; //右移一位 if(DSPORT) //读取数据 dat|=0x80; DSPORT=1; //停止读取 } return dat; } //DS1302时钟配置函数 void Ds1302Init() { Ds1302Write(0x8e); //写入控制字节,使能时钟 Ds1302Write(0x00); //关闭写保护 Ds1302Write(0x80); //时钟暂停,准备写入时间 Ds1302Write(0x00); //秒,写0表示启动时钟 Ds1302Write(0x00); //分钟 Ds1302Write(0x00); //小时 Ds1302Write(0x01); //日期 Ds1302Write(0x01); //月份(1-12) Ds1302Write(0x21); //星期(1-7,1表示星期日) Ds1302Write(0x20); //年(00-99) Ds1302Write(0x80); //结束写入,启动时钟 } //主函数 void main() { uchar sec,min,hour,day,mon,week,year; Ds1302Init(); //时钟初始化 while(1) { Ds1302Write(0x81); //读取秒 sec=Ds1302read(); Ds1302Write(0x83); //读取分钟 min=Ds1302read(); Ds1302Write(0x85); //读取小时 hour=Ds1302Read(); Ds1302Write(0x87); //读取日期 day=Ds1302Read(); Ds1302Write(0x89); //读取月份 mon=Ds1302Read(); Ds1302Write(0x8b); //读取星期 week=Ds1302Read(); Ds1302Write(0x8d); //读取年份 year=Ds1302Read(); //数码管显示 P0=table[sec%10]; //个位秒 P1=0xfe; //选择第1位数码管 P1=0xff; //关闭显示 P0=table[sec/10]; //十位秒 P1=0xfd; //选择第2位数码管 P1=0xff; //关闭显示 P0=table[min%10]; //个位分钟 P1=0xfb; //选择第3位数码管 P1=0xff; //关闭显示 P0=table[min/10]; //十位分钟 P1=0xf7; //选择第4位数码管 P1=0xff; //关闭显示 } } 上述代码使用了51单片机DS1302实现了对秒、分、时、日期、星期、年的读取。通过数码管显示即时时钟。可以通过修改代码来实现其他功能。 ### 回答3: 51单片机是一种常用的微控制器,可以用来实现各种功能,其中包括显示时钟。而DS1302是一款实时时钟芯片,具有高精度和低功耗的特点,可以提供准确的时间信息。 以下是使用51单片机DS1302显示4位共阴极数码管时钟代码的详细实现步骤: 1. 首先,需要连接好51单片机DS1302,并将4位共阴极数码管连接到51单片机的输出引脚上。 2. 在程序中,需要引入相关头文件,以便后续使用相关函数和变量。 3. 初始化DS1302的设置,包括设置时钟、日期、开始运行等。 4. 在主程序中,需要设置时钟的显示起始位置。 5. 通过DS1302获取当前的小时和分钟信息,并将其转换为BCD码。 6. 将转换后的BCD码通过相应的位选和段选转换为4位共阴极数码管所需的电平。 7. 循环执行以上步骤,实现实时更新时钟的显示。 完成以上步骤后,代码就能够实现通过DS1302显示4位共阴极数码管时钟。当每秒钟更新一次时,数码管上的数据也会实时更新,显示当前的小时和分钟。代码的具体实现细节可根据使用的具体开发环境和硬件电路进行相应调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值