Go Down

Topic: Timer1 not firing (Read 450 times) previous topic - next topic

ardnut

I am trying to set up Timer1 in CTC with a rate of 500Hz:

Code: [Select]

//  controlling pins A=pin9. B=pin10
pinMode(10, OUTPUT);
pinMode(9, OUTPUT); //
 TCCR1A &= (unsigned char)~0b11110011; // zeros are reserved bits
//  TCCR1A |= 0b00;  // WGM1[1,0] = 0b00, with WGM1[3,2]=01 for CTC; WGM1[3]=0 i/p
 TCCR1A |= 0b11100000;  // COM1A[1,0]= TCCR1A[7.6]=10; COM1B[1,0]= TCCR1A[5,4]=10 ; clear on match
                        // COM1A[1,0]= 1 ; inv-output  // normal DIO

//  TCCR1B[7,6] : input capture only, noise filter , edge detection. [5] reserved
//                NB only on 16b counter cf force comp on 8b

 TCCR1B &= ~0b11111;
 TCCR1B |=  0b01101; // 01101: WGM2[3,2]=01 + "div 1024" -> 16kHz tick: OCR1A sets count ...
 OCR1A = 16; // set cycle length = 16kHz /16/2 = circa 1/2 kHz
/*
    338:       80 e1           ldi     r24, 0x10       ; 16
    33a:       90 e0           ldi     r25, 0x00       ; 0
    33c:       90 93 89 00     sts     0x0089, r25
    340:       80 93 88 00     sts     0x0088, r24
*/

 TIMSK1 = 0b001; // in CTC, TOV1 triggers at MAX, ie OCR1A match


now with the exception of the possible unsafe write , this compiles as I expected.

However, when I run it the inverted op stays high and the other low. No PWM.

I had no trouble setting up Timer2 so there must be something I'm over looking or something in the library code that is messing this up that I am not aware of.

Can anyone see what's wrong?

thx

TMRh20


You just need to set COM1A0 and COM1B0  (TCCR1A register) to toggle on compare match, instead of 'set on compare match' :

Code: [Select]


//  controlling pins A=pin9. B=pin10
pinMode(10, OUTPUT);
pinMode(9, OUTPUT);
   TCCR1A &= (unsigned char)~0b11110011; // zeros are reserved bits
//  TCCR1A |= 0b00;  // WGM1[1,0] = 0b00, with WGM1[3,2]=01 for CTC; WGM1[3]=0 i/p
  TCCR1A |= 0b01010000;  // COM1A[1,0]= TCCR1A[7.6]=10; COM1B[1,0]= TCCR1A[5,4]=10 ; clear on match
                         // COM1A[1,0]= 1 ; inv-output  // normal DIO

//  TCCR1B[7,6] : input capture only, noise filter , edge detection. [5] reserved
//                NB only on 16b counter cf force comp on 8b

  TCCR1B &= ~0b11111;
  TCCR1B |=  0b01101; // 01101: WGM2[3,2]=01 + "div 1024" -> 16kHz tick: OCR1A sets count ...
  OCR1A = 16; // set cycle length = 16kHz /16/2 = circa 1/2 kHz
/*
     338:       80 e1           ldi     r24, 0x10       ; 16
     33a:       90 e0           ldi     r25, 0x00       ; 0
     33c:       90 93 89 00     sts     0x0089, r25
     340:       80 93 88 00     sts     0x0088, r24
*/

  TIMSK1 = 0b001; // in CTC, TOV1 triggers at MAX, ie OCR1A match





or how I find it easiest:

Code: [Select]

  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT);
  TCCR1A = _BV(COM1A0) | _BV(COM1B0);
  TCCR1B = _BV(WGM12) | _BV(CS12) | _BV(CS10);
  OCR1A = 16;
  TIMSK1 = _BV(TOIE1);

ardnut

Of course, I was mixing up the timings with the phase corrected modes. Clearly I need to toggle in CTC.

I actually find these mnemonics are just as cryptic as plain binary: remembering what WMG12 means is the same as remembering what TCCR1B[5] does except that I need to learn two names instead of one. (Not Arduinos fault, that's the Atmel doc) but it's as cryptic a binary at the end of the day.

I either need to define some const values that are human readable (which is probably what Arduino should have done) or liberally spray my code with comments. Until I find out exactly how all this hangs together , it's the latter.

Code: [Select]

pinMode(10, OUTPUT);
pinMode(9, OUTPUT);
  TCCR1A &= (unsigned char)~0b11110011; // zeros are reserved bits
//  TCCR1A |= 0b00;  // WGM1[1,0] = 0b00, with WGM1[3,2]=01 for CTC; WGM1[3]=0 i/p
  TCCR1A |= 0b01000000;  // COM1A[1,0]= TCCR1A[7.6]=01; COM1B[1,0]= TCCR1A[5,4]=00 ; normal DIO
                         // COM1A[1,0]= 01 ; toggle output to chk freq on pin 9 //

//  TCCR1B[7,6] : input capture only, noise filter , edge detection. [5] reserved

  TCCR1B &= ~0b11011111; // [7,6] noise canceller=0; [5] resv.
  TCCR1B |=  0b01101; // 01101: WGM2[3,2]=01 + "div 1024" -> 16kHz tick: OCR1A sets count ...
  OCR1A = 16; // set cycle length = 16kHz /16/2 = circa 1/2 kHz

  TIMSK1 = 0b001; // in CTC, TOIE1 bit: TOV1 triggers at MAX, ie OCR1A match



That seems to be the same as what you posted.

My TIMER1_OVF_vect() is getting called now as I intended. And I get 500Hz on pin 9

Thanks for your help in seeing this silly error.


ardnut

Of course the other error was that in CTC the timer counter never overflows so setting up TIMER_OVF_vect is a waste of time.

TIMSK1 = 0b010;
TIMER1_COMPA_vect()

That finally does what I intended

Thanks again.

Go Up