ATMELのAT-Tiny26,ATmega,R8Cなどのワンチップマイコン,C言語,JAVAなどのプログラミング言語の入門のためのページです.サンプルプログラムを中心に紹介します.他にもLinixや数学ソフトなどの紹介も行います.

このブログを検索

あなたは 番目のお客様です.

2009年9月8日火曜日

ATmega88でRTC-8564のテスト









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()