Let me start of by stating that I'm not very proficient with the debugger. I've read the tutorials, etc.
Hardware: Arduino Uno
Software: AS7, 7.0.1006
Arduino IDE for Atmel Studio, 1706.25.2
Function of code: Synchronize crank signal count with a position on the camshaft signal. Once synchronized, pulse an output signal every 40 crank pulses. There are 120 crank pulses.
Parts of this code don't work exactly as intended. I want to watch certain registers while it's running. Timer 1 is running on external clock, so I can slow things down to 1Hz if I like.
Specific Problem I'm having:When I invoke the Debugger - with or without any break point - the program hangs at the CAM_SYNC call. If I rem out the CAM_SYNC, then I can debug the rest of the program. The output window says it's "Running", but it isn't. I have LEDs watching output on the board, but all output is low and nothing happens.
If I place a BP at the first line in CAM_SYNC, it's never reached.
There are many settings for the Debugger that I'm not familiar with. The Debugger used to work fine on this project, but then I've added many functions to it - now it doesn't work.
Any thoughts or comments are greatly appreciated. Perhaps there are noobie rules that I'm not aware of.
First part of code that hangs in Debugger mode:
#define ledPin 13
volatile bool irFlag1 = false;
volatile bool compA_flag = false;
volatile bool compB_flag = false;
volatile int TCValue;
volatile int lastTCValue;
int camPulseWidth = 0;
int lastCamPulseWidth = 0;
bool shortCamPulseFound = false;
bool longCamPulseFound = false;
volatile int camEvent = 0;
unsigned long cycleCount = 0;
volatile int TC_cam_check = 0;
volatile int checkCount = 70;
volatile bool cam_ck_flag = false;
void setup()
{
//Serial.begin(115200);
pinMode(ledPin, OUTPUT);
pinMode(6, OUTPUT);
pinMode(8, OUTPUT); // No Sync indicator
pinMode(9, OUTPUT); // Sync indicator
pinMode(11, OUTPUT); // No Cam signal indicator %%% Debugger OK to here %%%
// %%%%%% IF CAM_SYNC IS LEFT IN, MICRO HANGS AND WON'T PROCESS CAM_SYNC FUNCTION - EVEN WITHOUT BREAK POINTS.
// %%%%%% IF CAM_SYNC IS REM'D OUT, TIMER1_RUN_SETUP PROCESSES, AND ALL IS WELL.
CAM_SYNC(); // Set up TC1 in mode 14, use camInt to read TC1 value and sync crank count with cam position.
// Set up timer for RUN mode.
TIMER1_RUN_SETUP();
}
void CAM_SYNC()
{
// **************** Initialize Timer1 to Sync the Cam with the Crank Count. **************
noInterrupts(); // disable all interrupts
TCCR1A = 0; // Clear both control registers.
TCCR1B = 0;
TCNT1 = 0; // Clear TC1
TCCR1B |= (1 << CS12) | (1 << CS11) ; // specify external clock
TCCR1B |= (1 << WGM13) | (1 << WGM12); // Setup for mode 14 - clear at ICR1L value. This is the TOP value, and trips TOV interrupt.
ICR1 = 200; // Define TOP value for CTC to reset at.
TIMSK1 |= (1 << TOIE1); // enable timer interrupt for overflow.
TIMSK1 |= (1 << ICIE1); // enable input capture enable interrupt ***** this is used as the TOP overflow interrupt *****
interrupts(); // enable all interrupts
/*
********** Description of CAM_SYNC function ***************
Outer while loop (!irFlag1):
1)Turn on 'no sync' led.
2)Ensure longCamPulseFound is false so inner while loop will work.
3)Calculate pulse width. Cam Interrupt provides new values - if no cam pulse, no new values; counter will reach TOP value and call overflow ISR.
4)Once a pulse width value falls into the first 'if' condition, start calculating camPulseWidth for second 'if'.
4a)This if statement needs to be true after the next cam interrupt. If it's not true, the first 'if' was true under erroneous conditions - start the whole process over.
5)Once the first and second 'if' are true, detach the cam interrupt, clear TC1 (clearing here sets the crank count sync with the cam), and fall out of the function
by setting longCamPulseFound and irFlag1 to true.
*/
irFlag1 = false;
CAM_Enable_Rising();
while (!irFlag1)
{ //Serial.println(camEvent);
PORTB |= (1 << PB0); //Turn on no Sync led. Pin 8.
PORTB &= ~(1 << PB1); // Turn off Sync led. Pin 9.
longCamPulseFound = false;
camPulseWidth = TCValue-lastTCValue;
Serial.println(camPulseWidth) ;
if ((camPulseWidth >= 9) && (camPulseWidth <=11)) // Wait until camPulseWidth is between 9 and 11, inclusive.
{
camEvent = 0; // Clear camEvent number.
while (!longCamPulseFound)
{
if ((camPulseWidth >= 28) && (camPulseWidth <=30) && (camEvent < 2)) // Wait until camPulseWidth is between 28 and 30, inclusive.
{
irFlag1 = true; // This will end the first while loop.
longCamPulseFound = true; // This will end this while loop.
PORTB |= (1 << PB1); // Turn on Sync led. Pin 9
PORTB &= ~(1 << PB3);// Turn off 'no cam signal' led.
PORTB &= ~(1 << PB0);// Turn off no Sync led. Pin 8
TCNT1 = 0; // Clear TC1. This is where the count is initiated.
TIMSK1 &= ~(1 << ICIE1); // Turn off mask for 'TOP' ISR.
CAM_Disable();
cam_ck_flag = false;
}
if (camEvent > 1)
{
longCamPulseFound = true; // Setting to true will jump out of this loop, but not the first while loop - force it to find the short pulse again.
}
camPulseWidth = TCValue-lastTCValue;
}
}
}
}
void TIMER1_RUN_SETUP()
{
// **************** Initialize Timer1 for normal operation. **************
noInterrupts(); // disable all interrupts
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
OCR1A = 1; // compare match register A
OCR1B = 11; // compare match register B
//TCCR0A |= (1 << WGM01); // CTC mode
TCCR1B |= (1 << CS12) | (1 << CS11) ; // specify external clock
TCCR1B |= (1 << WGM13) | (1 << WGM12); // Setup for CTC mode 12 - clear at ICR1L value.
// TCCR1A |= (1 << WGM11); // Add this to the above to set Mode 12, Fast PWM. This mode does not allow update of the OCR1x registers except at the BOTTOM.
ICR1L = 119; // Define TOP value for CTC to reset at.
TIMSK1 |= (1 << OCIE1A) | (1 << OCIE1B) ; // enable timer compare interrupt for Compare A and B.
interrupts(); // enable all interrupts
}