使用定时器中断移动BLDC电机

时间:2017-04-28 04:26:02

标签: arduino

我想用定时器中断移动我的BLDC电机。不知何故,电机根本不会旋转。我希望电机根据代码中设置的RPM旋转。我想知道你们是否可以指出我的错误。这是代码:

#include <Wire.h>  // Comes with Arduin


#define POSITIVE 1
int timerPin = 11;
int timer1_counter;
int prescaler;

// STATE CONDITION FOR MAIN LOOP
enum { enter_values, spin , finish } systemstate;
unsigned long previousMillis = 0;


// RPM MEASUREMENT
const int dataIN = 2; //IR sensor INPUT

unsigned long prevmillis; // To store time
unsigned long duration; // To store time difference
unsigned long lcdrefresh; // To store time for lcd to refresh
int rpm; // RPM value

boolean currentstate; // Current state of IR input scan
boolean prevstate; // State of IR sensor in previous scan

// DECLARE
int stage1speed , stage1time , stage2speed , stage2time , stage3speed , stage3time ;

void setup()
{
  Serial.begin(9600);
  systemstate = enter_values;  // set up the starting state
  pinMode(dataIN, INPUT);
  prevmillis = 0;
  prevstate = LOW;

  pinMode (timerPin, OUTPUT);
  //rmc timer interrupt
  // initialize timer1 
  noInterrupts();           // disable all interrupts
  TCCR1A = 0;
  TCCR1B = 0;

  // Set timer1_counter to the correct value for our interrupt interval
  //timer1_counter = 64911;   // preload timer 65536-16MHz/256/100Hz
  //timer1_counter = 64286;   // preload timer 65536-16MHz/256/50Hz
  //timer1_counter = 34286;   // preload timer 65536-16MHz/256/2Hz

  timer1_counter = 65536 - F_CPU/256/2;

  prescaler = 8;

  TCNT1 = timer1_counter;   // preload timer
  TCCR1B |= (1 << CS11) | (0 << CS10);    // prescaler 
  TIMSK1 |= (1 << TOIE1);   // enable timer overflow interrupt
  interrupts();             // enable all interrupts
}

ISR(TIMER1_OVF_vect)        // interrupt service routine 
{
  static byte outp = 0;

  TCNT1 = timer1_counter;   // preload timer
  digitalWrite(timerPin, outp);
  outp = 1-outp;
}


//FUNCTION FOR KEY IN SPEED AND TIME
void enter_speed_time()
{
  stage1speed = 4000;
  stage1time  = 10;
  stage2speed = 6000;
  stage2time  = 10; 
  stage3speed = 8000; 
  stage3time  = 10;

  return;
}


// FUNCTION FOR RPM MEASUREMENT
void rpmMeasure()
{
  static long last_update;

  // RPM Measurement
  currentstate = digitalRead(dataIN); // Read IR sensor state
  if ( prevstate != currentstate) // If there is change in input
  {
    if ( currentstate == HIGH ) // If input only changes from LOW to HIGH
    {
      duration = ( micros() - prevmillis ); // Time difference between revolution in microsecond
      rpm = (60000000 / duration); // rpm = (1/ time millis)*1000*1000*60;
      prevmillis = micros(); // store time for next revolution calculation
    }
  }
  prevstate = currentstate; // store this scan (prev scan) data for next scan

  if (millis()-last_update > 1000)
  {
      Serial.print ("speed=");
      Serial.println (rpm);
      last_update = millis();
  }



}

void set_speed (int speed)
{
  Serial.print ("set speed=");
  Serial.println (speed);

   timer1_counter = 65536 - F_CPU/prescaler/speed*60/2;
  //myservo.write(speed);
}

// FUNCTION FOR MOTOR SPINNING ACCORDING TO TIME AND SPEED
void motorspin()
{

  unsigned long currentMillis = millis();
  int idleValue = 0;

  static enum { IDLE, STAGE1, STAGE2, STAGE3 } spinningstate;
  switch (spinningstate) {
    case IDLE:
      set_speed(stage1speed);
      previousMillis = currentMillis;
      spinningstate = STAGE1;

      break;
    case STAGE1:
      if (currentMillis - previousMillis >= stage1time * 1000) {
        set_speed(stage2speed);
        previousMillis = currentMillis;
        spinningstate = STAGE2;
      }
      break;
    case STAGE2:
      if (currentMillis - previousMillis >= stage2time * 1000) {
        set_speed(stage3speed);
        previousMillis = currentMillis;
        spinningstate = STAGE3;

      }
      break;
    case STAGE3:
      if (currentMillis - previousMillis >= stage3time * 1000) {
        set_speed(idleValue);
        spinningstate = IDLE;
      }
      break;
  }
}

// MAIN LOOP
void loop()
{
  switch (systemstate)
  {
    case enter_values:

      enter_speed_time();
      systemstate = spin;
      break;

    case spin:

      rpmMeasure();
      motorspin();
      if (0) // haven't figure out yet
        {
          systemstate = finish;
        }
      break;

    case finish:

      systemstate = enter_values;
      break;
  }
}

0 个答案:

没有答案