DS3231 モジュールの時刻をコンピュータと同期します。 DS3231 および AVR マイクロコントローラーのクロック

DS3231 チップは、温度補償水晶発振器を内蔵した高精度 RTC リアルタイム クロックで、時間のずれは年間わずか ±2 分です。 さらにアラーム機能も実装しており、割り込み出力もあります。 この時計は、ストラップ要素とバッテリーコンパートメントを備えた既製の Arduino モジュールとして購入できます。

ここでモジュールを注文しました。 その図を以下の図に示します。


マイクロ回路は広く使用されているを使用します。 標準 (100 kHz) および高速 (400 kHz) データレートをサポートします。 I2C バス上のマイクロ回路アドレス (7 ビット) は 1101000 です。さらに、モジュールには I2C メモリ (24C32) がありますが、図には示されていません。

電力モード

マイクロ回路の電源電圧は 2.3 ~ 5.5V の範囲で、外部電源 (Vcc ライン) とバッテリー (Vbat) 用の 2 本の電源ラインがあります。 外部電源電圧は常に監視されており、閾値 Vpf=2.5V を下回るとバッテリーラインに切り替わります。 電力線の切り替え条件を次の表に示します。

時計の精度は周囲温度を監視することで維持されます。 マイクロ回路は、クロック ジェネレーターの周波数を調整するための内部手順を開始します。調整量は、周波数対温度の特別なグラフを使用して決定されます。 この手順は電源が投入された後に開始され、その後 64 秒ごとに実行されます。

充電を節約するために、バッテリが接続されているとき (電圧が Vbat ラインに印加されているとき)、クロック ジェネレータは、Vcc ラインの電圧がしきい値 Vpf を超えるか、マイクロ回路の正しいアドレスが送信されるまで起動しません。 I2Cインターフェース。 クロックジェネレータの起動時間は 1 秒未満です。 電源 (Vcc) が印加されてから、または I2C インターフェイス経由でアドレスが受信されてから約 2 秒後に、周波数補正手順が開始されます。 クロック ジェネレータが開始されると、Vcc または Vbat が存在する限り動作し続けます。 初めて電源を入れると、日付と時刻レジスタがリセットされ、次の値になります: 01/01/00 – 01 – 00/00/00 (日/月/年/ – 曜日 – 時/分) /秒)。

I2C インターフェイスを介したデータ送信がない場合、3.63V バッテリで電力を供給する場合の消費電流は 3 µA です。 外部 5.5V 電源と高い I2C データ転送速度を使用する場合、最大消費電流は 300 µA に達する可能性があります。

外部リセット機能

RST ラインは外部リセットに使用でき、低電圧アラーム機能も備えています。 ラインは内部抵抗を通じて High にプルアップされるため、外部プルアップは必要ありません。 外部リセット機能を使用するには、RST ラインと共通線の間にボタンを接続できます。超小型回路には接点バウンス保護が備わっています。 アラーム機能は、RST ラインが Low 論理レベルに設定されているときに、電源電圧 Vcc がしきい値 Vpf を下回るとアクティブになります。

DS3231 レジスタの説明

以下の表は、リアルタイム クロック レジスタのリストを示しています。

住所D7D6D5D4D3D2D1D0関数限界
0x000 10秒00-59
0x010 10分00-59
0x020 12/24 午前午後10時間時間時計1 ~ 12 + 午前/午後、または 00 ~ 23
10時間
0x030 0 0 0 0 曜日1-7
0x040 0 10位番号日付01-31
0x05世紀0 0 10ヶ月月/世紀01-12 + センチュリー
0x0610年00-99
0x07A1M110秒秒、最初のアラーム00-59
0x08A1M210分分、最初のアラーム00-59
0x09A1M312/24 午前午後10時間時間時計、第一アラーム1 ~ 12 + 午前/午後、または 00 ~ 23
10時間
0x0AA1M4DY/DT10位曜日、第1アラーム1-7
番号日付、第一アラーム01-31
0x0BA2M210分分、第 2 アラーム00-59
0x0CA2M312/24 午前午後10時間時間時計、第2アラーム1 ~ 12 + 午前/午後、または 00 ~ 23
10時間
0x0DA2M4DY/DT10位曜日、第2アラーム1-7
番号日付、第2アラーム01-31
0x0EEOSCBBSQW変換RS2RS1INTCNA2IEA1IE設定レジスタ(制御)
0x0FO.S.F.0 0 0 EN32kHzBSYA2FA1Fステータスレジスタ
0x10サインデータデータデータデータデータデータデータエージングオフセットレジスタ
0x11サインデータデータデータデータデータデータデータ温度レジスタ、上位バイト
0x12データデータ0 0 0 0 0 0 温度レジスタ、下位バイト

時間情報は 2 進数の 10 進数形式で保存されます。つまり、10 進数の各桁 (0 から 9) は 4 ビットのグループとして表されます。 1 バイトの場合、下位ニブルは 1 をカウントし、上位ニブルは 10 をカウントします。時間はアドレス 0x00 ~ 0x06 のレジスタでカウントされます。時間のカウントについては、12 時間モードまたは 24 時間モードを選択できます。 クロック レジスタ (アドレス 0x02) の 6 番目のビットを設定すると、12 時間モードが設定されます。このモードでは、5 番目のビットが時刻を示し、値 1 は午後 (PM) に対応し、値 0 は午後 (AM) に対応します。 6 番目のビットのゼロ値は 24 時間モードに対応し、ここでは 5 番目のビットが時間のカウントに関与します (値 20 ~ 23)。

曜日レジスタは深夜に 1 から 7 まで増分され、月レジスタ (アドレス 0x05) には世紀ビット (7 番目のビット) が含まれており、年カウント レジスタ (アドレス 0x06) がオーバーフローすると 99 から 00 に切り替わります。 。

DS3231 チップは 2 つのアラーム クロックを実装しており、1 つ目のアラーム クロックはアドレス 0x07 ~ 0x0A のレジスタを使用して構成され、2 つ目のアラーム クロックはレジスタ 0x0B ~ 0x0D を使用して構成されます。 A1Mx および A2Mx ビットを使用して、アラームのさまざまなモードを設定できます。このビットを設定すると、対応するレジスタが比較動作から除外されます。 以下の表は、さまざまなアラーム モードのビットの組み合わせを示しています。

表で指定されていないビットの組み合わせは、アラームが誤って機能する原因となります。 DY/DT ビットがクリアされている場合は、目覚まし時計の日付の一致 (曜日) が監視され、DY/DT ビットがセットされている場合は、曜日の一致がチェックされます。

ほとんどの機能は制御レジスタで設定されます。 EOSC ビットはクロック ジェネレータの開始を制御し、ビットをリセットするとクロック ジェネレータが開始されます。 ビットを設定すると、バッテリー モード (Vbat) の場合のみ、ジェネレーターが停止します。 外部電源 (Vcc) から電力が供給されている場合、発振器は EOSC ビットの状態に関係なく常に動作します。 有効な場合、デフォルトのビット値は 0 です。

BBSQW ビットをセットすると、外部電源がない場合、INT/SQW 出力 (3 番ピン) がバッテリ電源モードで動作できるようになります。 このビットがゼロに設定されている場合、外部電源電圧 Vcc がしきい値 Vpf を下回ると、INT/SQW 出力は状態 3 (非アクティブ) になります。 電源が投入された後のデフォルトのビット値は 0 です。

CONV ビットは強制温度測定を担当します。このビットを設定すると変換プロセスが開始され、その間にクロック ジェネレータの周波数も調整されます。測定結果はアドレス 0x11、0x12 のレジスタに格納されます。 前回の変換が完了している場合のみ開始可能ですので、開始前にビジーフラグBSYを確認する必要があります。 強制的な温度変換は、内部の 64 秒の周波数調整サイクルには影響しません。 CONV ビットを設定しても、2 ms の間は BSY フラグに影響しません。 CONV ビットと BSY ビットは、変換が完了すると自動的にクリアされます。

