すんさんの掲示板でAVRのPWMの話で盛り上がっていたので興味をもちました。いまいち理解が足りないですが、とりあえずコードを書いてみました。
回路は12pin → LED(A) → LED(K) → 100Ω抵抗 → GNDです。
AVRのPWMを使って、LEDホタルです。ほわっと明るくなって、ぼわっと暗くなってを繰り返します。
AVRGCCではutil/delay.hをincludeすることで_delay_msと_delay_usという関数が使えるようになります。動作クロックはF_CPUをマクロ定義します。自分で#defineすることもできますが、AVR StudioだとProject→Configuration Optionsのfrequencyに入力してやることで指定することもできます。このとき、gccのオプションで-DF_CPU=1000000のように定数が定義されます(この場合は1MHz)。このdelayシリーズは周波数の計算とかしなくていいのでとても便利です。
PWM出力をするには、4つのレジスタを設定する必要があります。
(1) 対応するPORTを出力にする(DDRBとかDDRD)
(2) 比較レジスタの設定(OCR0A)
(3) 制御レジスタA (TCCR0A)
(4) 制御レジスタB (TCCR0B)
割り込みを使うときは、さらに色々な設定が必要です。
AVRではクロック元を、動作クロックを分周したものにできます。CS02, CS01, CS00で、停止、1/1、1/8, 1/64, 1/256, 1/1024の指定ができます。今回は1MHz動作で1/1でそのまま使っています。
今のところ分かったのはこのくらいです。あまり理解しないうちから、とりあえずコードを書いてしまいます(笑)。
回路は12pin → LED(A) → LED(K) → 100Ω抵抗 → GNDです。
AVRのPWMを使って、LEDホタルです。ほわっと明るくなって、ぼわっと暗くなってを繰り返します。
#include <avr/io.h> #include <util/delay.h> int main() { unsigned char duty = 0; char dir; // MEGA88 タイマー関連ポート // OC0A/PD6 12pin // OC0B/PD5 11pin // OC1A/PB1 15pin // OC1B/PB2 16pin // OC2A/PB3 17pin ... MOSI // OC2B/PD3 5pin DDRD = 0x40; // PD6出力 // 14.9.4 タイマ/カウンタ0 比較Aレジスタ (p.66) OCR0A = duty; // 14.9.1 タイマ/カウンタ0制御レジスタA (p.64) // ++--------COM0A1:COM0A0 10 上昇時一致でL下降時一致でH // ||++------COM0B1:COM0B0 00 OC0B切断 // |||| ++--WGM1:WGM0 01 位相基準PWM動作 TCCR0A = 0b10000001; // 14.9.2 タイマ/カウンタ0制御レジスタB (p.65) // ++--------FOC0A:FOC0B 00 // || +-----WGM2 0 TOP = 0xff // || |+++--CS02:CS01:CS00 001 clkio/1 TCCR0B = 0b00000001; // start timer while(1){ _delay_ms(4); // 4ミリ秒毎にduty比を変更 512*4で周期は2秒 if(duty == 0x00) dir = 1; if(duty == 0xff) dir = -1; duty += dir; OCR0A = duty; } }
AVRGCCではutil/delay.hをincludeすることで_delay_msと_delay_usという関数が使えるようになります。動作クロックはF_CPUをマクロ定義します。自分で#defineすることもできますが、AVR StudioだとProject→Configuration Optionsのfrequencyに入力してやることで指定することもできます。このとき、gccのオプションで-DF_CPU=1000000のように定数が定義されます(この場合は1MHz)。このdelayシリーズは周波数の計算とかしなくていいのでとても便利です。
PWM出力をするには、4つのレジスタを設定する必要があります。
(1) 対応するPORTを出力にする(DDRBとかDDRD)
(2) 比較レジスタの設定(OCR0A)
(3) 制御レジスタA (TCCR0A)
(4) 制御レジスタB (TCCR0B)
割り込みを使うときは、さらに色々な設定が必要です。
AVRではクロック元を、動作クロックを分周したものにできます。CS02, CS01, CS00で、停止、1/1、1/8, 1/64, 1/256, 1/1024の指定ができます。今回は1MHz動作で1/1でそのまま使っています。
今のところ分かったのはこのくらいです。あまり理解しないうちから、とりあえずコードを書いてしまいます(笑)。