Go Down

Topic: Interrupts and time handling problems. (Read 2 times) previous topic - next topic

jano

hi again!

not completely, but i have some approach to the solution: asm in the interrupt vector handling (yes that ugly thing), right now i can have up to 165khz on pin7, is not enough smooth as i want and the duty cycle is about 48% (i don't know why), but i need to remember more asm  :)
the code is:

Code: [Select]


#include <avr/interrupt.h>
#include <pins_arduino.h>

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

//para el generador de frecuencia
volatile int freq_1=10;  // frecuencia osc 1
volatile int t_high_1=1;  // tiempo alto osc 1
volatile int t_low_1=9;   // tiempo bajo osc 1
volatile int pot=0;
volatile byte icnt1;             // var inside interrupt
volatile byte c4ms;              // counter
volatile long count=0;

volatile boolean high_1=true;  // determinacion del tiempo actual
volatile boolean high_2=true;  // en los dos osciladores


void setup() {

  pinMode(5,OUTPUT);    // pin5=  PWM para correccion de la rampa 1 - timer 0 - OC0A
  pinMode(6,OUTPUT);
  pinMode(7,OUTPUT);    // pin7= salida de frecuencia oscilador 1 PORTD7 - timer 1
  pinMode(4,OUTPUT);    // pin4= salida de frecuencia oscilador 2 PORTD4 - timer 1

  //Serial.begin(9600);

 
  cli();

  // set prescale to 16
  sbi(ADCSRA,ADPS2) ;
  cbi(ADCSRA,ADPS1) ;
  cbi(ADCSRA,ADPS0) ;

  Setup_timer0();
  sbi (TIMSK0,OCIE2A);          //habilita la interrupcion del timer 0 en compare match con OCR0A
  sbi (TIMSK0,OCIE2B);
  sbi (TIMSK0,TOIE2);
 
  sei();
}

void loop () {
 
  if (c4ms > 10) {                 
     c4ms=0;
     t_low_1=(analogRead(0)+1);
     
         
  }
   
 
 
}


void Setup_timer0() {

// Timer0 Clock Prescaler to : 1
  sbi (TCCR0B, CS20);
  cbi (TCCR0B, CS21);
  cbi (TCCR0B, CS22);


//modos de comparacion de los registros OCR 
  sbi (TCCR0A, COM0A0);  // toggle pin 6 en Compare Match con OCR0A
  cbi (TCCR0A, COM0A1);
  sbi (TCCR0A, COM0B0);  // toggle pin 4 en Compare Match con OCR0B
  cbi (TCCR0A, COM0B1);
 

 
// Timer0 modo CTC
  cbi (TCCR0A, WGM00); 
  sbi (TCCR0A, WGM01);
  cbi (TCCR0A, WGM02);
 

}

ISR(TIMER0_COMPA_vect) {
 
//asm("cli"); 


  if (high_1==true){
    asm("sbi 0x0B,7"); //pone el bit 7 del puerto D en alto
    asm("dec %[retval]":[retval]"+r"(t_high_1));


    if (t_high_1==0){
     high_1=false;
     t_high_1=t_low_1;
    }
  }
  if (high_1==false){
   asm("cbi 0x0B,7"); //pone el bit 7 del puerto D en bajo
   asm("dec %[retval]":[retval]"+r"(t_high_1));
   if (t_high_1==0){
     high_1=true;
     t_high_1=t_low_1;
   }
  }
  /*
    if (icnt1++ == 125) {  // increment variable c4ms
    c4ms++;
    icnt1=0;
   }
   */
  // asm("ldi %0,0x01":"=r"(TCNT0));
//  TCNT0=0x01;
  OCR0A=10;

//asm("sei");
}

ISR(TIMER0_OVF_vect) {


 
}

jano

well, i start to write in asm the interrupt handling vector, but there is more than 15 years since i don't touch asm and i don't remember too much :(
i read the inline assembler cookbook, but i miss some...
here is the code:

Code: [Select]

#include <avr/interrupt.h>
#include <pins_arduino.h>
#include <avr/io.h>

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

//para el generador de frecuencia
volatile int freq_1=10;  // frecuencia osc 1
volatile int t_half_p=1;  // tiempo alto osc 1


volatile char high_1=0xFF;  // determinacion del tiempo actual del oscilador (flag t_high, t_low)


void setup() {

  pinMode(5,OUTPUT);    // pin5=  PWM para correccion de la rampa 1 - timer 0 - OC0A
  pinMode(6,OUTPUT);
  pinMode(7,OUTPUT);    // pin7= salida de frecuencia oscilador 1 PORTD7 - timer 1
  pinMode(4,OUTPUT);    // pin4= salida de frecuencia oscilador 2 PORTD4 - timer 1

  //Serial.begin(9600);


  cli();


  Setup_timer0();
  sbi (TIMSK0,OCIE2A);          //habilita la interrupcion del timer 0 en compare match con OCR0A
  sbi (TIMSK0,OCIE2B);
  sbi (TIMSK0,TOIE2);

  sei();
}

void loop () {



}


void Setup_timer0() {

  // Timer0 Clock Prescaler to : 1
  sbi (TCCR0B, CS20);
  cbi (TCCR0B, CS21);
  cbi (TCCR0B, CS22);


  //modos de comparacion de los registros OCR 
  sbi (TCCR0A, COM0A0);  // toggle pin 6 en Compare Match con OCR0A
  cbi (TCCR0A, COM0A1);
  sbi (TCCR0A, COM0B0);  // toggle pin 4 en Compare Match con OCR0B
  cbi (TCCR0A, COM0B1);


  // Timer0 modo CTC
  cbi (TCCR0A, WGM00); 
  sbi (TCCR0A, WGM01);
  cbi (TCCR0A, WGM02);


}

ISR(TIMER0_COMPA_vect) {



  asm volatile("mov r7, %[thalf]"::[thalf]"r"(t_half_p):   //register7<--t_half
               "mov r6, %[thigh]"::[thigh]"r"(high_1):     //register6<--high_1
               "mov r5, r7"                                //r5=auxiliar register contains half period, redundant?
               "HIGH: tst r6, #0xFF"                        //is high_1 up?  --the statement label HIGH is right?
               "brne LOW"                                  //if not jump to LOW
               "sbi 0x0B,7"                                // we are on high time, so pin7 portD<-1
               "dec r7"                                    //decrement r7 (thalf)
               "tst r7, #0x00"                             //is r24 ==0?   (half period finished?)             
               "mov r6, #0x00"                             //if yes the low time start


               "LOW: tst r6, #0x00"                         //is high_1 low? -- again the statemen label LOW is right?
               "brne HIGH"                                 //if not jump to HIGH
               "cbi 0x0B,7"                                // we are on low time, so pin7 portD<-0
               "mov r7, r5"                                //load the half period again
               "dec r7"                                    //again decrement7
               "tst r7, #0x00"                             //until the half of period finishes
               
    );                                                      //should be done



  /*

   );
   if (high_1){
   asm("sbi 0x0B,7"); //pone el bit 7 del puerto D en alto
   asm("dec %[retval]":[retval]"+r"(t_high_1));
   if (!t_high_1){
   high_1=false;
   t_high_1=t_low_1;
   }
   
   }
   if (!high_1){
   asm("cbi 0x0B,7"); //pone el bit 7 del puerto D en bajo
   asm("dec %[retval]":[retval]"+r"(t_high_1));
   if (!t_high_1){
   high_1=true;
   t_high_1=t_low_1;
   }
   }
   
   */

  OCR0A=1;


}

ISR(TIMER0_OVF_vect) {



}



is supposed the asm par is a translation of the commented part after
but the compiler says:
timer_0_OCR0A_freq.cpp: In function 'void __vector_14()':
timer_0_OCR0A_freq:73: error: expected `)' before '::' token

so i delete some...

Code: [Select]


#include <avr/interrupt.h>
#include <pins_arduino.h>
#include <avr/io.h>

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

//para el generador de frecuencia
volatile int freq_1=10;  // frecuencia osc 1
volatile int t_half_p=1;  // tiempo alto osc 1


volatile char high_1=0xFF;  // determinacion del tiempo actual del oscilador (flag t_high, t_low)


void setup() {

  pinMode(5,OUTPUT);    // pin5=  PWM para correccion de la rampa 1 - timer 0 - OC0A
  pinMode(6,OUTPUT);
  pinMode(7,OUTPUT);    // pin7= salida de frecuencia oscilador 1 PORTD7 - timer 1
  pinMode(4,OUTPUT);    // pin4= salida de frecuencia oscilador 2 PORTD4 - timer 1

  //Serial.begin(9600);


  cli();


  Setup_timer0();
  sbi (TIMSK0,OCIE2A);          //habilita la interrupcion del timer 0 en compare match con OCR0A
  sbi (TIMSK0,OCIE2B);
  sbi (TIMSK0,TOIE2);

  sei();
}

void loop () {



}


void Setup_timer0() {

  // Timer0 Clock Prescaler to : 1
  sbi (TCCR0B, CS20);
  cbi (TCCR0B, CS21);
  cbi (TCCR0B, CS22);


  //modos de comparacion de los registros OCR 
  sbi (TCCR0A, COM0A0);  // toggle pin 6 en Compare Match con OCR0A
  cbi (TCCR0A, COM0A1);
  sbi (TCCR0A, COM0B0);  // toggle pin 4 en Compare Match con OCR0B
  cbi (TCCR0A, COM0B1);


  // Timer0 modo CTC
  cbi (TCCR0A, WGM00); 
  sbi (TCCR0A, WGM01);
  cbi (TCCR0A, WGM02);


}

ISR(TIMER0_COMPA_vect) {



  asm volatile("mov r7, %[thalf]"::[thalf]"r"(t_half_p):);    //register7<--t_half
  asm volatile("mov r6, %[thigh]"::[thigh]"r"(high_1):);      //register6<--high_1
  asm volatile("mov r5, r7");                            //r5=auxiliar register contains half period, redundant?
  asm volatile("HIGH: tst r6, #0xFF");                    //is high_1 up?  --the statement label HIGH is right?
  asm volatile("brne LOW");                                  //if not jump to LOW
  asm volatile("sbi 0x0B,7");                                // we are on high time, so pin7 portD<-1
  asm volatile("dec r7");                                    //decrement r7 (thalf)
  asm volatile("tst r7, #0x00");                             //is r24 ==0?   (half period finished?)             
  asm volatile("mov r6, #0x00");                             //if yes the low time start


  asm volatile("LOW: tst r6, #0x00");                        //is high_1 low? -- again the statemen label LOW is right?
  asm volatile("brne HIGH");                                 //if not jump to HIGH
  asm volatile("cbi 0x0B,7");                                // we are on low time, so pin7 portD<-0
  asm volatile("mov r7, r5");                                //load the half period again
  asm volatile("dec r7");                                    //again decrement7
  asm volatile("tst r7, #0x00");                         //until the half of period finishes
               
                                                            //should be done



  /*

   );
   if (high_1){
   asm("sbi 0x0B,7"); //pone el bit 7 del puerto D en alto
   asm("dec %[retval]":[retval]"+r"(t_high_1));
   if (!t_high_1){
   high_1=false;
   t_high_1=t_low_1;
   }
   
   }
   if (!high_1){
   asm("cbi 0x0B,7"); //pone el bit 7 del puerto D en bajo
   asm("dec %[retval]":[retval]"+r"(t_high_1));
   if (!t_high_1){
   high_1=true;
   t_high_1=t_low_1;
   }
   }
   
   */

  OCR0A=1;


}

ISR(TIMER0_OVF_vect) {



}


and when try to compile says:
/tmp/ccrQdvyh.s: Assembler messages:
/tmp/ccrQdvyh.s:226: Error: garbage at end of line
/tmp/ccrQdvyh.s:246: Error: garbage at end of line
/tmp/ccrQdvyh.s:251: Error: bad expression
/tmp/ccrQdvyh.s:251: Error: garbage at end of line
/tmp/ccrQdvyh.s:256: Error: garbage at end of line
/tmp/ccrQdvyh.s:281: Error: garbage at end of line


but the file /tmp/xxxxxxxxx.s is deleted immediately after the compiler print this text so i was unable to 'know' was happens on this files

some clues on it?

Go Up