我想用定时器中断移动我的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;
}
}