このプロジェクトでは、8051マイクロコントローラーを使用してRTCクロックを作成する方法を示します。Arduinoでこのプロジェクトを実行したい場合は、Arduinoを使用してこのデジタル時計を確認してください。このプロジェクトの主要コンポーネントは、リアルタイムデジタル時計ICであるDS1307です。このICについて詳しく教えてください。
RTC DS1307:
DS1307シリアルリアルタイムクロック(RTC)は、低電力の完全な2進化10進(BCD)クロック/カレンダーと56バイトのNVSRAMです。このチップはI²Cプロトコルで動作します。時計/カレンダーは、秒、分、時間、日、日付、月、および年の情報を提供します。うるう年の修正を含め、31日未満の月の月末日は自動的に調整されます。時計は、AM / PMインジケーター付きの24時間形式または12時間形式で動作します。 DS1307には、電源障害を検出し、バックアップ電源に自動的に切り替えるパワーセンス回路が組み込まれています。部品がバックアップ電源から動作している間、計時動作は続行されます。 DS1307チップは10年まで継続して実行できます。
8051ベースのリアルタイムクロックは、I2Cプロトコルで動作するRTCDS1307を使用してリアルタイムで表示するデジタル時計 です。リアルタイムクロックとは、停電後も動作することを意味します。電源を再接続すると、オフ状態の時間と期間に関係なく、リアルタイムで表示されます。このプロジェクトでは、16x2 LCDモジュールを使用して、時刻を-(時、分、秒、日付、月、年)形式で表示しました。リアルタイムクロックは、コンピュータ、住宅、オフィス、電子機器で一般的に使用されており、リアルタイムで最新の状態に保つことができます。
I2Cプロトコルは、2本のワイヤーを使用して2つ以上のデバイスを1つのシステムに接続する方法であるため、このプロトコルは2線式プロトコルとも呼ばれ ます。127個のデバイスを単一のデバイスまたはプロセッサに通信するために使用できます。ほとんどのI2Cデバイスは100Khzの周波数で動作します。
マスターからスレーブへのデータ書き込み手順(スレーブ受信モード)
- START条件をスレーブに送信します。
- スレーブアドレスをスレーブに送信します。
- 書き込みビット(0)をスレーブに送信します。
- スレーブからACKビットを受信しました
- ワードアドレスをスレーブに送信します。
- スレーブからACKビットを受信しました
- スレーブにデータを送信します。
- スレーブからACKビットを受信しました。
- そして最後にSTOP条件をスレーブに送信します。
スレーブからマスターへのデータ読み取りの手順(スレーブ送信モード)
- START条件をスレーブに送信します。
- スレーブアドレスをスレーブに送信します。
- 読み取りビット(1)をスレーブに送信します。
- スレーブからACKビットを受信しました
- スレーブからデータを受信しました
- スレーブからACKビットを受信しました。
- STOP条件をスレーブに送信します。
回路図と説明
回路では、DS1307、AT89S52、LCDの3つのほとんどのコンポーネントを使用しました。ここでは、AT89S52を使用してDS1307から時間を読み取り、16x2LCD画面に表示します。 DS1307は、2行を使用して時刻/日付をマイクロコントローラに送信します。
回路接続は理解しやすく、上の図に示されています。 DS1307チップピンSDAおよびSCLは、データおよびクロックラインでデフォルト値HIGHを保持するプルアップ抵抗を備えた89S52マイクロコントローラのP2.1およびP2.0ピンに接続されています。また、32.768KHzの水晶発振器がDS1307チップに接続されており、正確に1秒の遅延を生成します。また、3ボルトのバッテリーはDS1307のピン3rd(BAT)にも接続されており、停電後も時間を維持します。 16x2 LCDは、4ビットモードで8051に接続されています。制御ピンRS、RW、およびEnは、89S52ピンP1.0、GND、およびP1.1に直接接続されています。また、データピンD0〜D7は89S52のP1.4〜P1.7に接続されています。
SET、INC / CHANGE、Nextの3つのボタンを使用して、89S52(アクティブロー)のピンP2.4、P2.3、およびP2.2にクロック時間を設定します。SETを押すと、時間設定モードがアクティブになり、INC / CHANGEボタンを使用して時間を設定する必要があり、次へボタンを使用して桁に移動します。タイムレコーダーを設定した後、継続的に動作します。
プログラムの説明
コードには、8051ファミリライブラリと標準の入出力ライブラリが含まれています。そして、私たちが使用したピンを定義し、計算のためにいくつかの変数を取りました。
#include
そして、与えられた機能はLCDを駆動するために使用されます。
void 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を初期化し、フォームRTCICから日時を読み取るために使用されます。
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(); ショータイム(); //時刻/日付/日を表示delay(1);
これらの関数は、10進数をBCDに、BCDを10進数に変換するために使用されます。
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 =(decimalByte%10); bcd = ab; bcdを返します。}
以下の関数はI2C通信に使用されます。
void I2CStart(){SDA = 1; SCL = 1、SDA = 0、SCL = 0;} // ds1307RTCと通信するための「開始」関数voidI2CStop(){SDA = 0、SCL = 1、SDA = 1; } //通信用の「停止」関数ds1307RTC unsigned char 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からデータを受信します{unsignedchar 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に時刻/日付/日を表示する関数{charvar; lcdcmd(0x80); lcdprint( "日付:"); sprintf(var、 "%d"、date); lcdprint(var); sprintf(var、 "/%d"、mon); lcdprint(var); sprintf(var、 "/%d"、year + 2000); lcdprint(var); lcdprint( ""); lcdcmd(0xc0); lcdprint( "時間:"); sprintf(var、 "%d"、hour); lcdprint(var); sprintf(var、 ":%d"、min); lcdprint(var); sprintf(var、 ":%d"、sec); lcdprint(var); lcdprint( ""); // day(day1); lcdprint( ""); }