ビット RS2、RS1 は​​、INT/SQW 出力における方形パルス (方形波) の周波数を設定します。 デフォルトでは、有効な場合、ビットは 1 に設定されます。以下の表は、ビットの可能な組み合わせを示しています。

INTCN ビットは INT/SQW 出力を制御します。 ビットがリセットされると、出力に方形パルス (方形波) が表示され、その周波数は RS2、RS1 ビットで設定されます。 INTCN ビットがセットされると、出力はアラーム割り込みの生成に使用されます。 デフォルトでは、ビット値は 1 です。出力タイプは INT/SQW - オープン ドレインであるため、抵抗を介してハイ論理レベルにプルアップする必要があり、アクティブ レベルはローです。

A1IE、A2IE ビットを設定すると、それぞれ 1 番目と 2 番目のアラーム信号の割り込みが有効になります。 ビットをリセットし、割り込みを無効にします。 デフォルト値は 0 です。

ステータス レジスタにはイベント フラグが含まれており、32 kHz 出力を制御します。 OSF フラグはクロック ジェネレーターの状態を反映します。値 1 はクロック ジェネレーターが停止していることを意味します。このイベントは次の場合に発生する可能性があります。

  • 電源投入後初めて
  • バッテリまたは外部電圧がクロックジェネレータを動作させるのに不十分です
  • バッテリーモードでEOSCビットをセットすることで発電機がオフになります。
  • 水晶振動子に影響を与える外部要因(ノイズ、漏れなど)

一度設定するとビット値は変化しないため、ビットを手動でリセットする必要があります。

EN32kHz ビットを設定すると、32kHz 出力 (1 番ピン) で方形パルス (方形波) を生成でき、パルス周波数は固定され、32.768 kHz に等しくなります。 ビットをリセットすると、この機能が無効になり、出力が第 3 状態 (高入力インピーダンス) に移行します。 デフォルトでは、ビット値は 1 で、電力が印加されると出力にパルスが表示されます。 出力タイプは 32kHz オープン ドレインであるため、高ロジック レベルへのプルアップが必要です。

BSY ビジー フラグは、温度変換およびクロック調整プロセス中に設定されます。 変換が完了すると、フラグはリセットされます。

目覚ましフラグA1F、A2Fは、計時レジスタと目覚ましレジスタの値が一致したときにセットされます。 アラーム割り込み A1IE、A2IE が有効で、割り込み出力が割り当てられている (INTCN ビットがセットされている) 場合、割り込み信号が INT/SQW 出力に表示されます (論理レベルが High から Low に遷移します)。 フラグは値 0 を書き込んで手動でリセットする必要があります。

エージング オフセット レジスタは、クロック ジェネレータの周波数を調整するように設計されています。 レジスタ値は、温度変化が検出された場合、および CONV ビットによって温度変換がトリガされた場合に、内部調整手順中に発振器周波数に追加されます。 オフセット値は符号付きです。つまり、正の値(1 ~ 127)は周波数を減らし、負の値(128 ~ 255)は周波数を増やします。 同じオフセットでも、温度によって周波数の変化が異なります。 +25°C では、周波数変化は 0.1 ppm/LSB になります。

現在の温度値は、アドレス 0x11 と 0x12 (それぞれ上位バイトと下位バイト) のレジスタに保存され、レジスタ内の温度値は定期的に更新されます。 左揃えが設定され、分解能は 10 ビットまたは 0.25°C/LSB です。つまり、上位バイトには温度の整数部分が含まれ、下位レジスタの 6 番目と 7 番目のビットが小数部分を構成します。 上位バイトの 7 番目のビットは温度の符号を示します。たとえば、値 00011011 01 は温度 +27.25 °C に対応し、値 11111110 10 は温度 -2.5 °C に対応します。

時間レジスタを読み取るときは、追加のバッファを使用することをお勧めします。つまり、個々の読み取り操作の間に時間レジスタの値が変更される可能性があるため、複数のレジスタを個別に読み取るのではなく、一度に読み取ります。 このルールは、アカウント レジスタに新しいデータを書き込むときにも従うことをお勧めします。 秒レジスタに新しい値を書き込むとクロックが 1 秒間一時停止され、この間に残りのレジスタを書き換える必要があります。

DS3231 をマイクロコントローラーに接続する

PIC16F628Aマイコンにクロックを接続して使用しました。 接続図を以下に示します。


電源が投入されると、ダッシュ (– – – – – –) がインジケーターに表示され、その後時計が初期化され、クロック ジェネレーターを開始するために必要な 1 秒の遅延で時間値がインジケーターに表示されます。 インジケーターには、時、分、秒が小数点で区切られて表示され、時間形式は 24 時間形式です。 SB1 の「表示」ボタンを使用すると、表示形式を変更できます。インジケーターは、温度と時と分の値を小数点で区切って表示し、2 Hz の周波数で点滅します。 温度は小数部なしで表示され、プログラムはアドレス 0x11 にある温度ストレージの上位バイトのみを読み取ります。

時間値は、SQW/INT ラインの割り込みを介してクロックから読み取られ、最初のアラーム信号によって制御されます。クロックの初期化中、アラーム クロックは 2 秒ごとの信号に設定されます。 HL1 LED はインジケーターとして機能し、割り込み信号で 1 秒ごとに点滅します。 HL2 LEDは、I2Cインターフェースを介したデータ送信でエラーが発生した場合に点灯します。

さらに、SB2「設定」、SB3「インストール」ボタンを使用して時計を設定する機能をプログラムに追加しました。 SB2 ボタンを押すとセットアップ モードに入り、インジケーターには分と秒の代わりに 00 時間とダッシュが表示されます (00 – – – –)。 SB3 ボタンを使用して時間の値を設定し (押すたびに増加)、SB2 ボタンを押すと分の編集に切り替わり、ダッシュの代わりに 00 分が表示されます。 ボタン SB3 も必要な値などを設定します。 秒を編集してSB2ボタンを押すと時計の時刻が書き換えられ、更新された時刻がインジケーターに表示されます。

