Arduino uno R3 timer 1 in CTC mode pulses once after reset, will not re-trigger


hi! program executes correctly after reload or after pressing of reset button.

this program should generate precision pulses on pins d9 , d10 of arduino uno r3.
the pins d9 , d10 should high , go low during pulse.
the pulses should start simultaneously stop after individually set timeouts.
the individual pulse duration should 32 msecs setable in 0.5 microsecond increments.
the current program has 200 300 nanoseconds setup delay added total pulse duration.

all of program in loop() after producing first pulse, loops forever doing nothing. have printed out status of registers after reset , have attempted recreate them @ end of execution. successful except icf1 interrupt flag not reset (i.e. tifr1 remains 0x20). not using icf1 interrupt, set icf1 register 0xffff top value timer.

i have included debugging observations in code comments.


code: [select]
boolean running = false;
volatile boolean donea = false;
volatile boolean doneb = false;
isr (timer1_compa_vect)  {
  donea = true;
}
isr (timer1_compb_vect)  {
  doneb = true;
}
void setup() {               
  sei();                 // enable global interrupts
}
void loop() {
   /* 1 set of pulses per trigger required, test purposes, loop should
   produce free running pulse trains repetition rate set 'delay()' statement
   at end of loop. */
  if (running == false) {
// setup 'if' statement flags
    donea = false;
    doneb = false;
    running = true;
//  following code initializes timer1
    gtccr = 0x83;          //stop , reset timers during setup
    /* @ point oc1a & oc1b pins inputs , set outputs later.
    presetting them high or low has no effect until ddrb initialized.
    want them go low during pulse making sure...*/
    portb |= 0x06;         // preset oc1a & oc1b high
//  portb &= 0xf9;         // preset oc1a & oc1b low
    icr1 |= -1;            //set top 0xffff (i.e. max)
    tcnt1 = 0;             // initialize counter
    timsk1 = 0x06;         // enable compare interrupts
    /* in order make sure there no pending interrupts on exiting timer setup
    prefer clear interrupt flags writing logic '1' locations. first time through,
    icf1 flag '0' */
    tifr1 = 0x27;          // reset interrupt flags - should not seem reset icf1 next time around
    tccr1b = 0x1a;         // set mode = 12 , prescaler = 8
   /* setting tccr1a must occur before setting of ocr1a , ocr1b registers or first
   compare missed , output set @ tcnt1 == 0xffff or thereabout - my
   oscilloscope not precise enough */
    tccr1a = 0xf0;         // set oc1a & oc1b on compare
   /* ocr1a , ocr1b registers may set value >= 1
   i did not check values close 0xffff yet */
    ocr1a = 0x0005;        // set comparator - here testing 2.5 microseconds
    ocr1b = 0x0001;        // set comparator b - here testing 0.5 microseconds
    gtccr &= 0x03;         // start timer after setup
   /* oc1a , oc1b pins (d9 , d10) go low set outputs. in order to
   reduce initial dead time minimum, done last */
    ddrb |= 0x06;          // set oc1a & oc1b outputs
  }
  // timers run until both interrupt routines have completed  setting both donea , doneb true
  if  ((donea & doneb) == true)  {
// following section attempts return atmega328 initial state
    gtccr = 0x83;          //stop , reset timers during setup
    // clear 'if' statement flags
    donea = false;         
    doneb = false;
    running = false;
    /* oc1a & oc1b pins set inputs again. presetting them low has no effect
    (i.e. remain high) if done before tccr1a , tccr1b reprogrammed.*/
    ddrb = 0;              // set oc1a & oc1b inputs
    portb &= 0xf9;         // preset oc1a & oc1b low
    /* preset mode 1 (8-bit pwm) , prescaler of 64
    presetting these or other timer 1 related registers has no effect on ultimate outcome.
    oc1a , oc1b (d9 , d10) remain high until reset button pressed
    or program reloaded */
    tccr1a = 1;
    tccr1b = 3;
    ocr1a = 0;
    ocr1b = 0;
    tcnt1 = 0;
    timsk1 = 0;
    icr1 = 0;
    gtccr &= 0x03;         // restart timers
    delay(2000);           // wait 2 seconds repeat
  }   
}


once debugged converted procedure , triggered hardware interrupt
on input pin.

i don't see wrong.  i'm not expert manipulating avr timers...

i'd lot happier if separated timer initialization (modes/etc) code expect repeat.  "restoring initial state" seems poor idea.  (hmm.  restoring avr "reset" state, or state arduino init() code sets timers to?)

how symbolic constants timer register bits?

it doesn't seem idea me, reset port pins inputs after occ matches both occur.  don't want pulses "active" ?

you want this, right?
code: [select]
  initialize_timer();
   while (1) {
     start_timer(); // start both pulses.
     while (!(donea && doneb))
        ;  // spin, waiting both pulses complete.
     stop_timer();
     delay(2000);
   }  // repeat pulses 


why don't start writing that?  if it's slow after working, can work on optimizing glopping code together.  (but compiler anyway...)

in general, think don't emphasize breaking code modular pieces enough in these forums...  :-(



Arduino Forum > Using Arduino > Programming Questions > Arduino uno R3 timer 1 in CTC mode pulses once after reset, will not re-trigger


arduino

Comments

Popular posts from this blog

Connecting Raspberry Pi 2 to P10(1R)-V706 LED Dot Matrix - Raspberry Pi Forums

TypeError: <unknown> is not a numpy array - Raspberry Pi Forums

datso and removing imagetitle - Joomla! Forum - community, help and support