;---------------------------------------------------------------------------- ; ledtest2.asm for tiny15L ; 内部発振(1.6MHz)によるLED点滅テスト(0.5秒点灯0.5秒消灯の繰り返し) ;---------------------------------------------------------------------------- .include "c:\avrtools\appnotes\tn15def.inc" .def temp =r16 ;r0からr31までが汎用レジスタ .def cnt1 =r17 ;ただしr0からr15までは、sbci, subi, cpi, andi, ori, ldi命令が使えない .def cnt2 =r18 ;r16からr31までのレジスタはすべての命令が使える .def cnt3 =r19 .def cnt4 =r20 .org 0 rjmp reset ;パワーオンリセット ;rjmp(Relative Jump) (2steps) ;rjmp k 現在のプログラムカウンタ(PC)の示す値にk+1を加えて ;その位置に制御を渡す。kは相対バイト数を示し、通常ラベルを記述 ;PICの記述では下記のようになる ;goto reset reti ;外部割り込み未使用 ;reti(Return from Interrupt) (4steps) reti ;I/Oピンレベル変化未使用 reti ;タイマー/カウンタ1比較A一致未使用 reti ;タイマー/カウンタ1オーバーフロー未使用 reti ;タイマー/カウンタ0オーバーフロー未使用 reti ;EEPROM操作可未使用 reti ;アナログコンパレータ出力遷移未使用 reti ;A/D変換完了未使用 reset: ;--------------------------------------------------------------------------------- ; tiny15Lは内部発振回路の周波数校正値がEEPROMの最終番地($3F)に記録されている ; この値を読み出してOSCCALレジスタにセットしないと正確な発振周波数にならない ;--------------------------------------------------------------------------------- ldi temp,$3F ;EEPROM $3F番地を指定(周波数校正値格納場所) ;ldi(Load Immediate) (1step) ;指定したレジスタへ定数を格納 ;PIC命令ではwレジスタを介して下記のように記述する ;movlw 0x3F ;movwf temp out EEAR,temp ;EEAR(EEPROM Address Register) ;out(Store Register to I/O Location (Out Port)) (1step) ;指定したレジスタの内容を、指定したI/Oレジスタへ出力 sbi EECR,EERE ;EECR(EEPROM Control Register), EERE(EEPROM Read Enable) (2steps) ;EECRに読み出しモードを設定 ;sbi(Set Bit in I/O Register) ;指定したレジスタの指定したビットをセット in temp,EEDR ;EEDR(EEPROM Data Register) ;in(Load an I/O Location to Register (In Port)) (1step) out OSCCAL,temp ;周波数校正値を OSCCAL レジスタにセット ;PIC12F629ではwレジスタを介して下記のように記述する ;movf temp,w ;movwf OSCCAL ;------------------------------- ldi temp,$1f ;temp=0b00011111 out DDRB,temp ;PB0,PB1,PB2,PB3,PB4を出力に設定 loop: ldi temp,$1f ;temp=0b00011111 out PORTB,temp ;PB0,PB1,PB2,PB3,PB4 ON rcall timer ;rcall(Relative Subroutine Call) (3steps) PIC命令のcallと同じ ldi temp,$00 ;temp=0b00000000 out PORTB, temp ;PB0,PB1,PB2,PB3,PB4 OFF rcall timer rjmp loop ;PICでのgoto命令と同じ ;------------------------------- timer: ldi cnt1,222 ;PICでの下記の記述と同じ ;movlw d'255' ;movwf cnt1 tmlp1: ldi cnt2,200 tmlp2: ldi cnt3,5 tmlp3: dec cnt3 brne tmlp3 dec cnt2 ;dec(Decrement) (1step) ;指定したレジスタの内容をマイナス1する ;PICでの下記の記述と同じ ;decf cnt2,f brne tmlp2 ;brne(Branch if Not Equal) (1/2step(s)) ;brne k 直前の演算結果が等しくなければ(またはゼロ)、 ;プログラムカウンタにk+1を加えた番地へ分岐 ;kの値は-64から+63の範囲になければならない dec cnt1 brne tmlp1 ldi cnt4,31 tmlp4: nop dec cnt4 brne tmlp4 ret ;ret(Return from Subroutine) (4steps) ;PIC命令の return と同じ ;PICではプログラムの終わりに end の記述が必要だが AVR では何も書かない