プログラム コードの一部を以下に示します (完全版は記事の最後からダウンロードできます)。

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; #含む LIST p=16F628A __CONFIG H"3F10" ;マイクロコントローラ構成エラーレベル -302 ;リストにエラー 302 のメッセージを表示しません Sec equ 0020h ;補助アカウントレジスタ Sec1 equ 0021h ; Sec2 等価 0022h ; scetbit equ 0024h;ビット数をカウントするための補助レジスタ perem equ 0025h;spi、i2c temp を介したバイト受信/送信のための補助レジスタ equ 0026h;温度レジスタ perem_1 equ 0027h;2 進-10 進コンバータ用の補助レジスタ。 result equ 0028h ;2進数-10進数変換補助レジスタ dat_ind equ 0029h ; spi プロトコル経由で送信するデータ レジスタ adr_ind equ 002Ah ; spi プロトコル経由で送信するアドレス レジスタ 秒 equ 002Bh ; 時間分を設定するための秒格納レジスタ equ 002Ch ; 時間と時間を設定するための分格納レジスタ equ 002Dh ;時間設定用の時間ストレージレジスタ adr_i2c equ 002Eh ; i2c インターフェースデータ転送サブルーチンのレジスタ tmp_i2c equ 002Fh smile_adr equ 0030h data_i2c equ 0031h flag equ 007Fh ; フラグレジスタ #DEFINE int PORTB,0 ; 割り込みライン INT/SQW DS3231 #DEF INE sda PORTB ,1 ; DS3231 接続用の SDA ライン #DEFINE scl PORTB,2 ; DS3231 接続用の SCL ライン #DEFINE sda_io TRISB,1 ; SDA ラインの方向 #DEFINE scl_io TRISB,2 ; SCL ラインの方向 #DEFINE datai PORTB,5 ;MAX7219ドライバのデータ入力ライン #DEFINE cs PORTB,6 ;ドライバ選択ライン MAX7219 #DEFINE clk PORTB,7 ;ドライバクロックライン MAX7219 #DEFINE LED PORTB,4 ;i2cエラーLED #DEFINE led_sec PORTB,3 ;クロック進行インジケータLED 1Hz #DEFINE regim PORTA,2 ;表示ボタン - 表示モードの変更 #DEFINE nast PORTA,3 ;設定ボタン - 時間設定モードへの移行 #DEFINE ust PORTA,4 ;設定ボタン - 時計値の設定;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;; org 0000h ;アドレス 0000h からプログラムの実行を開始します goto Start ;Start ラベルに移動します ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;メインプログラム開始 movlw b"00000000" ;ポート A の出力ラッチの値を設定 movwf PORTA ; movlw b"01000000" ;ポートBの出力ラッチの値を設定します movwf PORTB ; movlw b"00000111" ;コンパレータをオフにする movwf CMCON ; bsf STATUS,RP0 ;最初のバンクを選択 movlw b"00000111" ;ポート B の入出力ラインを設定 movwf TRISB ;RB0-RB2 - 入力用、残りは出力用 movlw b"11111111" ;入力/出力を設定ポートAの出力ライン movwf TRISA ;入力するすべてのライン bcf STATUS,RP0 ;バンク0を選択 clrfフラグ ;リセットフラグレジスタ call init_lcd ;ドライバ初期化サブルーチン(MAX7219)をコール viv_not ;出力ダッシュ記号 " ------ " ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;; movlw b"11010000" ;デバイスアドレス(DS3231) movwf SLAVE_ADR ;i2c経由で受信/送信レジスタに4バイトを書き込みます;ここでは最初のアラームが設定されており、毎秒ビープ音が鳴ります movlw data_i2c ;i2c経由で最初の受信/送信レジスタを設定します movwf FSR ; movlw b"10000000" ;最初のアラームの秒レジスタのデータ movwf INDF ; incf FSR,F ; movlw b"10000000" ;最初のアラームの分レジスタのデータ movwf INDF ; incf FSR,F ; movlw b"10000000" ;最初の目覚まし時計のクロックレジスタのデータ movwf INDF ; incf FSR,F ; movlw b"10000000" ;第 1 アラームの日付/曜日レジスタのデータ movwf INDF ; 動く。 4 ; i2c movwf tmp_i2c 経由で 4 バイトを転送します。 movlw 0x07 ;最初の目覚まし時計の秒レジスタのアドレスを設定 movwf adr_i2c ; call write_i2c ; i2c インターフェイス経由で書き込みサブルーチンを呼び出す call err_prov ; I2C 書き込み/読み取りエラーをチェックする movlw .1 ; i2c 経由で最初のバイトを転送する movwf tmp_i2c ; movlw 0x0E ; 制御レジスタのアドレスを設定 movwf adr_i2c ; movlw data_i2c ; i2c movwf FSR を介して最初の送信/受信レジスタを設定します。 movlw b"00000101" ;クロックジェネレータを開始し、movwf INDFのINT/SQWピンの動作を禁止します。 ;バッテリ電源モード、INT/SQW出力のパルス周波数は1Hzです。 ;INT/SQW出力はアラームの生成に使用されます。クロック割り込み、 ; アラームクロック割り込みを有効にする 最初のアラーム呼び出し write_i2c ; i2c インターフェイス経由で記録サブルーチンを呼び出す err_prov ; I2C 書き込み/読み取りエラーをチェックするmet_2 movlw .1 ; i2c 経由で最初のバイトを転送する movwf tmp_i2c ; movlw 0x0F ;ステータスレジスタのアドレスを設定 movwf adr_i2c ; movlw data_i2c ; i2c movwf FSR を介して最初の送信/受信レジスタを設定します。 movlw b"00000000" ; OSF ビットをリセットし、EN32kHz 出力でのパルスの生成を禁止します。 movwf INDF ; アラーム割り込みフラグ A2F、A1F をリセットします write_i2c ; i2c インターフェイス経由で記録サブルーチンを呼び出します call err_prov ; I2C 書き込みをチェックします/read エラーmet_1 btfsc int ; アラーム割り込みラインをポーリング gotomet_3; bsf led_sec ;時計の進行状況インジケータ LED をオンにします gotomet_4 ; met_3 bcf led_sec ;クロック進行状況インジケータ LED をオフにします btfsc nast ;クロック設定ボタンをポーリングします gotomet_5 ; call nast_time ;時刻を設定するサブルーチンを呼び出します gotomet_2 ; met_5 btfsc regim ;表示モードボタンのポーリング gotomet_1 ; met_6 は paus_knp を呼び出します。 btfss 体制 ; gotomet_6 ; btfss flag,2 ;表示モードフラグの値を変更します gotomet_7 ; bcf flag,2 ;リセット指示フラグ、時計表示モード gotomet_1 ; met_7 bsf flag,2 ;表示フラグ、温度、時計表示モードの設定 gotomet_1 ; met_4 movlw .1 ; i2c movwf tmp_i2c を介して最初のバイトを送信します。 movlw 0x11 ;高温レジスタのアドレスを設定 movwf adr_i2c ; call read_i2c ; I2C 経由で読み取りサブルーチンを呼び出す call err_prov ; I2C 書き込み/読み取りエラーをチェックする movf INDF,W ; 温度値を一時レジスタにコピーする movwf temp rd_time movlw .3 ; i2c 経由で 3 バイトを転送する movwf tmp_i2c ; movlw 0x00 ;秒レジスタアドレスを設定 movwf adr_i2c ; call read_i2c ;I2C経由で読み取りサブルーチンを呼び出す call err_prov ;I2C書き込み/読み取りエラーをチェックする btfsc flag,2 ;指示モードフラグのポーリング gotomet_8 ; call vivod ;デジタルディスプレイに時計値を表示するためのサブルーチンを呼び出します gotomet_2 ; met_8 call vivod_temp ;デジタルディスプレイに温度と時計を表示するためのサブルーチンを呼び出します gotomet_2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

#含む

CONFIG H"3F10" ;マイクロコントローラー構成

errorlevel -302 ;リストに 302 エラー メッセージを表示しません

Sec equ 0020h ;補助アカウントレジスター

Sec1 等価 0021h ;

Sec2 等価 0022h ;

scetbit equ 0024h ;補助レジスタのビット数をカウント

perem equ 0025h ;spi、i2c経由の補助バイト受信/送信レジスタ

temp equ 0026h ;温度レジスタ

perem_1 equ 0027h ;BCD 補助レジスタ

result equ 0028h ;2進数-10進数変換補助レジスタ

dat_ind equ 0029h ;spi プロトコル経由で送信するためのデータ レジスタ

adr_ind equ 002Ah ;spiプロトコル経由で送信するためのアドレスレジスタ

Second equ 002Bh ;時刻設定用の秒記憶レジスタ

minut equ 002Ch ;時刻を設定するための分格納レジスタ

時間 equ 002Dh ;時間を設定するための時間記憶レジスタ

adr_i2c equ 002Eh ;i2c インターフェースデータ転送サブルーチンのレジスタ

tmp_i2c 等価 002Fh

スレーブ_adr equ 0030h

data_i2c 等価 0031h

フラグ equ 007Fh ;フラグレジスタ

#DEFINE int PORTB,0 ;割り込みライン INT/SQW DS3231

#DEFINE sda PORTB,1 ;DS3231 を接続するための SDA ライン

#DEFINE scl PORTB,2 ;DS3231 を接続するための SCL ライン

#DEFINE datai PORTB,5 ;MAX7219ドライバのデータ入力ライン

#DEFINE cs PORTB,6 ;ドライバ選択ライン MAX7219

#DEFINE clk PORTB,7 ;MAX7219ドライバのクロックライン

#DEFINE LED PORTB,4 ;i2c エラー LED

#DEFINE led_sec PORTB,3 ;LED クロック進行状況インジケーター 1Hz

#DEFINE regim PORTA,2 ;表示ボタン - 表示モードを変更します

#DEFINE nast PORTA,3 ;設定ボタン - 時間設定モードに入ります

