Visualizza messaggio singolo
Vecchio 11 febbraio 14, 20:10   #11 (permalink)  Top
faustog_2
User
 
L'avatar di faustog_2
 
Data registr.: 19-07-2008
Residenza: catania
Messaggi: 978
Non è una cosa complicata!

tutto sommato non è complicato....

abbiamo il Timer1 che cresce a ritmo di mezzo microsecondo.. (prescaler 8) ovvero 500 nS (nano secondi) quando raggiunge il valore del periodo, si verifica un interrupt.... che viene catturato dalla funzione ISR( ecc...) ..dentro questa funzione viene azzerato il timer... viene eseguito il fronte di salita sul pin in causa... Adesso il compare dovrà osservare non più il periodo ma un altro registro l'OCR1A appena il Timer1 raggiunge questo valore avviene dinuovo un interrupt ma stavolta esegue il fronte di discesa STOP! fine della storia.. ovviamente i registri



Citazione:
Originalmente inviato da baccothe Visualizza messaggio
Sempre in rete ho trovato questo, ma...non riesco a capirlo

Codice:
//this programm will put out a PPM signal

//////////////////////CONFIGURATION///////////////////////////////
#define chanel_number 1  //set the number of chanels
#define default_servo_value 1500  //set the default servo value
#define PPM_FrLen 22500  //set the PPM frame length in microseconds (1ms = 1000µs)
#define PPM_PulseLen 300  //set the pulse length
#define onState 1  //set polarity of the pulses: 1 is positive, 0 is negative
#define sigPin 10  //set PPM signal output pin on the arduino
//////////////////////////////////////////////////////////////////


/*this array holds the servo values for the ppm signal
 change theese values in your code (usually servo values move between 1000 and 2000)*/
int ppm[chanel_number];

void setup(){  
  //initiallize default ppm values
  for(int i=0; i<chanel_number; i++){
    ppm[i]= default_servo_value;
  }

  pinMode(sigPin, OUTPUT);
  digitalWrite(sigPin, !onState);  //set the PPM signal pin to the default state (off)
  
  cli();
  TCCR1A = 0; // set entire TCCR1 register to 0
  TCCR1B = 0;
  
  OCR1A = 100;  // compare match register, change this
  TCCR1B |= (1 << WGM12);  // turn on CTC mode
  TCCR1B |= (1 << CS11);  // 8 prescaler: 0,5 microseconds at 16mhz
  TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
  sei();
}

void loop(){
  //put main code here
  static int val = 1;
  
  ppm[0] = ppm[0] + val;
  if(ppm[0] >= 2000){ val = -1; }
  if(ppm[0] <= 1000){ val = 1; }
  delay(10);
}

ISR(TIMER1_COMPA_vect){  //leave this alone
  static boolean state = true;
  
  TCNT1 = 0;
  
  if(state) {  //start pulse
    digitalWrite(sigPin, onState);
    OCR1A = PPM_PulseLen * 2;
    state = false;
  }
  else{  //end pulse and calculate when to start the next pulse
    static byte cur_chan_numb;
    static unsigned int calc_rest;
  
    digitalWrite(sigPin, !onState);
    state = true;

    if(cur_chan_numb >= chanel_number){
      cur_chan_numb = 0;
      calc_rest = calc_rest + PPM_PulseLen;// 
      OCR1A = (PPM_FrLen - calc_rest) * 2;
      calc_rest = 0;
    }
    else{
      OCR1A = (ppm[cur_chan_numb] - PPM_PulseLen) * 2;
      calc_rest = calc_rest + ppm[cur_chan_numb];
      cur_chan_numb++;
    }     
  }
}
faustog_2 non è collegato   Rispondi citando