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.
once debugged converted procedure , triggered hardware interrupt
on input pin.
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?
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... :-(
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
Post a Comment