#DEFINE ust PORTA,4 ;設定ボタン - クロック値を設定します

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

org 0000h ;アドレス 0000h からプログラムの実行を開始します

開始に移動 ;開始ラベルに移動

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;メインプログラム

start movlw b"00000000" ;ポート A の出力ラッチの値を設定します

movlw b"01000000" ;ポートBの出力ラッチの値を設定します

movlw b"00000111" ;コンパレータをオフにする

bsf STATUS,RP0 ;最初のバンクを選択

movlw b"00000111" ;ポート B の入出力ラインを構成します

movwf TRISB ;RB0-RB2 - 入力に、残りを出力に

movlw b"11111111" ;ポート A の入出力回線の設定

movwf TRISA ;入力するすべての行

bcf STATUS,RP0 ;バンク 0 を選択

clrf フラグ ;リセットフラグレジスタ

call init_lcd ;ドライバ初期化ルーチンを呼び出します(MAX7219)

viv_not を呼び出し、ダッシュ記号「 ------ 」をインジケーターに出力します

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

movlw b"11010000" ;デバイスアドレス (DS3231)

; i2c 経由で受信/送信レジスタに 4 バイトを書き込みます

movlw data_i2c ; i2c 経由で最初の受信/送信レジスタを設定

movlw b"10000000" ;最初のアラームの秒レジスタのデータ

movlw b"10000000" ;最初のアラームの分レジスタのデータ

movlw b"10000000" ;最初の目覚まし時計レジスタのデータ

movlw b"10000000" ;第1アラームの日付/曜日レジスタのデータ

movlw .4 ;i2c経由で4バイトを転送

movlw 0x07 ;最初の目覚まし時計の秒レジスタのアドレスを設定します

なぜこれだけが必要なのでしょうか?

60 秒 * 60 分 * 24 時間 * 365 日 = 1 年あたり 31,536,000 秒。

これら何百万ものそれぞれについて、2 秒は一方向または別の方向に進む可能性があります。 3,150 万を 100 万で割って 2 を掛けると、1 年あたり 63 秒 (最大) になります。 許容可能なオプション? とても。 ただし、半年に一度、1分に収まるように時刻を同期します。

モジュールクロックの時刻は一般的にどのような方法で設定できますか?

従来、ライブラリの使用例のうち、DS3107モジュールからはArduinoスケッチを使用して時刻を設定していました。 アルゴリズムは次のとおりです。スケッチを開いて「コンパイルしてアップロード」をクリックし、コントローラーを初めて起動するときに時間が設定されます。 疑問は残ります:何時ですか? Arduino はどのようにして正確な時刻を知ることができるのでしょうか? そしてそれは非常に簡単です - コンパイル時間をスケッチするだけです。 ただし、このアプローチにはいくつかの欠点があることがわかります。
  • コンパイル時間はコンピュータの「能力」に依存します。
  • ダウンロード時間は、コンパイルされたスケッチが Arduino ボードに転送される速度によって異なります。
  • アップロードされたスケッチは「使い捨て」です (Arduino にアップロードするとすぐに無効になります)。
これらの制限を回避するにはどうすれば「回避」できるでしょうか? たとえば、コンパイル時刻がわかっている (実験的に設定) と、コンピュータの時計をこの時刻に「進める」ことができます。 次にコンパイルを実行し、ボードをフラッシュすると時間が設定されます。 この方法の利点は、比較的簡単であることです。 短所 - 比較的不便で、比較的不正確で、1 回限りの方法です。

他に何が考えられますか? たとえば、スケッチに所要時間を手動で設定したり、押すことができるボタンを提供したりできます。 正しい瞬間たとえば、現在の瞬間から 2 分など、指定された時間を「手動で」設定します。スケッチが「塗りつぶされ」ている間、ボタンを押す非常に必要な瞬間を手動で追跡する準備をしている間に、ちょうどその数分が経過します。 。 そして、コンピュータの時計を見ながら、ボタンを押す「まさに」その瞬間を待ちます。 長所 - 前の方法よりも複雑ですが、それでも比較的単純ですが、最初の方法よりも正確です。 欠点 - この方法はさらに不便で、時間がかかり、依然として「1 回限り」のスケッチです。

誰が責任を負うのか、何をすべきなのか?

これら 2 つの修辞的な質問を自問した後、私はインターネットにアクセスして、クロック モジュールとコンピュータの時刻同期を既に作成したのは誰なのかを探しました。 そして、ご存知のように、探す人は必ず見つけます。 というオプションを見つけました。 理論的には、すべてが単純です。通常の「バッチ ファイル」は、「最初の」方法で取得された現在のフルタイムを解析し (時間自体に加えて日付も必要なため)、時間を 2 秒増やします。この新しいループが到着する瞬間まで、空のループを駆動します。COM ポートにデータを「スロー」する時間は「プラス 2 秒」です。 さらに、「新しい plus_two_seconds」時間は別の方法で追跡されます (興味のある方は %time% 経由)。 しかし、そのような決定の「行き詰まり」については後で説明します。 COM ポートに「スローされた」データは Arduino によって解析され、モジュールに時刻が設定されます。 すべてがシンプルで論理的で便利に思えます。 しかし、「しかし」という非常に悪い言葉があります。 これはすべてドイツ人によって書かれたものと思われますが、Windows の地域標準は「私たちの」とは異なり、特に小数部分はカンマではなくドットで区切られています。 国内地域標準で起動した場合、バッチファイル内では空のループを抜ける時間が XX:XX:XX.xxx との比較条件で記述されているため、動作しません。 そうですね、ピリオドの代わりにカンマを入れる必要があります。これで「すべてを修正しました」ということになります。 しかし、それだけではありません (「バッチブック」でプログラムすることがどのような悪であるかを他に誰が覚えているかを確認することができます)。 本体ファイルはもっと本格的に修正する必要があります。 そして、DOSの「巻き戻しマット」と「マニュアル」を使って修正しました。 「バトニク」はそれを修正しましたが、スケッチはまだ機能しませんでした - 時間が設定されていませんでした。 つまり、データはポートに送信され、Arduino はそれを認識しましたが、「何か問題が発生しました」ということです。

バッチファイルがArduinoに何をどのような形式で送信するかを見てみましょう(参考までに)。

ケース 83: //S = 秒 ケース 68: //D = 分 (ペルシャ語の Daghigheh) ケース 72: //H = 時 ケース 84: //T = 月の日 (ドイツ語のタグ) ケース 77: /// M = 月 case 74: /// J = 年 (ドイツ語で Jahr)
データは S**~D**~H**~T*~M**~J****~ の形式で送信されます。~ は 2 バイトの復帰です。 合計、31 バイト。 それほど多くはないようですが、データはすぐに送信されます。

ただし、不便な点もあります。ご覧のとおり、曜日が送信されません。 毎月の日のみ。 曜日に依存するアラーム付き時計を実装するには問題が発生します。 曜日はスケッチに「手動」で設定する必要がありますが、これもまたスケッチの何らかの「使い捨て」、つまりその劣等性を示唆しています。

「工場からの」スケッチの劣悪さ、通常の動作の拒否、「私たちの」緯度に合わせて「本体ファイル」を修正する必要性などの要因を総合して、私はすべてを自分で開発することにしました。 そうであれば、欠点を解消し、データ形式を最適化することができます。

ソフトウェアとハ​​ードウェア。

すべてを機能させるには、Windows 用のプログラムと Arduino のハードウェアとソフトウェアの組み合わせという 2 つのコンポーネントが必要です。

まず、交換プロトコルに関する一般的なデータです。 送信するデータ形式を自由に選択できるようになると、31 バイトの情報を送信するのは合理的ではないと判断し、送信データを 4 バイトに削減しました。 それで、それで十分でしたか? 4バイトに何を入れることができますか? はい、それで十分です。 必要なものがすべて収まります。 多くの人は 4 バイトが何であるかを推測していると思います。 想像できない人のために、ウィキペディアから記事の一部を引用します。

