AVRでPWMを使う

AVR(ATtiny2313)の高速PWMを使い、約38kHzの波形をオシロスコープで観察した。

PD5 (OC0B)から波形が出力される。

プログラム

.include "tn2313def.inc"

.cseg
.org 0
    rjmp setup

setup:
    ldi  r16,1<<DDD5
    out  DDRD,r16
    ldi  r16,(1<<COM0B1)|(1<<WGM01)|(1<<WGM00)
    out  TCCR0A,r16
    ldi  r16,(1<<WGM02)|(1<<CS00)
    out  TCCR0B,r16
    ldi  r16,25
    out  OCR0A,r16
    ldi  r16,8
    out  OCR0B,r16
loop:
    rjmp loop

レジスタ

  • TCCR0x...タイマ/カウンタ0制御レジスタ

  • OCR0x...タイマ/カウンタ0比較レジスタ

  • FOC0x...非PWM動作の時だけ有効。1で比較一致が強制される

name\bit 7 6 5 4 3 2 1 0
TCCR0A COM0A1 COM0A0 COM0B1 COM0B0 - - WGM01 WGM00
TCCR0B FOC0A FOC0B - - WGM02 CS02 CS01 CS00
COM0A1 COM0A0 動作
0 0 標準ポート
COM0B1 COM0B0 動作
1 0 比較一致でLow、0でHigh
WGM02 WGM01 WGM00 動作
1 1 1 高速PWM(TOP=OCR0A)
CS02 CS01 CS00 動作
0 0 1 clk

メモ

OCR0Aで周波数(=38kHz)、OCR0BでDuty(=9/26≒1/3)を決めている。

clk=1MHz、出力したい周波数は38kHzなので、OCR0A=1M/38k≒26。

TCNT0はOCR0Aを通過すると0からカウントするため、実際の値から1を引いてOCR0A=25(0~25=26カウント)となる。