이 프로젝트에서는 8051 마이크로 컨트롤러를 사용하여 RTC 클럭을 만드는 방법을 시연 할 것 입니다. 아두 이노로이 프로젝트를하고 싶다면 아두 이노를 사용하여이 디지털 시계를 확인하세요. 이 프로젝트의 주요 구성 요소는 실시간 디지털 클록 IC 인 DS1307입니다. 이 IC에 대해 자세히 알려드립니다.
RTC DS1307:
DS1307 직렬 실시간 클록 (RTC)은 저전력, 완전 이진 코드 십진 (BCD) 클록 / 캘린더와 56 바이트의 NV SRAM입니다. 이 칩은 I²C 프로토콜에서 작동합니다. 시계 / 달력은 초, 분, 시간, 일, 날짜, 월 및 연도 정보를 제공합니다. 월말 날짜는 윤년 수정을 포함하여 31 일 미만의 달로 자동 조정됩니다. 시계는 AM / PM 표시기가있는 24 시간 또는 12 시간 형식으로 작동합니다. DS1307에는 정전을 감지하고 자동으로 백업 전원으로 전환하는 내장형 전력 감지 회로가 있습니다. 부품이 백업 공급 장치에서 작동하는 동안 시간 유지 작업이 계속됩니다. DS1307 칩은 10 년까지 지속적으로 실행할 수 있습니다.
8051 기반 실시간 시계 는 I2C 프로토콜에서 작동 하는 RTC DS1307을 사용하여 실시간으로 표시하는 디지털 시계 입니다. 실시간 시계는 정전 후에도 작동한다는 것을 의미합니다. 전원이 다시 연결되면 꺼진 시간과 지속 시간에 관계없이 실시간으로 표시됩니다. 이 프로젝트에서는 16x2 LCD 모듈을 사용하여 시간을-(시, 분, 초, 날짜, 월 및 연도) 형식으로 표시했습니다. 실시간 시계는 일반적으로 컴퓨터, 주택, 사무실 및 전자 장치에서 실시간으로 업데이트되는 데 사용됩니다.
I2C 프로토콜은 두 개의 와이어를 사용하여 두 개 이상의 장치를 단일 시스템에 연결하는 방법이므로이 프로토콜을 두 개의 와이어 프로토콜 이라고도 합니다. 단일 장치 또는 프로세서에 127 개의 장치를 통신하는 데 사용할 수 있습니다. 대부분의 I2C 장치는 100Khz 주파수에서 실행됩니다.
데이터 쓰기 마스터에서 슬레이브 (슬레이브 수신 모드)에 대한 단계
- START 조건을 슬레이브로 보냅니다.
- 슬레이브 주소를 슬레이브로 보냅니다.
- 쓰기 비트 (0)를 슬레이브로 보냅니다.
- 슬레이브로부터 수신 된 ACK 비트
- 단어 주소를 슬레이브로 보냅니다.
- 슬레이브로부터 수신 된 ACK 비트
- 데이터를 슬레이브로 보냅니다.
- 슬레이브로부터 ACK 비트를 받았습니다.
- 마지막으로 슬레이브에게 STOP 조건을 보냅니다.
슬레이브에서 마스터로 데이터 읽기 단계 (슬레이브 전송 모드)
- START 조건을 슬레이브로 보냅니다.
- 슬레이브 주소를 슬레이브로 보냅니다.
- 읽기 비트 (1)를 슬레이브로 보냅니다.
- 슬레이브로부터 수신 된 ACK 비트
- 슬레이브로부터 데이터 수신
- 슬레이브로부터 ACK 비트를 받았습니다.
- STOP 조건을 슬레이브로 보냅니다.
회로도 및 설명
회로에서 우리는 DS1307, AT89S52 및 LCD 3 개의 대부분의 구성 요소를 사용했습니다. 여기서 AT89S52는 DS1307에서 시간을 읽고 16x2 LCD 화면에 표시하는 데 사용됩니다. DS1307은 2 개의 라인을 사용하여 시간 / 날짜를 마이크로 컨트롤러에 보냅니다.
회로 연결은 이해하기 쉽고 위의 다이어그램에 나와 있습니다. DS1307 칩 핀 SDA 및 SCL은 89S52 마이크로 컨트롤러의 P2.1 및 P2.0 핀에 연결되며 데이터 및 클록 라인에서 기본값 HIGH를 유지하는 풀업 저항이 있습니다. 32.768KHz 수정 발진기는 DS1307chip과 연결되어 정확한 1 초 지연을 생성합니다. 그리고, 3 볼트의 전지의 3 핀으로 연결되어 RD 정전 후에 실행 시간을 유지 (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 버튼을 이용하여 시간을 설정해야하며 다음 버튼을 사용하여 자리 이동합니다. 시간 설정 후 시계가 계속 실행됩니다.
프로그램 설명
코드에는 8051 패밀리 라이브러리와 표준 입력 출력 라이브러리가 포함되어 있습니다. 그리고 우리가 사용한 핀을 정의하고 계산을 위해 몇 가지 변수를 사용했습니다.
#포함
그리고 주어진 기능은 LCD 구동에 사용됩니다.
무효 daten () {rs = 1; en = 1; 지연 (1); en = 0; } void lcddata (unsigned char ch) {lcdport = ch & 0xf0; daten (); lcdport = (ch << 4) & 0xf0; daten (); } void cmden (void) {rs = 0; en = 1; 지연 (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)); 시간 = BCDToDecimal (I2CRead (1)); day1 = BCDToDecimal (I2CRead (1)); date = BCDToDecimal (I2CRead (1)); mon = BCDToDecimal (I2CRead (1)); year = BCDToDecimal (I2CRead (1)); I2CStop (); show_time (); // 시간 / 날짜 / 일 표시 delay (1);
이 함수는 십진수를 BCD로, BCD를 십진수로 변환하는 데 사용됩니다.
int BCDToDecimal (char bcdByte) {char a, b, dec; a = (((bcdByte & 0xF0) >> 4) * 10); b = (bcdByte & 0x0F); dec = a + b; return dec; } char DecimalToBCD (int decimalByte) {char a, b, bcd; a = ((decimalByte / 10) << 4); b = (decimalByte % 10); bcd = ab; 반환 bcd; }
아래의 기능은 I2C 통신에 사용됩니다.
void I2CStart () {SDA = 1; SCL = 1, SDA = 0, SCL = 0;} // ds1307 RTC와 통신하기위한 "start"함수 void I2CStop () {SDA = 0, SCL = 1, SDA = 1; } // ds1307과 통신하기위한 "중지"기능 RTC unsigned char I2CSend (unsigned char Data) // ds1307에 데이터 보내기 {char i; char ack_bit; for (i = 0; i <8; i ++) {if (데이터 & 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 ++) {데이터 << = 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 ("날짜:"); sprintf (var, "% d", 날짜); lcdprint (var); sprintf (var, "/ % d", mon); lcdprint (var); sprintf (var, "/ % d", 연도 +2000); lcdprint (var); lcdprint (""); lcdcmd (0xc0); lcdprint ("시간:"); sprintf (var, "% d", 시간); lcdprint (var); sprintf (var, ": % d", min); lcdprint (var); sprintf (var, ": % d", 초); lcdprint (var); lcdprint (""); // 일 (일 1); lcdprint (""); }