UNIX 時間 (POSIX 時間) は、UNIX およびその他の POSIX 互換オペレーティング システムで採用されている、時刻を記述するためのシステムです。 1970 年 1 月 1 日 (木) の午前 0 時 (00:00:00 UTC) から経過した秒数として定義されます。
UNIX 時間は、人間が読みやすいように年、月、日、時、分を計算する必要がなく、秒ごとに増加する整数として表されます。 最新の UNIX 時間は UTC と一致しており、カウントは SI 秒で行われます。

したがって、UNIX 時間を格納する整数は 4 バイトを必要とし、最大 2,147,483,648 秒まで保持するには十分です。 その後 可能潜在的な問題。 なぜ潜在的なのでしょうか? これは数値が上昇するしきい値であるため、 多分否定的に解釈される可能性があります(一度に多くの好奇心旺盛な同志のiPhoneがそうであったように)。 おそらく、そうなる可能性がありますが、必ずしもそうなるとは限りません。それは、プログラマーの手が自然に与えられた場所から伸びるかどうかによって決まります。 示されている秒数は、2038 年 1 月 19 日の 03:14:08 に相当します。 この時点までは、64 ビット バージョンの OS にゆっくりと切り替えることができます。このバージョンでは、時間が 8 バイトの変数に格納され、今後 2,920 億年間持続することになります。 私たちの一生はこれで十分になる可能性があります。 その後、UNIX の 128 ビット バージョンにアップグレードする必要があります。

このオプションを選択することでどのような問題が解決されましたか? まず、転送されるバイト数が大幅に削減され、時間設定の精度がミリ秒単位で向上しました。 すごいですよね? そして 2 つ目は、(おそらく) Linux との互換性を容易にしたことです。 恥ずかしながら、私は Linux に慣れることができず、ほとんど Windows しか使っていません。 Windows 用の転送プログラムは作成できますが、Linux 用は作成できません。 しかし、Linux では、Windows よりもはるかに簡単に UNIX 時刻値を取得し、この数値を COM ポートに送信できると思います。

なし 追加曜日などのデータを送信する必要はありません。 UNIX 時間のみ。 それ以外はすべてArduinoで行われます。

ここで直接的に少し具体的に説明します 初めコンポーネント - Windows 用のプログラム。 このプログラムは古き良き Delphi で書かれています。 起動すると、ポップアップ ウィンドウが表示され、データの送信先の COM ポートを選択するように求められます。 選びましょう。 残りの設定はデフォルトのままにする必要があります。

プログラムはどのように機能するのでしょうか? Windows の時刻形式を UNIX の時刻形式、つまり 1970 年 1 月 1 日の午前 0 時からの秒数に変換します。 次に、3 秒が追加され、空のループ (明らかに追加の 3 秒より短いループ) に「落ち」、必要な秒数 (可能な限り 000 ミリ秒に近い) で終了します。 言い換えれば、その秒の始まりの発生が監視され、その値がArduinoに送信される必要があります。 同意します。たとえば、現在が XXXXXXXXX5 秒であるときに、実際にはすでに XXXXXXXXX5 秒であり、(たとえば) 1000 分の 756 秒であるデータを送信することは正しくありません。 このため、データ転送を開始する秒の先頭を追跡する必要があります。 データを転送した後、プログラムはステータス「完了:)」をフレンドリーに報告します。 これでプログラムの使命は完了です。


2番コンポーネント - ハードウェアとソフトウェア - Arduino。 2つあります 品種このプロジェクトの「ハードウェア」: 画面とボタンを備えた「フル」バージョンと、モジュール時間を素早く設定するための「必要最低限​​の」バージョンで、「クソとスティック」から組み立てられています。 それらの違いについては以下をご覧ください。 「フル」バージョンは、Arduino Nano、I2C からシールドまでの「アダプター」を備えた 1602 シールド、オプションの Arduino リセット ボタン、およびクロック モジュールを接続するためのピン ヘッダー (メス) で構成されます。 また、オプションで端末本体に「かわいい」ステッカーも貼れます。 「必要最低限​​の」バージョンは、Arduino (Uno、Nano、Pro Mini + DTR を備えた「正しい」USB アダプター) とクロック モジュールを接続するための 4 本のワイヤーで構成されています。



図からわかるように、「完全版」バージョンには、「必要最低限​​の」バージョンに加えて、リセット ボタンと「アダプター」を備えた 1602 画面が含まれています。両方のバージョンの主な機能は完全に同一です。画面は工程の段階を表示するだけで、時刻設定の処理が完了すると、新たに設定された時刻、日付、曜日が表示されます。 「必要最低限​​の」バージョンでは、Arduino ボードに組み込まれた LED が画面の役割を果たします。新しい時刻を設定するプロセスの後、LED が点灯し始めます。すべての指示。

リセットボタンは何のためにあるのでしょうか? そのため、フルバージョンでは、時刻を設定した後、Arduino は無限ループに入り、新しく設定された時刻を表示します。つまり、実際には時計になります。 また、急遽作られた時計であるため、秒の選択が遅れて行われる、電源を切ると時刻表示が消えてしまうなどの理由から、通常の時計の代替品にはなりません。 結局のところ、目標は時刻が正しく同期されていることを確認することであり、それ以上ではありません。 したがって、次のクロック モジュールを同期するには、リセットする必要があります (より正確には、USB ケーブルを「歪ませる」ことで実行できます)。 言い換えれば、ボタンの目的は純粋に実用的なものです。 必要に応じて、それなしで行うこともできます。

ハードウェアのバージョンが 2 つありますが、スケッチは 1 つしかない場合、Arduino をフラッシュするにはどうすればよいですか? ファームウェアの「正しい」バージョンをコンパイルするには、スケッチ ヘッダーに目的のパラメータ値を設定する必要があります。 完全版: 真実 「フル」バージョンの場合、または 間違い -「削ぎ落とされた」の意味。 したがって、コンパイラは、どのバージョンのハードウェアに対してファームウェアをコンパイルするかを決定します。

接続図があり、スケッチ コードが必要です。 スケッチが「フル」バージョンで適切に動作するには、ライブラリが必要であることに注意してください。 液晶 I2Cフランク・デ・ブラバンダー著(ライブラリマネージャーを使用してリポジトリからインストールされます)。 また、クロック モジュールをサポートするためのライブラリも必要です (1 つだけではありません :)。 ここからダウンロード: 。 図書館を整理しました。

スケッチのコードは次のとおりです。

