ATmega88で秋月のリアルタイムクロックモジュールRTC-8564をテストしてみました.
RTC-8564はI2C対応のクロックモジュールです.
RTC-8564にはジャンパーJP1,JP2があるので半田接続すれば,
I2Cの抵抗プルアップ2.2kが省略できます.
ATmega88は内部発振8MHzを使っています.
PC6はデフォルトではリセット端子なので注意しましょう.
秒データ0X02に読み込みの前に書き込みを行うと,VLの関係で
トラブルが生じる可能性があります.
RTC-8564のVCC-GNDには忘れず0.1μF程度のパスコンを入れましょう.
プログラムには時間待ちのためdelay()やwait()などの関数を定義して使っています.
待ち時間はいい加減です.なくてもよいかも.
以下はサンプルプログラム
(1)秒データを読み込みPBに出力しLEDで表示する
接続PC5とSCL,PC4とSDA,PB0-6にLED
#include <avr/io.h>
//マイクロ秒単位の待ち(t<256)
void delay(uint8_t t){
TCCR0B=0B00000010; //タイマカウンタ0の分周をセットCK/8
TCNT0=0;
while(TCNT0<t){}
}
int main( void )
{
DDRB=0B11111111; // PBを出力に設定する
//SCL=8MHz/(16+2*17*1)=200kHz;
TWBR=17;
TWSR=0X00;
while(1){
//s開始条件送出
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
//SLA_W,アドレス送信
TWDR=0B10100010;
TWCR = (1<<TWINT)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
//DATA,データ送信(RTC-8564のアドレス)
TWDR=0X02;//seconds
TWCR = (1<<TWINT)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
//s開始条件送出
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
//SLA_R,読み出しでアドレス送信
TWDR=0B10100011;
TWCR = (1<<TWINT)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
//データ読み込み
TWCR = (1<<TWINT)|(1<<TWEA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
//p停止条件送出
TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
PORTB=TWDR;//データをPORTBにコピー
delay(100);//100μ秒の待ち
}//while(1)
}//main()
(2)書き込みテストのためminutesの初期値を13に設定し,minutesの値を表示する.
#include <avr/io.h>
//マイクロ秒単位の待ち(t<256)
void delay(uint8_t t){
TCCR0B=0B00000010; //タイマカウンタ0の分周をセットCK/8
TCNT0=0;
while(TCNT0<t){}
}
int main( void )
{
DDRB=0B11111111; // PDを出力に設定する
//SCL=8MHz/(16+2*17*1)=200kHz;
TWBR=17;
TWSR=0X00;
//テストのためminutesの初期値を13に設定
//s開始条件送出
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
//SLA_W,アドレス送信
TWDR=0B10100010;
TWCR = (1<<TWINT)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
//DATA,データ送信(RTC-8564のアドレス)
TWDR=0X03;//minutes
TWCR = (1<<TWINT)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
//データ書き込み
TWDR=0B00010011;//13
TWCR = (1<<TWINT)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
//p停止条件送出
TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
delay(100);//100μ秒の待ち(念のためちょっと待つ)
while(1){
//s開始条件送出
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
//SLA_W,アドレス送信
TWDR=0B10100010;
TWCR = (1<<TWINT)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
//DATA,データ送信(RTC-8564のアドレス)
TWDR=0X03;//minutes
TWCR = (1<<TWINT)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
//s開始条件送出
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
//SLA_R,読み出しでアドレス送信
TWDR=0B10100011;
TWCR = (1<<TWINT)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
//データ読み込み
TWCR = (1<<TWINT)|(1<<TWEA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
//p停止条件送出
TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
PORTB=TWDR;//データをPORTBにコピー
delay(100);//100μ秒の待ち
}//while(1)
}//main()
(3)時,分の表示をPORTDのLEDで行う
PD0はMinutes Secondsの値を0にリセットする
PD1,PD2でMinutes Secondsの値をインクリメントして設定が可能
PD0-2は1-10kでGND,SWでVCCに接続する
#include <avr/io.h>
//ミリ秒単位の待ち(t<256)
void wait(uint8_t t){
uint8_t i;
TCCR0B=0B00000011; //タイマカウンタ0の分周をセットCK/64(8Us)
for(i=0;i*2<t;i++){
TCNT0=0;
while(TCNT0<250){}
}
}
void write(uint8_t a,uint8_t d){
//s開始条件送出
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
//SLA_W,アドレス送信
TWDR=0B10100010;
TWCR = (1<<TWINT)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
//DATA,データ送信(RTC-8564のアドレス)
TWDR=a;
TWCR = (1<<TWINT)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
//データ書き込み
TWDR=d;
TWCR = (1<<TWINT)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
//p停止条件送出
TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
}
uint8_t read(uint8_t a){
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
//SLA_W,アドレス送信
TWDR=0B10100010;
TWCR = (1<<TWINT)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
//DATA,データ送信(RTC-8564のアドレス)
TWDR=a;
TWCR = (1<<TWINT)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
//s開始条件送出
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
//SLA_R,読み出しでアドレス送信
TWDR=0B10100011;
TWCR = (1<<TWINT)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
//データ読み込み
TWCR = (1<<TWINT)|(1<<TWEA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
//p停止条件送出
TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
return TWDR;
}
void inc(uint8_t a){
uint8_t x;
x=read(a);
//インクリメントして,下位が10なら下位をクリアして,上位をインクリメント
x++;
if((x&0B00001111)==10)x=(x&0B11110000)+0B00010000;
write(a,x);
}
int main( void )
{
uint8_t x;
DDRB=0B11111111; // PBを出力に設定する
DDRD=0B00000000; // PDを入力に設定する
TWBR=17;//SCL=8MHz/(16+2*17*1)=200kHz;
TWSR=0X00;
while(1){
if(PIND & 0B00000001){
write(0X03,0X00);
write(0X04,0X00);}//PD0HighでMHリセット
if(PIND & 0B00000010)inc(0X03);//PD1HighでMinutes++
if(PIND & 0B00000100)inc(0X04);//PD2HighでHours++
x=read(0X04);//Hours
PORTB=x;//データをPORTBにコピー
wait(200);//msの待ち
wait(200);//msの待ち
wait(200);//msの待ち
wait(200);//msの待ち
PORTB=0X00;//LEDクリア
wait(200);//msの待ち
x=read(0X03);//Minutes
PORTB=x;//データをPORTBにコピー
wait(200);//msの待ち
PORTB=0X00;//LEDクリア
wait(200);//msの待ち
}//while(1)
}//main()
ATMELのAT-Tiny26,ATmega,R8Cなどのワンチップマイコン,C言語,JAVAなどのプログラミング言語の入門のためのページです.サンプルプログラムを中心に紹介します.他にもLinixや数学ソフトなどの紹介も行います.
このブログを検索
内容
Visual C++ Express Editionを用いたプログラミングメモ
Windows版 Mathematicaの使い方
MATLABとOctaveを使う
Fedora,Vine,Debian,KnoppixでLinux一本勝負?
CygwinやMinGWでCプログラミングを行う
C言語のプログラミング入門
R8Cで液晶SC1602BSの表示を行う
マイコンと2進数
R8CTinyマイコンの最初の一歩(Cプログラミング)
R8C/TinyシリーズのリセットとIDコードチェック機能
R8CTinyでCOMポートの通信実験
CT-208でR8CTinyの実行(アセンブラ)
R8C/Tiny29(サンハヤトのMB-8C29)の評価
サウンドファイルwavを開く
よく使うATMELのマイコンのアセンブラの比較
ATMELのATTiny26入門
Tiny26で液晶SC1602BSの表示を行う
AD変換の結果を液晶に表示する
マイコンによる電子オルゴール
Tiny2313でパルスの分周とカウンタ
Tiny2313でシリアル通信とROMリーダ
Tiny2313でGPSデータを液晶に表示
加速度センサを使う
マイコンでI2C-EEPROMの読み書きを行う
TINY13,TINY25,2313などの8ピンマイコンを使う
PSOCマイコンスタートアップ
AF,FMラジオ
Windows版 Mathematicaの使い方
MATLABとOctaveを使う
Fedora,Vine,Debian,KnoppixでLinux一本勝負?
CygwinやMinGWでCプログラミングを行う
C言語のプログラミング入門
R8Cで液晶SC1602BSの表示を行う
マイコンと2進数
R8CTinyマイコンの最初の一歩(Cプログラミング)
R8C/TinyシリーズのリセットとIDコードチェック機能
R8CTinyでCOMポートの通信実験
CT-208でR8CTinyの実行(アセンブラ)
R8C/Tiny29(サンハヤトのMB-8C29)の評価
サウンドファイルwavを開く
よく使うATMELのマイコンのアセンブラの比較
ATMELのATTiny26入門
Tiny26で液晶SC1602BSの表示を行う
AD変換の結果を液晶に表示する
マイコンによる電子オルゴール
Tiny2313でパルスの分周とカウンタ
Tiny2313でシリアル通信とROMリーダ
Tiny2313でGPSデータを液晶に表示
加速度センサを使う
マイコンでI2C-EEPROMの読み書きを行う
TINY13,TINY25,2313などの8ピンマイコンを使う
PSOCマイコンスタートアップ
AF,FMラジオ
2009年9月8日火曜日
ATmega88でRTC-8564のテスト
登録:
投稿 (Atom)