DCモーター / Hブリッジで正転、反転を切り換える / Sign-Magnitudeモードで速度を制御する
p.316
回路は前回のDCモーター / Hブリッジで正転、反転を切り換える -と同じである。回転方向(Sign)と回転速度(Magnitude)とを指定する。具体的にはどちらか一方の制御ラインをHに固定して回転方向を決め、他方にpwmに印加して回転速度を決める(どちらか一方をLに固定して他方にpwmを印加するのでも同じ)。
#include <avr/io.h> #include <util/delay.h> #include "mylib.h" void initTimer0(){ TCCR0A |= (1 << COM0B1); // コンペアマッチ時にOC0B (PD5)をクリア、ボトム時にOC0B (PD5)をセット。 TCCR0A |= (1 << COM0A1); // コンペアマッチ時にOC0A (PD6)をクリア、ボトム時にOC0A (PD6)をセット。 TCCR0A |= (1 << WGM01) | (1 << WGM00); // Fast PWMモード。 setPrescaler0(256); // Timer0の分周比。0, 1, 8, 64, 256, or 1024 } void setMotorSpeed(uint8_t isForward, uint8_t speed){ // 1:forward, 0:backward; 0:stop, 255:fastest if(isForward){OCR0B = 255; OCR0A = 255 - speed;} else {OCR0A = 255; OCR0B = 255 - speed;} } int main(){ initTimer0(); DDRD |= (1 << PD5) | (1 << PD6); uint8_t direction = 1; const int DELAY = 2000; while(1){ setMotorSpeed(direction, 10) ; _delay_ms(DELAY); // ゆっくり回す。 setMotorSpeed(direction, 20) ; _delay_ms(DELAY); // 少し速く回す。 setMotorSpeed(direction, 50) ; _delay_ms(DELAY); // さらに速く回す。 setMotorSpeed(direction, 255); _delay_ms(DELAY); // 全速回転。 setMotorSpeed(direction, 0) ; _delay_ms(DELAY); // 停止する。 direction = !direction; // 回転方向を逆にして繰り返す。 } return 0; }
―――――――――――――――――
これだと引数が1つで済む:
#include <avr/io.h> #include <util/delay.h> #include "mylib.h" void initTimer0(){ TCCR0A |= (1 << COM0B1); // コンペアマッチ時にOC0B (PD5)をクリア、ボトム時にOC0B (PD5)をセット。 TCCR0A |= (1 << COM0A1); // コンペアマッチ時にOC0A (PD6)をクリア、ボトム時にOC0A (PD6)をセット。 TCCR0A |= (1 << WGM01) | (1 << WGM00); // Fast PWMモード。 setPrescaler0(256); // Timer0の分周比。0, 1, 8, 64, 256, or 1024 } void setMotorSpeed(int16_t speed){ // speed:255 ~ -255 uint8_t isForward; speed >=0 ? isForward = 1 : isForward = 0; if(isForward){OCR0B = 255; OCR0A = 255 - speed;} else {OCR0A = 255; OCR0B = 255 + speed;} } int main(){ initTimer0(); DDRD |= (1 << PD5) | (1 << PD6); int8_t direction = 1; const int DELAY = 2000; while(1){ setMotorSpeed(direction * 10) ; _delay_ms(DELAY); // ゆっくり回す。 setMotorSpeed(direction * 20) ; _delay_ms(DELAY); // 少し速く回す。 setMotorSpeed(direction * 50) ; _delay_ms(DELAY); // さらに速く回す。 setMotorSpeed(direction * 255); _delay_ms(DELAY); // 全速回転。 setMotorSpeed(0) ; _delay_ms(DELAY); // 停止する。 direction = -direction; // 回転方向を逆にして繰り返す。 } return 0; }