DCモーター / Hブリッジで正転、反転を切り換える / Sign-Magnitudeモードで速度を制御する

p.316
回路は前回のDCモーター / Hブリッジで正転、反転を切り換える -と同じである。回転方向(Sign)と回転速度(Magnitude)とを指定する。具体的にはどちらか一方の制御ラインをHに固定して回転方向を決め、他方にpwmに印加して回転速度を決める(どちらか一方をLに固定して他方にpwmを印加するのでも同じ)。
f:id:ti-nspire:20191114170007p:plain:h250

#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;
}