AVRでアセンブラーの練習 2007.09.21(金)〜 LessonA_06。 PWMを利用した調光器。
著作者名: 中野 良知 作成開始: 2007.09.20(木) 更新 : 2009.08.02(日) △1 誤記訂正 intr_time→intr_time1。
目次 1. 目的 2. フローチャート 3. プログラムソースコード 4. キーワード 4.1. ランプ(RAMP)信号でAD変換 4.2. アナログ比較器 4.3. ちらつき防止 5. PWMの周波数 6. 実験結果 7. 実験回路 1. 目的 可変抵抗器でLEDの明るさを調節します。 可変抵抗器の摺動子端子の電位をランプ信号を利用してAD変換し、 得られたAD値をLED駆動用PWMの変調度設定に使用します。 2. フローチャート (main) ↓ ポートの初期化 アナログ比較器ポートデジタル入力をOFF ウォッチドック動作禁止 タイマー1オーバーフロー割込み許可 8ビット高速PWM出力に設定(OCR1A、OCR1B)(fpwm=3.9KHz) ↓ ├──┐ ↓ │ └──┘ (タイマー1割込み) ↓ ランプ用PWM変調度更新 ↓ No <ランプスタート?> ───┐ ↓yes │ 閾値検出リセット │ ↓ │ (終了) │ │ ┌──────────┘ │ No <ランプスタート領域?> ─┐ ↓Yes │ 閾値検出リセット │ ↓ │ (終了) │ │ ┌──────────┘ │ No <ランプが閾値を越えた?>──(終了) ↓Yes Yes <閾値検出セット?> ─────(終了) ↓No ランプ用PWMを LED駆動用PWMにコピー │ 閾値検出セット ↓ (終了) 3. プログラムソースコード 全角のシフト記号"<<"は半角記号に変更してください。 ;============================================================= ; タイトル : LessonA06 ; 著者 : 中野 良知 ; 作成開始 : 2007.09.19(水) 作成開始 ; 最新修正 : 2007.09.20(木) ; 動作クロック : CLOCK=1MHz。内蔵RC発振器を使用 ; 内容 : 調光器 ;============================================================= ;============================================================= ; ポートマップ ;============================================================= ; Name Pin Use ; AIN0(PB0) 12 VRレベル入力(RAMP閾値)。CMP+ ; AIN1(PB1) 13 ランプ(RAMP)信号入力。CMP- ; OC1A(PB3) 15 ランプ信号用PWM出力 ; OC1B(PB4) 16 調光用PWM出力(fpwm=1/256u=3.9KHz) ;============================================================= ; 定数定義 ;============================================================= .equ RAMP_START = 3 ; ランプ開始領域。10K:0.01UF。 ;============================================================= ; 汎用レジスターに名前を定義(変数定義) .def sreg_save = R0 ; SREG保存用 .def acc = R16 ; アキュムレーター .def ramp_det = R17 ; RAMP>VR検出。RAMP>VRなら1 ;============================================================= ; SRAM定義 ;============================================================= ; スタック .equ STACK_INIT = $00DF ; スタック初期値 .dseg ; データセグメント=SRAM .org STACK_INIT ; stack_top: .byte 1 ; 昇順で使用。ダミーの1バイトを確保 ;============================================================= ; プログラム ;============================================================= .cseg ; CODE SEGMENT ;============================================================= ; リセットスタートベクター ;============================================================= .org 0 ; リセットスタートベクタ start: rjmp main ; mainへ ;============================================================= ; タイマ1オーバーフロー割込みベクター ;============================================================= .org 5 ; タイマ/カウンタ1オバーフロベクタ rjmp intr_time1 ; intr_time1へ ;============================================================= ; メイン ;============================================================= main: // プルアップ禁止 ldi acc,(1<<PUD) ; out MCUCR,acc ; // スタックポインター初期化 ;ldi acc,high(STACK_INIT); ;out sph,acc ; スタックポインター上位設定 ldi acc,low(STACK_INIT) ; out spl,acc ; スタックポインター下位設定 // PORTB 初期化 ldi acc,$00 ; 出力データ out PORTB,acc ; PORTBの全ビットをLowに設定 ldi acc,$FC ; PORTB b0,b1=In。b2,b3,b4,b5,b6,b7=Out out DDRB,acc ; PORTB入出力方向設定 // PORTD 初期化 ldi acc,$00 ; 出力データ out PORTD,acc ; PORTDの全ビットをLowに設定 ldi acc,$7F ; PORTD全ビット出力 out DDRD,acc ; PORTD入出力方向設定 // アナログ比較器初期化 ldi acc,$03 ; out DIDR,acc ; デジタル入力禁止 // ウォッチドッグ(WD)禁止 wdr ; WDタイマリセット in acc,MCUSR ; MCUSR値を取得 andi acc,~(1<<WDRF) ; WDRF=0 out MCUSR,acc ; WD RESETフラグ(WDRF)解除 in acc,WDTCSR ; 現WDTCSR値を取得 ori acc,(1<<WDCE)|(1<<WDE) ; WDCE=WDE=1を設定 out WDTCSR,acc ; WDCEとWDEに書き込み ldi acc,$00 ; WDCE=WDE=0を設定 out WDTCSR,acc ; WD禁止 // タイマー1オーバーフロー割込み許可。256usec毎に割込み発生 in acc,TIMSK ; タイマ割込みマスクレジスタ取得 sbr acc,(1<<TOIE1) ; オーバーフロー割込み許可ビットセット out TIMSK,acc ; タイマ1 オーバーフロー割込み許可 // PWM設定。分解能8ビット。 ldi acc,(1<<COM1A1)|(1<<COM1B1)|(1<<WGM10) ; out TCCR1A,acc ; 非反転動作,8ビット高速PWM ldi acc,(1<<WGM12)|(1<<CS10) ; out TCCR1B,acc ; 8ビット高速PWM,clk/1,スタート // PWM比較レジスター設定 eor acc,acc ; out OCR1AL,acc ; ランプ信号用PWM変調度 out OCR1BL,acc ; 調光用PWM変調度 // RAMP>VR検出をリセット clr ramp_det ; sei ; 全割込み許可 loop: rjmp loop ; ;============================================================= ; タイマ1オバーフロー割込み。 PWMカウンター(TCNT1) ;============================================================= intr_time1: ; △1 in sreg_save,SREG ; ステータスを退避 push acc ; acc退避 in acc,OCR1AL ; ランプPWM変調度取得 inc acc ; ランプPWM変調度更新 out OCR1AL,acc ; ランプPWM変調度設定 brne int10 ; ランプ開始でなければ // ランプ開始 clr ramp_det ; RAMP>VR検出をリセット cbi PORTB,7 ; RAMP>VRモニターをリセット rjmp int50 int10: cpi acc,RAMP_START ; ランプ開始領域? brlo int30 ; Yes sbic ACSR,ACO ; No. RAMP>VR ? rjmp int20 ; No cpi ramp_det,1 ; RAMP>VRを検出済み? breq int50 ; Yes out OCR1BL,acc ; No. ACO=0。調光用PWM変調度設定 ldi ramp_det,1 ; RAMP>VR検出をセット sbi PORTB,7 ; RAMP>VRモニターをセット rjmp int50 ; int20: clr ramp_det ; RAMP>VR検出をリセット cbi PORTB,7 ; RAMP>VRモニターをリセット rjmp int50 ; int30: cbi PORTB,7 ; RAMP>VRモニターをリセット int50: pop acc ; acc復帰 out SREG,sreg_save ; ステータスを復帰 reti ; ;============================================================= ;============================================================= END ;============================================================= 4. キーワード 4.1. ランプ(RAMP)信号でAD変換 ランプ信号の発生にPWM(OCR1AL)を使用します。 タイマー1のオーバーフロー毎にOCR1ALの値をインクリメントすることで、 PWM信号をRCで積分した波形は鋸歯状になります。 RC積分回路 ┌───┐ ランプ用PWM信号──┤10K├─●───ランプ信号 └───┘ │ ┴ ┬ 0.01uF │ ┴ ランプ信号と閾値 →| |←65.5msec /| /| /| /| /| / | / | / | / | / | −/−|−/−|−/−|−/−|−/−|− ←閾値(VRの電圧) / | / | / | / | / | / |/ |/ |/ |/ | ↑ └ ランプ信号が閾値に達した時のPMW変調度がAD変換値です。 ランプ信号が閾値に達したときのランプ用PWMの変調度はVRの位置に対応します。 VRのMINからMAXの範囲を、255等分の分解能でAD変換します。 ランプ信号の繰返しは、 TCNT1が8ビット、カウントパルス周期が1usec、PWMが8ビットで 256*1usec*256=65.5msecです。 タイマー1のオーバーフロー割込み毎に、ランプ信号の閾値越えの判定(AD変換)を行い ます。 4.2. アナログ比較器 アナログ比較入力のPB0(+AIN0)にVRの摺動子端子電圧(閾値)を、 PB1(-AIN1)にランプ信号を接続します。 /| /| /| /| /| / | / | / | / | / | −/−|−/−|−/−|−/−|−/−|− ←閾値(VRの電圧) PB0(+AIN) / | / | / | / | / | / |/ |/ |/ |/ | ←ランプ信号 PB1(-AIN) ─┐ ┌┐ ┌┐ ┌┐ ┌┐ ┌ ACO └─┘└─┘└─┘└─┘└─┘ ↓ ↓ ↓ ↓ ↓ IOレジスターACSRのACOビットが立下った時のランプ用PWM変調度(OCR1AL)がAD変換 値です。 このAD値をLED駆動用PWM(OCR1BL)に設定します。 4.3. ちらつき防止 ランプ信号の立下りが完了するまでには、計算値で0.77msec掛かります。 これは、PWM変調度設定用レジスターOCR1ALの値が0から3になるまでの時間に相当し ます。 この値は、RC積分回路の放電時定数で変わります。 立下り期間中にランプ信号が閾値と交差するとLEDがちらつく為、 OCR1ALが0から3の期間は、ランプ信号と閾値のアナログ比較を禁止することで、LEDの ちらつきを防止します。 /| /| /| /| /| / | / | / | / | / | −/−|−/−|−/−|−/−|−/−|− ←閾値(VRの電圧) PB0(+AIN) / | / | / | / | / | / |/ |/ |/ |/ | ←ランプ信号 PB1(-AIN) →||← 比較禁止期間(AD変換禁止) 上:[RAMP>VR]モニター出力。 下:ランプ立下り波形。 比較禁止期間の実測値は0.744msecです。 可変抵抗器位置がMINの時の[RAMP>VR]モニター出力がLowの期間を測定。 5. PWMの周波数 fOCnxPWM=fclk_I/O÷(N×(1+TOP))=3906.25Hz fclk_I/O=1MHz N=1(前置分周比) TOP=255(8ビットカウンタ) 6. 実験結果 LED駆動用PWMの変調度範囲とLED平均電流 VR位置 変調度 LED平均電流 -------+--------+------------- MIN 1.5% 0.20mA MAX 100% 13.27mA 7. 実験回路 ATtiny2313 ┌────┐20 │ VCC├───●──●──────●────●──── +5V │ │ │ R1│ C2│0.1u │ C3 │ │ │ R10K C1 ┴ /50V │┴│100u/16V │ │1 │ │ 0.1u/50V ┬ └┬┘ │ -RESET├──────●─┤├───●────●──── 0V(GND) │ │ │ │ │ │12┌─┴─┐ │ │AIN0 PB0├─┤ 10K │VR1 │ │ │ └─┬─┘ │ │ │ └─────────● │ │13 │ │AIN1 PB1├──────┐ │ │ │ │ C4 │ │ │15 R2 │ 0.01u/25 │ │OC1A PB3├──R10K──●──┤├──● │ │ │ │ │16 R3 ┌─┬┐LED │ │OC1B PB4├──R220─┤>│├────● │ │ └─┴┘ │ │ │10 │ │ GND├─────────────● └────┘ │ ┴ GND C2(0.1u/50V)は、VCCとGNDの近くに接続します。
LessonAのTopへ
サイトのTopへ
法律条項 この資料により生じたいかなる障害や損害に対し、著者は全てを免責されるものとします。 この資料は、著作権法の下で保護され、入手先、著者、日付、法律条項を含んだ場合にのみ複製が可能です。
inserted by FC2 system