Счётчик прерываний севомотора с Atmega328 - PullRequest
0 голосов
/ 19 февраля 2020

В настоящее время я работаю над проблемой, которая включает использование внутренних таймеров периферийных устройств в микроконтроллере Atmega328 для создания ШИМ-сигнала (период 20 мс) для управления серводвигателем. Я должен двигать сервомотор с тремя импульсами ширины - (0 градусов: 1 мс, 90 градусов: 1,5 мс, 180 градусов: 2 мс). Дальнейшие условия включают в себя то, что я должен использовать Timer1 и режим FAST PWM. Ниже моя реализация. Пожалуйста помоги.


enum{onems, pointonems, twoms}; 

byte state = onems;

 volatile boolean interrupt; 
//***********************************************************************************
void setup()
{  

  pinMode(9,OUTPUT);  // to drive servo on pin 9
  Serial.begin(9600);
  Serial.println(F("PWM_servo_compact"));
  TCCR1A=0b00100010;     //fast PWM mode 14
  TCCR1B=0b00011010;     //fast PWM mode 14, /8 clock scale
   OCR1A=0; 
  ICR1=39999;         //period = 20 ms
  cli(); 
  TIMSK1 = (1 << OCIE1A);
  sei(); 
  Serial.println("I'm ready to run a servo, attach one to pin 9");
}
//***********************************************************************************
void loop()
{ 

  switch(state){
    case onems:

      //Serial.println("a"); 
       interrupt=false; 
       TCCR1B=0b00011001;     //fast PWM mode 14, /1 clock scale
       OCR1A=15999; 
          TCNT1 = 0; //clear 
         if(interrupt==true) state=pointonems;

      break;

    case pointonems:
        //Serial.println("a"); 

          TCCR1B=0b00011001;     //fast PWM mode 14, /1 clock scale
          OCR1A = 23999; 
          TCNT1 = 0; //clear 
          interrupt=false; 

         if(interrupt==true) state = twoms;

      break;
      case twoms:
     //Serial.println("a"); 

          TCCR1B=0b00011001;     //fast PWM mode 14, /1 clock scale
          OCR1A = 31999;  
          TCNT1 = 0; //clear 
          interrupt=false; 

          // Stop the timer
          TCCR1B &= 0b00000000;
         if(interrupt==true) state = onems;

      break;

    default:
      break;
  }
  delay(1);

} // Arduino loop()

ISR(PCINT0_vect) {
  interrupt=true; 
}
...