AVRでアセンブラーの練習 2007.09.16(日)〜 / LessonA_05。 PWMを利用して鋸歯状波を発生。
著作者名: 中野 良知 作成開始: 2007.09.15(土) 更新 : 2009.08.02(日) △1 誤記訂正 intr_time:→intr_time0:
目次 1. 目的 2. フローチャート 3. プログラムソースコード 4. キーワード 4.1. PWM 4.2. 鋸歯状波 5. 実験結果 6. 実験回路 1. 目的 PWM信号発生機能を使って、鋸歯状波信号を発生します。 2. フローチャート (main) ↓ ポートの初期化 アナログ比較器の電源OFF ウォッチドック動作禁止 タイマー0初期化。1msec毎にオーバーフロー割込み 8ビット高速PWM出力に設定 ↓ ├────────────┐ ↓ │ PWMレジスターに │ 1msecカウンター値を設定 │ ↓ │ └────────────┘ (タイマー0割込み、1msec毎) ↓ ステータスレジスター退避 ↓ acc退避 ↓ タイマー0カウンター設定 ↓ 1msecカウンターインクリメント ↓ acc復帰 ↓ ステータスレジスター復帰 ↓ (終了) 3. プログラムソースコード 全角のシフト記号"<<"は半角記号に変更してください。 ;============================================================= ; タイトル : LessonA_05 ; 著者 : 中野 良知 ; 作成開始 : 2007.09.15(土) 作成開始 ; 最新修正 : 2007.09.15(土) ; ヒューズビット : 3DF64 ; 動作クロック : CLOCK=1MHz。内蔵RC発振器を使用 ; 内容 : PB4(OC1B)に鋸歯状波発生。 ;============================================================= ; インクルード .include "tn2313def.inc" ; ;============================================================= ; 定数定義 ;============================================================= ; タイマカウント .equ T1MSEC = 256 - 125 ; CLOCK=1MHz、Pre Scale=1/8、1msec .equ PRE_SCALE = $02 ; 1/8。タイマスタート ;============================================================= ; 汎用レジスターに名前を定義(変数定義) .def sreg_save = R0 ; SREG保存用 .def acc = R16 ; アキュムレーター .def t1ms = R17 ; 1msecタイマカウンタ ;============================================================= ; SRAM定義 ;============================================================= ; スタック .equ STACK_INIT = $00DF ; スタック初期値 .dseg ; データセグメント=SRAM .org STACK_INIT ; stack_top: .byte 1 ; 昇順で使用。ダミーの1バイトを確保 ;============================================================= ; プログラム ;============================================================= .cseg ; CODE SEGMENT ;============================================================= ; リセットスタートベクター ;============================================================= .org 0 ; リセットスタートベクタ start: rjmp main ; mainへ ;============================================================= ; タイマ0オーバーフロー割込みベクター ;============================================================= .org 6 ; タイマ/カウンタ0オバーフロベクタ rjmp intr_time0 ; intr_time0へ ;============================================================= ; メイン ;============================================================= main: // スタックポインター初期化 ldi acc,low(STACK_INIT) ; out spl,acc ; スタックポインター下位設定 // PORTB 初期化 ldi acc,$00 ; 出力データ out PORTB,acc ; PORTBの全ビットをLowに設定 ldi acc,$FF ; PORTB全ビット出力 out DDRB,acc ; PORTB入出力方向設定 // アナログ比較器初期化 sbi ACSR,ACD ; アナログ比較器電源オフ // ウォッチドッグ(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禁止 // Timer/Counter 0 初期化 // TCCR0A=0x00 ; 標準動作 in acc,TIMSK ; タイマ割込みマスクレジスタ取得 sbr acc,(1<<TOIE0) ; オーバーフロー割込み許可ビットセット out TIMSK,acc ; タイマ0 オーバーフロー割込み許可 ldi acc,T1MSEC ; 1msecカウント値 out TCNT0,acc ; タイマ0カウンタ設定 ldi acc,PRE_SCALE ; プリスケール値。1/8。8usec。 out TCCR0B,acc ; タイマ0スタート。プリスケール設定 // 高速PWM設定。分解能8ビット。PB4(OC1B,16pin)にPWM出力 eor acc,acc ; out OCR1BH,acc ; 比較レジスター上位設定 out OCR1BL,acc ; 比較レジスター下位設定 ldi acc,(1<<COM1B1)|(1<<WGM10) ; out TCCR1A,acc ; 非反転動作,8ビット高速PWM ldi acc,(1<<WGM12)|(1<<CS10) ; out TCCR1B,acc ; 8ビット高速PWM,clk/1,スタート clr t1ms ; 1msecカウンタ初期化 sei ; 全割込み許可 serrulation_wave: // 鋸歯状波出力(PB4,16PIN) out OCR1BL,t1ms ; 比較レジスター下位設定 rjmp serrulation_wave ; ループ ;============================================================= ; タイマ0割込み ;============================================================= intr_time0: ; △1 in sreg_save,SREG ; ステータスを退避 push acc ; acc退避 ldi acc,T1MSEC ; 1msecカウント値 out TCNT0,acc ; タイマ0カウンタ設定 inc t1ms ; 1msecカウント pop acc ; acc復帰 out SREG,sreg_save ; ステータスを復帰 reti ; ;============================================================= ;============================================================= ; END ;============================================================= 4. キーワード 4.1. PWM OCR1BLの設定値によりPWM(パルス幅変調)の変調度が変化します。 ┌┐ ┌┐ ┌┐ ┌ OCR1BL=$01 ─┘└────────┘└────────┘└──────┘ ┌────┐ ┌────┐ ┌────┐ OCR1BL=$80 ─┘ └────┘ └────┘ └─── ┌────────┐┌────────┐┌───────┐ OCR1BL=$F0 ─┘ └┘ └┘ └ │←───────→│256usec RC内部発信周波数が1MHzで1usecのクロックを分周せずにPWMカウンター(TCNT1)に供 給します。 1usecクロック ┌────────┐ ──────→┤ TCNT1 │ └┬┬┬┬┬┬┬┬┘ ││││││││ ┌┴┴┴┴┴┴┴┴┐ │ = ├─→ 一致(TOP) → PWM出力=0 └┬┬┬┬┬┬┬┬┘ ││││││││ ┌┴┴┴┴┴┴┴┴┐ │ OCR1BL │ └────────┘ TCNT1が0からカウントアップされ、 TCNT1<OCR1BLの間はPWM出力は1。 TCNT1>=OCR1BLの間はPWM出力は0です。 TCNT1は255の次に0になりPWM出力=1になり、再びカウントアップされます。 PWMの繰り返し周期は1usec×256=256usecです。 4.2. 鋸歯状波 1msecタイマー割込み毎にインクリメントするカウンターの値をOCR1BLに設定すとPWM のHレベルの幅が1msec毎に拡張し、1msecカウンターが0になると一気にPWMのHレベル の幅が無くなります。 PWM出力に接続したRC積分回路の出力は、Hの幅が増えるに従って上昇し、Hの幅が0に なると急激に降下し、鋸の歯に似た波形になります。 /| /| /| /| /| / | / | / | / | / | / | / | / | / | / | / | / | / | / | / | / |/ |/ |/ |/ | │←→│256msec 鋸歯状波の繰り返し周期は、1バイトの1msecタイマーが0からカウントアップし オーバーフローをするまでの時間です。 5. 実験結果 繰返し周期 = 252msec。 振幅 = 4.24V。 谷の部分の電圧 = 0.35V。RCの放電時定数により残留電圧が生じます。 6. 実験回路 ATtiny2313 ┌────┐20 │ VCC├──────●──────●────●──── +5V │ │ R1│ C2│0.1u │ C3 │ │ R10K C1 ┴ /50V │┴│100u/16V │ │1 │ 0.1u/50V ┬ └┬┘ │ -RESET├──────●─┤├───●────●──── 0V(GND) │ │ │ │ │10 │ │ GND├─────────────● │ │ │ │ │ │ │ │16 RC積分回路 │ │ PB4├── R470K─●──────────────── 鋸歯状波 │ │ R2 │ C4 │ │ │ ┴ 0.01u │ └────┘ ┬ /25 │ │ │ └──────● │ ┴ GND C2(0.1u/50V)は、VCCとGNDの近くに接続します。
LessonAのTopへ
サイトのTopへ
法律条項 この資料により生じたいかなる障害や損害に対し、著者は全てを免責されるものとします。 この資料は、著作権法の下で保護され、入手先、著者、日付、法律条項を含んだ場合にのみ複製が可能です。
inserted by FC2 system