//=============================================== ====== 変更可能な設定 === ==================================== #define fullVersion true //true = 画面付きの「フル」バージョン; false = LED を内蔵した「無駄を省いた」バージョン //==================================== ============ 使用するライブラリと変数の宣言 = =============================== ==== #include #含む #if (フルバージョン) #include #endif unsigned long t1 = 0; //受信時刻の変数 unsigned long t2 = 0; // 受信した時刻バイト b の変数; //COM ポートからデータを受信するためのバッファ #if (fullVersion) byte day = 0; #endif DS3231 クロック; RTCDateTime dat1; #if (フルバージョン) LiquidCrystal_I2C lcd(0x3F,16,2); //中国人は i2c から画面への「アダプター」の新しいアドレスを気に入っています #endif //============================== == =============================================== ===== ==================================== void setup())( #if ( !fullVersion) // 「切り詰められた」バージョンにのみ関連 - コード セクションの先頭 pinMode(13, OUTPUT);digitalWrite(13,LOW); #endif // 「切り詰められた」バージョンにのみ関連 - コード セクションの終わりコードセクション Clock.begin(); Serial.begin(9600); #if (fullVersion) //「フル」バージョンにのみ関連 - コードセクションの始まり lcd.init(); lcd.backlight(); lcd .setCursor(0,0); lcd.print("COMport 9600 8N1"); //プログラム内で選択する COM ポート パラメータのヒント lcd.setCursor(0,1); lcd.print("Ready to sync") ; //ステータス メッセージ - 同期の準備ができました遅延(1000); #endif //「完全」バージョンにのみ関連 - コード セクションの終わり) void loop())( if (Serial.available())( / /COM ポートの「フラスコに火薬」がある場合 Serial.readBytes(b,4); // 4 バイトすべてをカウントします (他には何も期待しません) t1=b; t2=(t1<<24); //поместить значение байта в 4-байтную переменную и передвинуть его на 3 байта влево t1=b; t2+=(t1<<16); //поместить значение байта в 4-байтную переменную и передвинуть его на 2 байта влево t1=b; t2+=(t1<<8); //поместить значение байта в 4-байтную переменную и передвинуть его на 1 байт влево t2+=b; //поместить значение байта в 4-байтную переменную clock.setDateTime(t2); //установить полученное время на DS3231 #if (fullVersion) //актуально только для "полной" версии - начало участка кода lcd.clear(); lcd.setCursor(0,0); lcd.print("Done:) : :"); while (true){ //начало бесконечного цикла по отображению свежеустановленных времени и даты dat1 = clock.getDateTime(); if (dat1.day != day){ day = dat1.day; lcd.setCursor(0,1); if (dat1.day < 10) lcd.print("0"); lcd.print(day); lcd.print("-"); switch (dat1.month){ //выбираем буквенное соответствие месяца по цифре case 1:{ lcd.print("Jan"); break; } case 2:{ lcd.print("Feb"); break; } case 3:{ lcd.print("Mar"); break; } case 4:{ lcd.print("Apr"); break; } case 5:{ lcd.print("May"); break; } case 6:{ lcd.print("Jun"); break; } case 7:{ lcd.print("Jul"); break; } case 8:{ lcd.print("Aug"); break; } case 9:{ lcd.print("Sep"); break; } case 10:{ lcd.print("Oct"); break; } case 11:{ lcd.print("Nov"); break; } case 12:{ lcd.print("Dec"); break; } default:{ lcd.print("???"); break; } }//switch month lcd.print("-"); lcd.print(dat1.year); lcd.print(" "); switch(dat1.dayOfWeek){ //выбираем буквенное соответствие дня недели по цифре case 1:{ lcd.print("Mon"); break; } case 2:{ lcd.print("Tue"); break; } case 3:{ lcd.print("Wed"); break; } case 4:{ lcd.print("Thu"); break; } case 5:{ lcd.print("Fri"); break; } case 6:{ lcd.print("Sat"); break; } case 7:{ lcd.print("Sun"); break; } default:{ lcd.print("???"); break; } }//switch dayOfWeek }//if date changed lcd.setCursor(8,0); if (dat1.hour < 10) lcd.print("0"); lcd.print(dat1.hour); lcd.setCursor(11,0); if (dat1.minute < 10) lcd.print("0"); lcd.print(dat1.minute); lcd.setCursor(14,0); if (dat1.second < 10) lcd.print("0"); lcd.print(dat1.second); delay(995); }//while #else //актуально только для "урезанной" версии - начало участка кода digitalWrite(13, HIGH); delay(3000); digitalWrite(13, LOW); #endif //актуально только для "полной" версии - конец участка кода }//if Serial }//loop


完成したデバイスの「フル」バージョンの写真を数枚。


そして最後に、「戦闘中」に動作するデバイスのビデオをご覧ください。

スケッチとプログラムはどこでダウンロードできますか?

スケッチをダウンロード(Dropbox)します。
Windows 用プログラムをダウンロードします (Dropbox)。

"長所と短所"。

この場合、「メリット」と「デメリット」を明確にするのは困難です。 したがって、誰もが自分自身で何が良くて何が悪いかを決定します。

合計。

時間がモジュールで設定されるようになったのがとても気に入りました。 時間を設定する必要があるとき、必要なスケッチを毎回思い出したり、モジュールで時間がどの程度正確に設定されるかを考える必要はありません。 さらに、このような同期方法を組み込んだ自作時計のレビューも間もなく行われる予定です。私はこの方法がとても気に入りました。 読者の中にもこの方法が役に立つと思う人がいると幸いです。

このプロジェクトは無料で非営利です。 誰もが商業目的以外の目的でレビューのデータを使用する権利を有します。

ではごきげんよう。

+48を購入する予定です お気に入りに追加 レビューが気に入りました +60 +114

特徴的な機能:

  • 精度 ±2 ppm (温度範囲 0°C ~ +40°C)
  • -40°C ~ +85°C の温度範囲にわたって精度 ±3.5 ppm
  • 継続的な動作を確保するために自律型電源を接続するための入力
  • 動作温度範囲 商業用: 0°C ~ +70°C 工業用: -40°C ~ +85°C
  • 低消費電力
  • 秒、分、時間、曜日、月日、月、年をカウントするリアルタイム クロック (うるう年補正は 2100 年まで)
  • 毎日2つのアラーム
  • 周波数をプログラム可能な方形波出力
  • 高速 (400 kHz) I 2 C インターフェイス
  • 3.3V電源
  • 測定精度±3℃のデジタル温度センサー
  • 必要な調整に関するデータを含むレジスタ
  • 非RSTリセット入出力

応用:

  • サーバー
  • 電子電力メーター
  • テレマティクス機器
  • GPSシステム

DS3231 の一般的な接続図:

概要:

DS3231 は、I 2 C インターフェイス、温度補償水晶発振器 (TCXO)、および水晶発振器を内蔵した高精度リアルタイム クロック (RTC) です。 このデバイスには、バックアップ自律電源を接続するための入力があり、主電源電圧がオフになっている場合でも、計時と温度測定が可能です。 内蔵の水晶振動子により、デバイスの耐用年数が長くなり、必要な外付け要素の数が減ります。 DS3231 は商業用および工業用温度バージョンがあり、300 mil 16 ピン SO パッケージにパッケージされています。

RTC は、秒、分、時間、曜日、月の日、および年のカウントを提供します。 月の終了日は閏年を考慮して自動的に決定されます。 リアルタイム クロックは 24 時間または 12 時間形式で動作し、現在の半日 (AM/PM) を示します。 このデバイスには 2 つの毎日のアラームとプログラム可能な周波数の方形波出力が備わっています。 デバイスとのデータ交換は、内蔵のシリアルI 2 C互換インターフェイスを通じて行われます。

」。 DS3231 リアルタイム クロック モジュールについて理解しましょう。 この記事には、ビデオ手順、プログラムリスト、DSファミリーのモジュールをArduinoに接続する目的と方法が含まれています。

DS3231 リアルタイム クロック モジュール

DS3231 リアルタイム クロック モジュールとは何ですか?

リアルタイムクロックモジュール- クロノメトリックデータ(現在時刻、日付、曜日など)を記録するために設計された電子回路であり、自律電源と記録装置から構成されるシステムです。

DS3231モジュール基本的には普通の時計です。 Arduino ボードにはすでに時間センサーが組み込まれています ミリスただし、ボードに電力が供給されている場合にのみ機能します。 Arduino の電源をオフにしてからオンにすると、ミリス時間はゼロにリセットされます。 また、DS3231 にはバッテリーが搭載されており、Arduino ボードが切断されていてもモジュールに「電力」を供給し続け、時間を測定できるようになります。

このモジュールは、Arduino ボードに基づいて時計または目覚まし時計として使用できます。 または、スマートホームなどのさまざまなシステムのアラートとして。

DS3231の仕様:

  • モジュールは、時間、分、秒、日付、月、年を計算します (うるう年は 2100 年まで考慮されます)。
  • さまざまなデバイスに接続するために、クロックは I2C インターフェイスを介して接続されます。

32K— 出力は12Vを超える外部電源を供給するように設計されています。

S.Q.W.— プログラム可能な方形波信号出力。

SCL– このピンを介して、データは I2C インターフェイス経由でクロックと交換されます。

S.D.A.– 時計からのデータはこのピンを通じて送信されます。

VCC– リアルタイム クロック用の電源、5 ボルトが必要です。 このピンに電圧が供給されない場合、時計はスリープ モードに入ります。

グランド- 地球。

DS3231 リアルタイム クロックと簡単なプログラムの接続図

異なる Arduino ボード上の SDA ピンと SCL ピン:

