After setting up and enabling timer1 after successfully using attachInterrupt for external interrupts 0 and 1 on pins D2 and D3, I found that timer1 would work, but seems to replace, inhibit, or otherwise kill my external interrupt 0 on pin D2.
Does that mean timer1 uses external interrupt 0?
Is this general knowledge? Is it documented somewhere?
I want to have two external interrupts and at least one (hopefully two) timers...
When I comment out the attachInterrupt for int0, all works okay, but when left intact... it definitely kills of the timer1...
Suggestions and comments? I am monitoring video horizontal and vertical sync and playing with the clock...
Thanks for looking...
I am running into some strange effects and perhaps this isn't possible with a 16mhz processor...
but here is the code in case something jumps out at you...
Sorry for the left over code in some cases... just trying to see what works...
Tim
// This program attempts to break out an LCDs horizontal and vertical syncs and data clock
// to delay both the horizontal and vertical placement of a non standard screen that
// displays an offset of about 100 lines in both axis.
// The data clock will be delayed for a bit as well as waiting for enough horizontal syncs
// before enabling them both by feeding an enable line to and AND gate along with the source
// clock to essentially enable its output when desired. Another AND gate handles the other signal
// to accomplish a move back up to the top left corner of the screen...
//
// Clock Frequency = 23.8 MHz
// Clock Cycle = 42 ns
// Pulse width = 21 ns
// 50 Clocks = 50 * 42 ns = 2100 ns = 2.1 us
// 25 Clocks = 25 * 42 ns = 1050 ns = 1.05 us
// Horizontal Sync Clock Cycle = 29.3 kHz... New Horizontal Sync every 811 clocks
// Horizontal Sync = 34.1 us
// Vertical Sync Clock Cycle = 60 Hz... New Vertical Sync every 488 Horizontal Syncs
// Recycles to zero (top of screen)
// Vertical Sync = 16.3 ms
// T = timer period, f = clock frequency
// T = 1 / f
// T = 1 / 1 MHz = 1 / 10^6 Hz
// T = (1 * 10^-6) s
#define CLOCK_PIN_ENABLE 10
#define HORZ_PIN_ENABLE 12
#define LED_PIN 13
#define VERT_SYNC_PIN 4
int vDelayClocks = 50;
int hDelayClocks = 50;
volatile unsigned int hSyncCtr = 0;
volatile unsigned int vSyncCtr = 0;
volatile unsigned int state = LOW;
volatile byte portDStatus = 0;
volatile byte portDOldStatus = 1;
void setup()
{
// initialize timer1
noInterrupts(); // disable all interrupts
pinMode(CLOCK_PIN_ENABLE, OUTPUT);
pinMode(HORZ_PIN_ENABLE, OUTPUT);
pinMode(LED_PIN, OUTPUT);
pinMode(2, INPUT);
pinMode(3, INPUT);
pinMode(VERT_SYNC_PIN, INPUT);
//Enable pullup for Vertical Sync Input
digitalWrite(VERT_SYNC_PIN, HIGH);
// attachInterrupt(0, VertSync, FALLING); // Replaced with new interrupt due to conflicts
attachInterrupt(1, HorzSync , FALLING);
// pin change interrupt
PCMSK2 |= bit (PCINT20); // want pin D4
PCIFR |= bit (PCIF2); // clear any outstanding interrupts
PCICR |= bit (PCIE2); // enable pin change interrupts for D0 to D7
// Setup Timer1 interrupt
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 3036; // preload timer 65536-16MHz/256
TIMSK1 |= (1 << TOIE1); // enable timer overflow interrupt
TCCR1B |= (1 << CS12); // 256 prescaler
interrupts(); // enable all interrupts
// Disable LCD clock output
digitalWrite(CLOCK_PIN_ENABLE, 0);
// Disable Horizontal Sync output
digitalWrite(HORZ_PIN_ENABLE, 0);
// Serial.println("State...");
}
// New Verticzl SYNC interrupt handler which should come in every 16.3 ms (60Hz)
ISR(PCINT2_vect)
{
//Handle a pin change interrupt for D0 thru D7
// PINB is the register that containes the momentary status of the pins of port B (pins D0-D7)
// Look at only pin 4
portDStatus = PIND & 0x10;
if(portDStatus != portDOldStatus)
{
// if we get an active low
if(portDStatus == 0)
{
// Every 30 vertical syncs toggle the state for viewing on scope
++vSyncCtr %= 30;
if(vSyncCtr == 0)
{
state = !state; // toggle the state of the LED for VSync
digitalWrite(13, state);
}
// Reset the horizontal sync counter on each vertical sync
hSyncCtr = 0;
// Disable both the LCD Clock and the Horizontal sync output
digitalWrite(CLOCK_PIN_ENABLE, 0);
//digitalWrite(HORZ_PIN_ENABLE, 0);// Already done in the Horizontal SYNC routinge
}
portDOldStatus = portDStatus;
}
}
// interrupt service routine that wraps a user defined function
// supplied by attachInterrupt
ISR(TIMER1_OVF_vect)
{
TCNT1 = 3036; // preload timer
//digitalWrite(LED_PIN, digitalRead(LED_PIN) ^ 1);
}
//
void HorzSync()
{
// Disable LCD clock on every horizontal sync
digitalWrite(CLOCK_PIN_ENABLE, 0);
// Let's count down desired lines before enabling the Clock and the Horizontal Syncs
// At his point, the clock and horizontal sync might be disabled
hSyncCtr++;
if (hSyncCtr > 50)
{
// Delay for about 100 LCD data clocks
delayMicroseconds(8);
// Re-Enable LCD clock
digitalWrite(CLOCK_PIN_ENABLE, 1);
// Enable Horizontal Syncs and keep them enabled untill the next vertical sync
digitalWrite(HORZ_PIN_ENABLE, 1);
}
}
void VertSync()
{
}
void loop() {
// put your main code here, to run repeatedly:
// Display the state of the HSync status
//Serial.print(state);
//Serial.print("\r");
//delay(100);
}
The data clock for the video is at that speed...
My arduino uno is 16mHz...
The horizontal sync at 23 mHz means that I get a horizontal sync pulse every 34 usec...
So that is what I attached to the external interrupt line...
That is what I am wondering about if there is enough time to do any processing before the interrupt comes again...