在本项目中,我们将演示使用8051微控制器制作RTC时钟。如果您想使用Arduino进行此项目,请使用Arduino检查此数字时钟。该项目的主要组件是DS1307,它是一种实时数字时钟IC。让我们详细了解该IC。
RTC DS1307:
DS1307串行实时时钟(RTC)是低功耗,全二进制编码的十进制(BCD)时钟/日历以及56字节的NV SRAM。该芯片可用于I²C协议。时钟/日历提供秒,分钟,小时,日期,日期,月份和年份信息。对于少于31天的月份,将自动调整月末日期,包括leap年的更正。带有AM / PM指示器的时钟以24小时或12小时格式运行。 DS1307具有内置的电源检测电路,可检测到电源故障并自动切换到备用电源。当零件通过备用电源工作时,计时工作将继续进行。 DS1307芯片可以连续运行到10年。
基于8051的实时时钟是使用RTC DS1307实时显示的数字时钟,该 时钟基于I2C协议。实时时钟意味着它即使在断电后也能运行。重新接通电源后,无论处于关闭状态的时间和持续时间,它都会显示实时时间。在此项目中,我们使用了16x2 LCD模块以-(小时,分钟,秒,日期,月份和年份)格式显示时间。实时时钟通常用于我们的计算机,房屋,办公室和电子设备中,以保持实时更新。
I2C协议是一种使用两条线将两个或更多设备连接到单个系统的方法,因此该协议也称为“ 两条线协议”。它可以用于将127个设备通信到单个设备或处理器。大多数I2C设备以100Khz的频率运行。
数据写入主机到从机的步骤(从机接收模式)
- 发送启动条件给从机。
- 发送从站地址到从站。
- 将写位(0)发送到从站。
- 从机接收到ACK位
- 发送地址到奴隶。
- 从机接收到ACK位
- 将数据发送到从站。
- 从机接收到ACK位。
- 最后发送STOP条件给从机。
从站到主机的数据读取步骤(从站发送模式)
- 发送启动条件给从机。
- 发送从站地址到从站。
- 将读取位(1)发送到从站。
- 从机接收到ACK位
- 从站接收数据
- 从机接收到ACK位。
- 发送停止条件给从站。
电路图和说明
在电路中,我们使用了3个大多数组件DS1307,AT89S52和LCD。在这里,AT89S52用于从DS1307读取时间并将其显示在16x2 LCD屏幕上。 DS1307使用2条线将时间/日期发送到微控制器。
电路连接易于理解,如上图所示。 DS1307芯片的SDA和SCL引脚通过上拉电阻连接到89S52微控制器的P2.1和P2.0引脚,该电阻在数据和时钟线上均保持默认值HIGH。 DS1307chip连接了一个32.768KHz晶体振荡器,可产生精确的1秒延迟。和一个3伏电池也被连接至引脚3次(BAT)DS1307的这保持时间断电后运行。 16x2 LCD以4位模式与8051连接。控制引脚RS,RW和En直接连接到89S52的引脚P1.0,GND和P1.1。数据引脚D0-D7连接到89S52的P1.4-P1.7。
三个按钮,即SET,INC / CHANGE和Next用于设置时钟时间至89S52的引脚P2.4,P2.3和P2.2(低电平有效)。当我们按SET键时,时间设置模式被激活,现在我们需要使用INC / CHANGE按钮设置时间,而Next按钮用于移动到数字。设置时间后,时钟将连续运行。
节目说明
在代码中,我们包括8051系列库和一个标准的输入输出库。并定义了我们已经使用过的引脚,并采用了一些变量进行计算。
#包括
给定的功能用于驱动LCD。
无效的daten(){rs = 1; en = 1; delay(1); en = 0; } void lcddata(unsigned char ch){lcdport = ch&0xf0; daten(); lcdport =(ch << 4)&0xf0; daten(); } void cmden(void){rs = 0; en = 1; delay(1); en = 0; } void lcdcmd(unsigned char ch)
此功能用于初始化RTC并从RTC IC读取时间和日期。
I2CStart(); I2CSend(0xD0); I2CSend(0x00); I2CStart(); I2CSend(0xD1); sec = BCDToDecimal(I2CRead(1)); min = BCDToDecimal(I2CRead(1)); hour = BCDToDecimal(I2CRead(1)); day1 = BCDToDecimal(I2CRead(1)); date = BCDToDecimal(I2CRead(1)); mon = BCDToDecimal(I2CRead(1)); year = BCDToDecimal(I2CRead(1)); I2CStop(); 开演时间(); //显示时间/日期/日期延迟(1);
这些函数用于将十进制转换为BCD,将BCD转换为十进制。
int BCDToDecimal(char bcdByte){char a,b,dec; a =((((bcdByte&0xF0)>> 4)* 10); b =(bcdByte&0x0F); dec = a + b; 返回dec; } char DecimalToBCD(int decimalByte){char a,b,bcd; a =((decimalByte / 10)<< 4); b =(十进制字节%10); bcd = ab; 返回bcd; }
以下给定的功能用于I2C通信。
void I2CStart(){SDA = 1; SCL = 1,SDA = 0,SCL = 0;} //用于与ds1307 RTC通信的“启动”函数void I2CStop(){SDA = 0,SCL = 1,SDA = 1; } //“停止”功能,用于与ds1307进行通信RTC无符号字符I2CSend(unsigned char Data)//将数据发送到ds1307 {char i; char ack_bit; for(i = 0; i <8; i ++){if(Data&0x80)SDA = 1; 否则SDA = 0; SCL = 1;数据<< = 1;SCL = 0; } SDA = 1,SCL = 1; ack_bit = SDA; SCL = 0; 返回ack_bit; } unsigned char I2CRead(char ack)//从ds1307接收数据{unsigned char i,Data = 0; SDA = 1;for(i = 0; i <8; i ++){Data << = 1; do {SCL = 1;} while(SCL == 0); if(SDA)数据== 1; SCL = 0; } if(ack)SDA = 0; 否则SDA = 1;SCL = 1;SCL = 0; SDA = 1;返回数据;}
set_time函数用于设置时钟时间,下面的show_time函数用于在LCD上显示时间。
void show_time()//用于在LCD上显示时间/日期/日期的功能{char var; lcdcmd(0x80); lcdprint(“ Date:”); sprintf(var,“%d”,date); lcdprint(var); sprintf(var,“ /%d”,mon); lcdprint(var); sprintf(var,“ /%d”,year + 2000); lcdprint(var); lcdprint(“”); lcdcmd(0xc0); lcdprint(“ Time:”); sprintf(var,“%d”,hour); lcdprint(var); sprintf(var,“:%d”,min); lcdprint(var); sprintf(var,“:%d”,sec); lcdprint(var); lcdprint(“”); // day(day1); lcdprint(“”); }