S.D.A. SCL
ウノ A4 A5
ミニ A4 A5
ナノ A4 A5
メガ2560 20 21
レオナルド 2 3

リアルタイムクロックモジュールをArduino UNOに接続してみましょう。 SDA - ピン A4、SCL - ピン A5。

次のプログラムは、モデルが動作するのに適しています (プログラムを Arduino IDE にコピーするだけです)。

#含む

void setup() (
遅延(300);
シリアル.begin(9600);
time.begin();
}
ボイドループ()



}
}

このスケッチでは、時間が単にカウントダウンされています。

まずはsktechでライブラリを接続します iarduino_RTC.h。

ここで、正しく動作するようにモジュールの正確な名前を指定します。

その結果、DS3231 モジュールからポート モニターへの時刻出力が得られます。 時、分、秒が表示されます。

次のスケッチでは関数を追加します。 セットタイム、最初のカウントダウン時間を設定できます。

#含む
iarduino_RTC 時間(RTC_DS3231);
void setup() (
遅延(300);
シリアル.begin(9600);
time.begin();
time.settime(0,0,18,24,04,17,1); // 0 秒、0 分、18 時間、2017 年 4 月 24 日、月曜日
}
ボイドループ()
if(millis()%1000==0)( // 1秒が経過した場合
Serial.println(time.gettime("d-m-Y, H:i:s, D")); // 表示時間
遅延(1); // 1msの間に何度も時刻を表示しないように1ms一時停止します
}
}

この例では、2017 年 4 月 24 日月曜日 18 時 0 秒 0 から時間のカウントが開始されます。

レッスンの投稿:

  1. 最初のレッスン: 。
  2. 2 番目のレッスン: 。
  3. 3 番目のレッスン: 。
  4. 4 番目のレッスン: 。
  5. 5 番目のレッスン: 。
  6. レッスン 6: 。
  7. 7 番目のレッスン: 。
  8. 8 番目のレッスン: 。
  9. 9番目のレッスン:

今日も完璧なリアルタイム クロック (RTC) チップの探索を続けます。 をベースに時計を製作していきます。 ディスプレイは開発にとってより便利です。LCD ディスプレイは、設定を除くすべての情報を一度に表示します。 この形式では、時計はデスクトップ オプションとして使用すると便利です。

それでは、DS3231 チップ自体を見てみましょう。 DS3231 は、温度補償を備えた内蔵クォーツ共振器のおかげで、非常に正確な動き (メーカーがこの言葉を選びました) を備えたリアルタイム クロックです。 データ転送インターフェースは I 2 C です。この超小型回路にはバックアップ バッテリ電圧の入力もあります。主電源がオフになると、超小型回路は自動的にバックアップ バッテリからの動作に切り替わりますが、バックアップ バッテリからの動作の精度は保証されません。影響を受ける。 とても嬉しいですね。 DS3231 は、秒、分、時、日 (日付)、曜日、月、年 (月の閏年を含む) のカウントをサポートしています。 12 時間および 24 時間形式の勤務をサポートします。 設定してステータスを監視できる目覚まし時計が 2 つあります。 温度補償精度の調整。 また、32 kHz (出力は 32.768 kHz) と 1 Hz ~ 8.192 kHz のプログラム可能な出力の 2 つの出力もあります。 リセットピン - RST もあります。 リアルタイム クロック チップは SO-16 パッケージで提供されます。 ケースはかなり大きいですが、内部にクォーツが入っており、温度補償もされていることを考えると、寸法的には問題ないように思えます。 DS3231 には DS3232 の形のツインがありますが、さらに 2 つの脚があります。 これらすべては、NXP 製品である PCA2129 および PCF2129 クロック チップを非常に彷彿とさせます。 同様の温度補償内蔵水晶発振子は、どちらも n.c. の数が異なるだけで同じ双子です。 時間管理に加えて、DS3231 に関連するピンおよび同様の機能も備えています。

RTC DS3231 は、必要な配線を備えたモジュールの形で販売されており、EEPROM チップも備えていますが、これは重量が増えるだけで、ほとんどの場合必要ありません。

必要な部品に加えて、モジュール基板には LED もあり、その機能は端子への電源接続を示すことです。 おそらく美しさのために納品しただけでしょう。

このようなリアルタイム クロック チップを使用する場合に知っておくべき重要なことは、そこからデータを抽出する方法、またはそこにデータを書き込む方法です。 クロックには I 2 C インターフェイスがあり、データを書き込むには (これはデータの読み取りにも必要です)、開始条件を渡す必要があります (これらのコマンドは、ハードウェアまたはソフトウェア I 2 C を使用して実行されます)。マイクロコントローラー)、次にビットレコードを持つチップのアドレスを渡し、次にアクセスするレジスタのアドレスを渡し、次にデータのバイトをこのレジスタに転送します。その後、別のデータのバイトを転送すると、次のようになります。次のレジスタに書き込まれます。 終了したら、停止条件を渡す必要があります。 上記を図に表すと次のようになります。

初期設定時および現在時刻設定時にデータの記録が必要です。 次に、現在の日時に関するデータを常に受信する必要があります。 これを行うには、この情報を保存しているレジスタから読み取る必要があります。 読み出しは、ポインタを目的のレジスタに設定する手順と、それを読み出す手順の 2 つで構成されます。 ポインタを目的のレジスタに設定するには、開始条件を渡し、次に書き込みビットを含むチップのアドレスとレジスタ アドレスを含むバイトを渡す必要があります。 次は停止条件と開始条件、または単なる再起動のいずれかです。 2 番目のプロシージャはレジスタから直接読み取ります。 開始が送信されたら、読み取りビットでマイクロ回路のアドレスを送信し、必要な数のレジスタを読み取り、完了したら停止条件を送信する必要があります。 レジスターからの情報が読み取られた場合、マイクロコントローラー (デバイスマスター) 側で不要なアクションを行わなくても、ポインターは自動的に次のレジスターに移動します。 この図は、I 2 C インターフェイスを使用したレジスタの読み取りに関する上記のすべてを示しています。

チップアドレス:

  • 録音用 - 0b11010000
  • 読書用 - 0b11010001

C コードは次のようになります。

