Timer1 kesmesi ile duraklat ve devam ettir yapılabilirmi?

kumandan11

Üye
Katılım
4 Ağu 2013
Mesajlar
26
Puanları
1
Aşağıdaki kodda durdurma işlemi yapabiliyorum. Duraklat ve Devam ettir işleme eklemek istiyorum. Nasıl yapabilirim?
C:
/********************************************************************
  pump
********************************************************************/
uint8_t pump(int8_t pumpingDirection, uint32_t flowrate, uint32_t volume)
{
  float tempFloat;

  ustepCounterLimit = (uint32_t)(coef * volume + 0.5);
  ustepCounterLimit *= NOFMICROSTEPS;                   

  float ustepsPERmin = coef * NOFMICROSTEPS * (float)flowrate; 
  if (ustepsPERmin < 14.4) ustepsPERmin = 14.4;
  float multiplier;
  if (ustepsPERmin >= 229) multiplier = 15000000;
  else multiplier = 937500;
  tempFloat = multiplier / ustepsPERmin;
  uint16_t countsPERustepActual = (uint16_t)(tempFloat + 0.5);
  float ustepsPERsActual = multiplier / (float)countsPERustepActual;
  ustepsPERsActual /= 60;

  lcd.clear();
  lcd.setCursor(0, 0);
  if (pumpingDirection > 0)
  {
    endStopPin = ENDSTOP_PIN1;
    if (INVERTDIRECTION == true) digitalWrite(DIRECTION_PIN, LOW);
    else digitalWrite(DIRECTION_PIN, HIGH);
    lcd.print(F(">> DOLDURULUYOR >>"));
  }
  else
  {
    endStopPin = ENDSTOP_PIN2;
    if (INVERTDIRECTION == true) digitalWrite(DIRECTION_PIN, HIGH);
    else digitalWrite(DIRECTION_PIN, LOW);
    lcd.print(F("<< BOŞALTILIYOR <<"));
  }
  lcd.setCursor(0, 1);
  printTimeAndVolume(0, 0);

  TCNT1 = 0;
  TCCR1A = 0;
  TCCR1B |= (1 << WGM12);
  if (ustepsPERmin >= 229)
  {
    TCCR1B &= ~( 1 << CS12);
    TCCR1B |= (1 << CS11);
    TCCR1B |= (1 << CS10);
  }
  else
  {
    TCCR1B |= (1 << CS12);
    TCCR1B &= ~( 1 << CS11);
    TCCR1B |= (1 << CS10);
  }

  digitalWrite(ENABLE_PIN, LOW);
  digitalWrite(STEP_PIN, LOW);

  ustepCounter = 1;
  uint32_t ustepCounterActual;
  float coef2 = ((float)items[LINK2LPV].value * stepsPERmm * 1e-9) * (float)valueDivider(VOLUME) * NOFMICROSTEPS * 10;
  bool isManualStop = false;
  uint32_t pumpingVolume;
  uint16_t pumpingTime = 1;
  uint32_t nextMillis = millis() + 1000;
  OCR1A = (countsPERustepActual - 1);
  TIMSK1 |= (1 << OCIE1A);
  while ( (TIMSK1 & (1 << OCIE1A)) )
  {
    button = NA;
    getButtonState();
    if (buttonState == SHORTPRESS && lastButton == LEFT)
    {
      buttonState = MEDIUMPRESS;
      lcd.setCursor(0, 0);
      lcd.print(F(" POMPA DURDUR?  "));
      lcd.setCursor(0, 1);
      lcd.print(F("(EVET)   (HAYIR)"));
      while ( (TIMSK1 & (1 << OCIE1A)) )
      {
        button = NA;
        getButtonState();
        if (buttonState == SHORTPRESS)
        {
          buttonState = MEDIUMPRESS;
          if (lastButton == LEFT)
          {
            TIMSK1 &= ~( 1 << OCIE1A);
            isManualStop = true;
          }
          else if (lastButton == RIGHT)
          {
            lcd.setCursor(0, 0);
            if (pumpingDirection > 0) lcd.print(F(" >> DOLDURULUYOR >> "));
            else lcd.print(F("<< BOŞALTILIYOR <<"));
            break;
          }
        }
      }
    }

    if (nextMillis <= millis())
    {
      cli();
      ustepCounterActual = ustepCounter;
      sei();

      pumpingVolume = (uint32_t)(((float)ustepCounterActual / coef2) + 0.5);
      printTimeAndVolume(pumpingTime, pumpingVolume);
      pumpingTime++;
      nextMillis += 1000;
    }
  }

  digitalWrite(ENABLE_PIN, HIGH);
  button = NA;
  lcd.setCursor(0, 1);
  pumpingVolume = (uint32_t)(((float)ustepCounter / coef2) + 0.5);
  printTimeAndVolume(pumpingTime, pumpingVolume);
 

  lcd.setCursor(0, 0);
  if (isManualStop)
  {
    lcd.print(F("MANUEL DURDURMA "));
    button = NA;
    return 2;
  }
  if (ustepCounterLimit == ustepCounter - 1)
  {
    lcd.print(F("     BİTTİ      "));
    button = NA;
    return 0;
  }
  else
  {
    lcd.print(F("  HATALI DURUŞ  "));
    button = NA;
    return 1;
  }
}



/********************************************************************
  ISR(TIMER1_COMPA_vect)
********************************************************************/
ISR(TIMER1_COMPA_vect)
{
  digitalWrite(STEP_PIN, HIGH);
  if (ustepCounter == ustepCounterLimit) TIMSK1 &= ~( 1 << OCIE1A);
  if ( digitalRead(endStopPin) == LOW) TIMSK1 &= ~( 1 << OCIE1A);
  delayMicroseconds(10);
  digitalWrite(STEP_PIN, LOW);
  ustepCounter++;
}
 
Timer1 kütüphanesindeki:
TCNT1= 0 satrını TCNT1=1 yaparak deneneyin
 
Timer kesmesi kullanarak yapılan işlemlerde Timer kesmesini kapatıp açmak bazı durumlarda sorun yaratabilir. Onun yerine isr içine bir kontrol değişkeni koyup onun durumuna göre isr deki kodları çalıştırarak işlemleri yaptırabilirsin. Eğer çok acil bir durdurma gerekiyorsa başlatma ve durdurma butonlarını yine pin durumuna göre kesme yapabilen pinlere bağlamak daha kararlı bir sonuç oluşturacaktır.



Aşağıda basit bir örnek var.


volatile boolean motor_durdur_baslat=false;

/*

eğer durdur butonuna basılmışsa
motor_durdur_baslat =false;

eğer başlat yada devam ettir butonuna basılmışsa

motor_durdur_baslat =true;


*/

ISR(TIMER1_COMPA_vect)
{

if( motor_durdur_baslat == false )
{
return ;
}
digitalWrite(STEP_PIN, HIGH);
if (ustepCounter == ustepCounterLimit) TIMSK1 &= ~( 1 << OCIE1A);
if ( digitalRead(endStopPin) == LOW) TIMSK1 &= ~( 1 << OCIE1A);
delayMicroseconds(10);
digitalWrite(STEP_PIN, LOW);
ustepCounter++;


}


Ayrıca (MCU) Micro controller Unit 'ler ile çalışıyorsan " state machine programming " öğrenmen çok iyi olacaktır.
 
Son düzenleme:

Forum istatistikleri

Konular
127,951
Mesajlar
913,867
Kullanıcılar
449,599
Son üye
Gksn

Yeni konular

Geri
Üst