MEGA pwm pin9,10 - 20Khz

Тема в разделе "Arduino & Shields", создана пользователем debager, 13 сен 2017.

  1. debager

    debager Нерд

    Имется MEGA + мотор шилд
    помогите модифицировать библиотеку управления .
    Конкретно надо заставит выдавать шим 20кгц на pin 9,10
    в библиотеке это сделано для pin 3,5
    Исходники:

    Код (C++):
    #include "DualVNH5019MotorShieldMega.h"

    // Constructors ////////////////////////////////////////////////////////////////

    DualVNH5019MotorShield::DualVNH5019MotorShield()
    {
      //Pin map
      _INA1 = 2;
      _INB1 = 4;
      _EN1DIAG1 = 6;
      _CS1 = A0;
      _INA2 = 7;
      _INB2 = 8;
      _EN2DIAG2 = 5;
      _CS2 = A1;
    }

    DualVNH5019MotorShield::DualVNH5019MotorShield(unsigned char INA1, unsigned char INB1, unsigned char EN1DIAG1, unsigned char CS1,
                                                   unsigned char INA2, unsigned char INB2, unsigned char EN2DIAG2, unsigned char CS2)
    {
      //Pin map
      //PWM1 and PWM2 cannot be remapped because the library assumes PWM is on timer1
      _INA1 = INA1;
      _INB1 = INB1;
      _EN1DIAG1 = EN1DIAG1;
      _CS1 = CS1;
      _INA2 = INA2;
      _INB2 = INB2;
      _EN2DIAG2 = EN2DIAG2;
      _CS2 = CS2;
    }

    // Public Methods //////////////////////////////////////////////////////////////
    void DualVNH5019MotorShield::init()
    {
    // Define pinMode for the pins and set the frequency for timer1.

      pinMode(_INA1,OUTPUT);
      pinMode(_INB1,OUTPUT);
      pinMode(_PWM1,OUTPUT);
      pinMode(_EN1DIAG1,INPUT);
      pinMode(_CS1,INPUT);
      pinMode(_INA2,OUTPUT);
      pinMode(_INB2,OUTPUT);
      pinMode(_PWM2,OUTPUT);
      pinMode(_EN2DIAG2,INPUT);
      pinMode(_CS2,INPUT);
      #if defined(__AVR_ATmega168__)|| defined(__AVR_ATmega328P__)
      // Timer 1 configuration
      // prescaler: clockI/O / 1
      // outputs enabled
      // phase-correct PWM
      // top of 400
      //
      // PWM frequency calculation
      // 16MHz / 1 (prescaler) / 2 (phase-correct) / 400 (top) = 20kHz
      TCCR1A = 0b10100000;
      TCCR1B = 0b00010001;
      ICR1 = 400;
      #endif
      #if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
      // Mega board specific stuff here - assumes assigning timer3, using pins 3 &5
      TCCR1A = 0b10100000; // Mega pin 5
      TCCR1B = 0b00010001; // Mega pin 3
      ICR1 = 400; // defined=400
      #endif
    }
    // Set speed for motor 1, speed is a number betwenn -400 and 400
    void DualVNH5019MotorShield::setM1Speed(int speed)
    {
      unsigned char reverse = 0;
     
      if (speed < 0)
      {
        speed = -speed;  // Make speed a positive quantity
        reverse = 1;  // Preserve the direction
      }
      if (speed > 400)  // Max PWM dutycycle
        speed = 400;
      #if defined(__AVR_ATmega168__)|| defined(__AVR_ATmega328P__)
      OCR1A = speed;
      #elif defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
      // Mega board specific stuff here - assumes assigning timer3, using pins 3 &5
      OCR1A = speed;
      #else
      analogWrite(_PWM1,speed * 51 / 80); // default to using analogWrite, mapping 400 to 255
      #endif
      if (reverse)
      {
        digitalWrite(_INA1,LOW);
        digitalWrite(_INB1,HIGH);
      }
      else
      {
        digitalWrite(_INA1,HIGH);
        digitalWrite(_INB1,LOW);
      }
    }

    // Set speed for motor 2, speed is a number betwenn -400 and 400
    void DualVNH5019MotorShield::setM2Speed(int speed)
    {
      unsigned char reverse = 0;
     
      if (speed < 0)
      {
        speed = -speed;  // make speed a positive quantity
        reverse = 1;  // preserve the direction
      }
      if (speed > 400)  // Max
        speed = 400;
      #if defined(__AVR_ATmega168__)|| defined(__AVR_ATmega328P__)
      OCR1B = speed;
      #elif defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
      // Mega board specific stuff here - assumes assigning timer3, using pins 3 &5
      OCR1B = speed;
      #else
      analogWrite(_PWM2,speed * 51 / 80); // default to using analogWrite, mapping 400 to 255
      #endif
      if (reverse)
      {
        digitalWrite(_INA2,LOW);
        digitalWrite(_INB2,HIGH);
      }
      else
      {
        digitalWrite(_INA2,HIGH);
        digitalWrite(_INB2,LOW);
      }
    }

    // Set speed for motor 1 and 2
    void DualVNH5019MotorShield::setSpeeds(int m1Speed, int m2Speed)
    {
      setM1Speed(m1Speed);
      setM2Speed(m2Speed);
    }

    // Brake motor 1, brake is a number between 0 and 400
    void DualVNH5019MotorShield::setM1Brake(int brake)
    {
      // normalize brake
      if (brake < 0)
      {
        brake = -brake;
      }
      if (brake > 400)  // Max brake
        brake = 400;
      digitalWrite(_INA1, LOW);
      digitalWrite(_INB1, LOW);
      #if defined(__AVR_ATmega168__)|| defined(__AVR_ATmega328P__)
      OCR1A = brake;
      #elif defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
      // Mega board specific stuff here - assumes assigning timer3, using pins 3 &5
      OCR1A = brake;
      #else
      analogWrite(_PWM1,brake * 51 / 80); // default to using analogWrite, mapping 400 to 255
      #endif
    }

    // Brake motor 2, brake is a number between 0 and 400
    void DualVNH5019MotorShield::setM2Brake(int brake)
    {
      // normalize brake
      if (brake < 0)
      {
        brake = -brake;
      }
      if (brake > 400)  // Max brake
        brake = 400;
      digitalWrite(_INA2, LOW);
      digitalWrite(_INB2, LOW);
      #if defined(__AVR_ATmega168__)|| defined(__AVR_ATmega328P__)
      OCR1B = brake;
      #elif defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
      // Mega board specific stuff here - assumes assigning timer3, using pins 3 &5
      OCR1B = brake;
      #else
      analogWrite(_PWM2,brake * 51 / 80); // default to using analogWrite, mapping 400 to 255
      #endif
    }

    // Brake motor 1 and 2, brake is a number between 0 and 400
    void DualVNH5019MotorShield::setBrakes(int m1Brake, int m2Brake)
    {
      setM1Brake(m1Brake);
      setM2Brake(m2Brake);
    }

    // Return motor 1 current value in milliamps.
    unsigned int DualVNH5019MotorShield::getM1CurrentMilliamps()
    {
      // 5V / 1024 ADC counts / 144 mV per A = 34 mA per count
      return analogRead(_CS1) * 34;
    }

    // Return motor 2 current value in milliamps.
    unsigned int DualVNH5019MotorShield::getM2CurrentMilliamps()
    {
      // 5V / 1024 ADC counts / 144 mV per A = 34 mA per count
      return analogRead(_CS2) * 34;
    }

    // Return error status for motor 1
    unsigned char DualVNH5019MotorShield::getM1Fault()
    {
      return !digitalRead(_EN1DIAG1);
    }

    // Return error status for motor 2
    unsigned char DualVNH5019MotorShield::getM2Fault()
    {
      return !digitalRead(_EN2DIAG2);
    }
     
  2. ORLENOK

    ORLENOK Гик

    попробуйте строки
    OCR1B = speed;
    и
    OCR1A = speed;
    Поменять на analogWrite(9,speed *51/80);
    и
    analogWrite(10,speed *51/80);

    Ну и ещё
    OCR1A = brake;
    и
    OCR1B = brake;
    по такому же прицыпу.

    Вообще практически вся библиотека построена на работе с регистрами. Поэтому не знаю, можно ли просто заменить код. Возможно код выполнится один раз и всё.

    Не знаю, как тут относятся к ссылкам на сторонние ресурсы, если что извеняйте.
    http://arduino.ru/forum/programmirovanie/etyudy-dlya-nachinayushchikh-blink-i-bez-delay-i-bez-millis
     
    Последнее редактирование: 16 сен 2017
  3. debager

    debager Нерд

    Cпасибо за помощь я решил проблему через назад
    но 7KHz плучил.