データシート略語
PWM
CS0-CS2
http://kcnotebook.web.fc2.com/avr/timer.html
CS02 CS01 CS00
0 0 0 停止(タイマ/カウンタ動作停止)
0 0 1 Fclk(分周無し)
0 1 0 Fclk / 8(8分周)
0 1 1 Fclk / 64(64分周)
1 0 0 Fclk / 256(256分周)
1 0 1 Fclk / 1024(1024分周)
1 1 0 T0ピンの下降端 (外部クロック)
1 1 1 T0ピンの上昇端 (外部クロック)
マクロ一覧
ポート
ポートB方向レジスタ DDRB (ポートAならDDRA) 0ならINPUT 1ならOUTPUT
ポートB出力レジスタ PORTB (ポートAならPORTA) OUTPUTにHigh/Lowをセット
ポートB入力レジスタ PINB (ポートAならPINA) INPUTがHigh/Lowかチェック
servo
#include <avr/wdt.h>
#define OUTPUT_PIN _BV(1)
void init_pwm() {
OCR0A = 156; // TOP value : 64us * 156 = 9984us = 10ms = 100Hz. SG92R works on 50Hz. but set 100Hz for degree subdivide.
OCR0B = 1; // H period : 256us x 10 / 2 = 128us
TCCR0A = B00100011; // COM0A: 00, COM0B: 10, WGM01-00: 11. TCCR0A(TimeCountControlRegister 0A)
//TCCR0B = B00001001; // FOC:00, WGM02:1, CS02-01: 001 (system clock x1)
TCCR0B = B00001011; // FOC:00, WGM02:1, CS02-01: 011 (system clock x64)
TCNT0 = OCR0A;// init count. if(TCNT0 == OCR0A) ic reset count and reload new OCR0A and OCR0B.
}
void set_pwm(int a) {
OCR0B = a;
}
void setup() {
cli();
DDRB = OUTPUT_PIN; // inputは0
PORTB = 0; // 他は0
ACSR |= 0x80; // アナログコンパレータ禁止
ADCSRA &= 0x7f; // disable ADC
wdt_disable();
TIMSK = 0; // disable Timer0/1 overflow interrupt.
sei();
pinMode(0, INPUT);
init_pwm();
}
void trigger_on(int a){
set_pwm(a);
}
void trigger_off(){
TCCR0A = 0;
TCCR0B = 0;
}
int wait = 100;
int count = 8 * wait; //64us x 8 = 512 us.
void loop() {
if(digitalRead(0) == LOW){
trigger_on(count/wait);
++count;
if(count > 37*wait) count = 8*wait;
}else{
trigger_off();
}
delay(1);
}