// クロックを使用した関数 ============================================ =============== ================================== ================== ======== // 初期設定を初期化します void RTC_init(void)( i2c_start_cond(); // i2c を開始します i2c_send_byte(RTC_adr_write); // デバイスアドレスを転送、記録モード i2c_send_byte(0x0E); // メモリアドレスを転送 i2c_send_byte(0b00100000); // 温度変換を開始し、1 Hz で出力 i2c_send_byte(0b00001000); // 32 kHz 出力を有効にする i2c_stop_cond(); // i2c を停止 ) // 時刻と日付を取得 void RTC_read_time(void)( i2c_start_cond() ; // i2c を開始 i2c_send_byte(RTC_adr_write); // デバイスアドレスを転送、書き込みモード i2c_send_byte(0x00); // メモリアドレスを転送i2c_stop_cond(); // i2c を停止 i2c_start_cond(); // i2c を開始 i2c_send_byte(RTC_adr_read); // 送信デバイスアドレス、読み取りモード sec = bcd(i2c_get_byte(0)); // 読み取り秒数、ACK min = bcd(i2c_get_byte) (0)); // 分の読み取り、ACK 時間 = bcd(i2c_get_byte(0)); // 時計の読み取り、ACK wday = bcd(i2c_get_byte(0)); // 曜日を読み取り、ACK 日 = bcd(i2c_get_byte(0)); // 数値を読み取り、ACK 月 = bcd(i2c_get_byte(0)); // 月の読み取り、ACK 年 = bcd(i2c_get_byte(1)); // 年を読み取り、NACK i2c_stop_cond(); // i2c を停止 ) // 時刻を設定 void RTC_write_time(unsigned charhour1, unsigned char min1, unsigned char sec1)( i2c_start_cond(); // i2c を開始 i2c_send_byte(RTC_adr_write); // デバイスアドレスを転送、記録モード i2c_send_byte( 0x00) ; // メモリアドレスの転送 i2c_send_byte(bin(sec1)); // 0x00秒(秒も指定したほうが良いでしょうか?) i2c_send_byte(bin(min1)); // 0x01分 i2c_send_byte(bin(hour1)) ; // 0x02 クロック i2c_stop_cond(); // i2c を停止 ) // 日付を設定 void RTC_write_date(unsigned char wday, unsigned char day, unsigned char month, unsigned char year)( i2c_start_cond(); // i2c を開始 i2c_send_byte(RTC_adr_write) ); // デバイスアドレスの転送、記録モード i2c_send_byte(0x03); // メモリアドレスの転送 i2c_send_byte(bin(wday)); // 0x03 曜日 (日曜 - 1、月 2、火 3、水 4、木 5、金 6、土 7 ) i2c_send_byte(bin(day)); // 0x04 日 月 i2c_send_byte(bin(month)); // 0x05 月 i2c_send_byte(bin(year)); // 0x06 年 i2c_stop_cond(); // i2c を停止 ) // 温度を読み取る void RTC_read_temper(void)( i2c_start_cond(); // i2c を開始 i2c_send_byte(RTC_adr_write); // デバイス アドレスを転送、書き込みモード i2c_send_byte(0x11); // メモリ アドレスを転送 i2c_stop_cond (); // i2c を停止 i2c_start_cond(); // i2c を開始 i2c_send_byte(RTC_adr_read); // デバイスアドレスを送信、読み取りモード t1 = i2c_get_byte(0); // MSB 温度を読み取る t2 = i2c_get_byte(1); // 読み取りLSB 温度 i2c_stop_cond (); // i2c を停止 t2=(t2/128); // 6 でシフト - 精度 0.25 (2 ビット) // 7 でシフト - 精度 0.5 (1 ビット) t2=t2*5; )

これは、マイクロ回路を操作するために使用されるすべてのソース コードです。クロックは数日間 1 秒も失われていなかったため、クロック速度の調整は影響を受けませんでした。

はい - 素晴らしい機能です DS3231 は、同じチップが温度計の機能 (それ以外の場合は温度補償を実行する方法) と現在の温度を読み取る機能を実行することです。 最大温度分解能は摂氏 0.25 度です。 また、温度更新周期は非常に長く、約 1 分です。 はい、急いで更新する必要はありません。

全体のクロック構造の図は次のようになります。

このマイクロコントローラーは、広く入手可能で低価格であるため、Atmega8 によって選ばれました。 このマイクロコントローラは、DIP-28 パッケージと TQFP-32 パッケージの SMD バージョンの両方で使用できます。 抵抗 R3 は、PC6 ピンにランダム ノイズが発生した場合にマイクロコントローラーが自然に再起動するのを防ぐために必要です。 抵抗 R3 はこのピンにプラスの電力を供給し、その両端に確実に電位を生成します。 表示には液晶ディスプレイ(LCD)が使用されます。 私は 2004A のディスプレイを使用しました - 20 文字の 4 行がより美しく、より親しみのある表示 - 16 文字の 2 行を使用できます。 LCD ディスプレイは 4 ビット システムを使用してマイクロコントローラーに接続されます。 可変抵抗器R2は、ディスプレイの文字のコントラストを調整するために必要です。 この抵抗器のスライダーを回転させると、画面上で最も明確な読み取り値が得られます。 LCD ディスプレイのバックライトは、ディスプレイ ボードのピン「A」および「K」によって構成されます。 バックライトは、電流制限抵抗 R1 を介してオンになります。 値が大きいほど、ディスプレイのバックライトが暗くなります。 ただし、バックライトへの損傷を避けるために、この抵抗を無視しないでください。 ボタン S1 ~ S4 は時計設定を制御します。 LED はアラームが鳴ったことを示します。 LED をある種のサウンド回路に置き換えることもできます。 抵抗 R5 ~ R8 はプルアップされており、クロック チップの端子で方形パルスを形成するために必要です。 これは、I2C プロトコルが正しく動作するためにも必要です。 回路に電力を供給するには、リニア スタビライザ チップ L7805 が使用されます。これは、5 ボルトのリニア スタビライザ KR142EN5A の国産アナログと置き換えることも、回路内の接続に応じて別の電圧スタビライザ チップを使用することもできます (たとえば、 LM317 またはスイッチング スタビライザー LM2576、LM2596、MC34063 など)。 次に、5 ボルトは別のマイクロ回路、つまり 3.3 ボルトの出力を与えるバージョンの AMS1117 によって安定化されます。 データシートによると、クロック チップは 3.3 ボルトの電圧で駆動されます。 ただし、最大電圧は 5.5 ボルトです。 したがって、このスタビライザーを使用するかどうかはあなたの裁量で決定できます。 AMS1117 電圧スタビライザは、ADJ バージョン (AMS1117ADJ) に置き換えることもできます。つまり、調整可能なバージョンです。この選択で必要な電圧を設定する必要があります。データシートに従って超小型回路に接続された 2 つの抵抗を使用します。

回路は、ATmega8 マイクロコントローラー用の開発ボードを使用して組み立てられ、デバッグされました。

ボタンの目的:

  • S1 - アラーム信号をオフにするか、設定メニューからメイン メニューに戻ります。
  • S2- マイクロコントローラーのリセット
  • S3 - 設定メニューで時刻または日付を変更します
  • S4 - 設定メニューに入り、メニューをスクロールします。

32 kHz ピンはクリスタル周波数の制御に使用できます。 周波数メーターまたはオシロスコープをこのピンに接続し、周波数を制御します。

オシログラムのスクリーンショットからわかるように、周波数は約 32.768 kHz に対応します (周波数測定の分解能の限界によるものであり、「目で」それほど正確に判断することは困難です)。

その結果、次のような特徴を持つ時計が完成しました。

  • 時間表示
  • 日付表示
  • 曜日表示
  • 目覚まし時計のアクティビティ表示
  • マイクロコントローラーからの信号出力付き目覚まし時計 1 台
  • 周囲温度の表示 (ソフトウェアでは正の温度のみが実装されています。負の温度は役に立たないと思います)
  • アラーム設定
  • 時間設定
  • 日付設定
  • バックライト付きLCDディスプレイ
  • 設定を保存し、主電源がオフになっても時計を継続する

要約しましょう。 DS3231 リアルタイム クロック チップは優れたソリューションです。 精度は一部の DS1307 以上に匹敵しますが、PCA/PCF2129 もそれと競合できます。 私がレビューしたリアルタイム クロック チップの中で、このインスタンスは現在、機能と精度の点で第一位にランクされています。

Atmega8 マイクロコントローラーをプログラムするには、ヒューズ ビットの構成を知る必要があります (プログラムで取得したスクリーンショット)。

この記事には、Atmega8マイクロコントローラーのファームウェア、プログラム内の回路設計、時計の動作のビデオが添付されています(最初にアラームが鳴り、LEDが点灯します)。

放射性元素のリスト

指定 タイプ 宗派 注記私のメモ帳
IC1 MK AVR 8ビット

ATメガ8

1 メモ帳へ
IC2 リアルタイムクロック (RTC)

DS3231

1 メモ帳へ
VR1 リニアレギュレータ

L7805AB

1 メモ帳へ
VR2 リニアレギュレータ

AMS1117-3.3

1 メモ帳へ
VD1 整流ダイオード

1N4148

1 メモ帳へ
C1 470μF1 メモ帳へ
C2、C3、C5、C7 コンデンサ100nF4 メモ帳へ
C4 電解コンデンサ220μF1 メモ帳へ
C6、C8 電解コンデンサ10μF2 メモ帳へ
R1 抵抗器

22オーム

1 メモ帳へ
R2 トリマ抵抗器10キロオーム1 3296W-1-103LF
トピックの続き:
ルーター

こんにちは、iklife.ru ブログの読者の皆さん! この記事では、より多くの人が注目するように Instagram プロフィールをデザインする方法について説明します。 正しい...