電子さいころ
いままで確認してきたことを元にして電子さいころを作ります。回路は前回作りました回路を使用してソフトを作ります。
1.回路図
回路図
・回路への電源は今回は電池から供給します。
・単3電池2本(=3V)または単3ニッケル水素電池2本(=2.4V)を使用します。
2.組立図
部品表
名称 |
仕様 |
数量 |
マイコン |
ATmega328 |
1 |
LED |
φ3、緑色 |
6 |
抵抗 |
200Ω 1/4W |
6 |
抵抗 |
10kΩ 1/4W |
1 |
抵抗 |
100kΩ 1/4W |
1 |
タクトスイッチ |
|
1 |
ブレッドボード |
|
1 |
ブレットボード用ジャンパ線 |
|
1 |
電池ボックス |
単3電池2本用 |
1 |
電池 |
単3電池またはニッケル水素電池 |
1 |
組立図
3.フローチャート
フローチャート
今まで実験してきた内容でフローを作成しています。スリープモードについてはこれから説明します。電池で回路を動作させる場合、回路の消費電流を低減して電池の持ちを良くすることが行われます。ここではマイコンのみの低消費電力化を行ない回路の消費電力を削減します。
スリープモード
前項までに作ってきたプログラムにおいて、何もしていないときはwhileループ内を例えばスイッチが押されるまでは何もせずにぐるぐると回っています。何もしていないときはwheleループをぐるぐると回っているのを止めることでマイコンの消費電流を低減させることが可能となります。
このマイコンのスリープモードは、アイドルモード、ADC変換雑音低減モード、パワーダウンモード、パワーセーブモード、スタンバイモードを持っています。以下に各モードの概要を示します。今回はパワーダウンモードを使用します。スリープモード時は、マイコン内のCPUクロックおよびマイコン内の周辺回路のクロックを停止させます。、復帰は外部割り込み(今回はスイッチ)で行ないます。
スリープモード |
機能 |
アイドル |
CPU、ROMへのクロック供給停止しますが、周辺回路へのクロックは供給し続けます。
SPI、UART、TWI、コンパレータ、AD変換器、タイマ、各割り込み等は動作を継続します。 |
AD変換雑音低減 |
CPU、ROM、IOへのクロック供給を停止しますが、他へのクロックき供給し続けます。
AD変換時の雑音を低減するモードです。
SPI、UART、TWI、コンパレータ、AD変換器、タイマ、各割り込み等は動作を継続します。 |
パワーダウンモード |
クロック発信器を停止させ、クロックの供給を停止します。
外部割り込み、TWIアドレス一致割り込み、ウォッチドックは動作を継続します。 |
パワーセーブ |
パワーダウンモードと同様ですが、タイマ2は動作をすることか可能です。
外部割り込み、TWIアドレス一致割り込み、ウォッチドックは動作を継続します。 |
スタンバイモード |
外部クリスタル/セラミック振動子で動作する以外はパワーダウンモードと同様です。 |
拡張スタンバイモード |
外部クリスタル/セラミック振動子で動作する以外はパワーセーブモードと同様です。 |
4.プログラム
#include <avr/io.h>
#include <util/delay.h> // _delay_ms()を使用するためにインクルードします。
#include <avr/interrupt.h> // スイッチ割込をするためにインクルードします。
#include <avr/sleep.h> // スリープモードを使用するためにインクルードします。
#include <stdlib.h> // ランダム関数を使用するためにインクルードします。
void InitHard( void); //ポートD初期設定
// 1 2 3 4 5 6 全消灯 全点灯
char dice[] = {0x08, 0x14, 0x1c, 0x55, 0x5d, 0x77, 0x00, 0x3f};
int main(void)
{
uint8_t blink_led;
InitHard(); // ポート初期化
set_sleep_mode( SLEEP_MODE_PWR_DOWN); // スリープ:パワーダウンモード
sleep_enable();
PORTD = dice[7]; // 全点灯
while(1)
{
PCIFR |= 1 << PCIF2; // sleepする前にスイッチ割込フラグをクリアします。
sleep_enable(); // スリープ許可
sei(); // スイッチ割り込み許可
// スリープ
sleep_cpu(); // スイッチ割り込みが入るとスリープから抜けます
cli(); // 割り込み禁止
sleep_disable(); // スリープ禁止
_delay_ms(10); // チャタリング待ち
blink_led = rand() % 6; // ランダム関数を使用します。
PORTD = dice[7]; // 全点灯させます。
while( !(PIND & 0x80)); // スイッチがオフになるまで待つ
_delay_ms(10); // チャタリング待ち
PORTD = dice[blink_led]; // 結果を表示します。
}
}
void InitHard( void)
{
DDRD = (1 << PORTD6) | (1 << PORTD5) | (1 << PORTD4)
| (1 << PORTD3) |
(1 << PORTD2) | (1 << PORTD1) | (1 << PORTD0); //
portd0からportd6まで出力に設定
PORTD = 0;
PCICR = 1 << PCIE2; // ピン割込2を許可
PCMSK2 |= 1 << PCINT23; // PCINT23をマスク
}
// 割込処理
SIGNAL(PCINT2_vect) // s1割込
{
// 何もしないsleepを解除するだけ
} |
・スリープモードの設定
ヘッダファイルに記載されているように以下の順序でスリープモードにします。その際スリープから復帰する割り込みの設定も行います。
1:スリープモードを選択します。
set_sleep_mode(mode); modeは上表に示したモードのいずれかを選択します。
2:割り込みの設定をします。
3:スリープを許可します。
sleep_enable();
4:割り込みを許可します。
sei();
5:スリープに入ります。
スリープに入ると割り込みが入るまでこの場所にずっといます。
sleep_cpu();
6:スリープを禁止します。
sleep_disable();
スリープモード |
モード |
アイドルモード |
SLEEP_MODE_IDLE |
AD変換雑音低減モード |
SLEEP_MODE_ADC |
パワーダウンモード |
SLEEP_MODE_PWR_DOWN |
パワーセーブモード |
SLEEP_MODE_PWR_SAVE |
スタンバイモード |
SLEEP_MODE_MODE_STANBY |
拡張スタンバイモード |
SLEEP_MODE_EXT_STANBY |
5.プログラムの実行
初期
プログラムを転送すると最初はLEDか全部点灯します。
スイッチ押した後
LEDが点灯します。