SW2 is a define, and it resolves directly to a number; therefore the compiler never created the code for the test. In order to read a pin in CCS, use the input() function.
So your test code should be:
C:
if ((ch<=674) && (input(SW2)==1)) //Low Voltage protection enable if SW2 is always on(conect with GND).
return(LOW_VOLTAGE); //if SW2 is always off(no conect with GND & +5 volt.) Low Voltage protection disable
Took me a few minutes to figure this out. I would set a breakpoint in MPLAB SIM, and it would tell me that the 'breakpoint could not be resolved." The reason it could not be resolved was that it was being optimized out.
void BlinkLED1(void)
{
int x;
for (x=0; x<=9; x++) // Repeat 10 times, count from 0 to 9
{
output_high(L1);
delay_ms(BLINK_DELAY);
output_low(L1);
if ((input(SW1)==1) && delay_ms(1)) // Quake start hear if SW1 is on any time 1 sec
goto(NORMAL_VOLTAGE);
}
void BlinkLED1(void)
{
int x;
for (x=0; x<=9; x++) // Repeat 10 times, count from 0 to 9
{
output_high(L1);
delay_ms(BLINK_DELAY);
output_low(L1);
if ((input(SW1)==1) && delay_ms(1)) // Quake start hear if SW1 is on any time 1 sec
goto(NORMAL_VOLTAGE);
if ( (input(SW1)==1) && delay_ms(1) ) // Quake start hear if SW1 is on any time 1 sec goto(NORMAL_VOLTAGE);
In the line above, delay_ms(1) isn't correct in that context. The code executes, but it's not right. All you are doing in this block of code is testing for SW1==1 and then executing a delay of one ms. I don't think that is what you want. You want to test that one ms (or is it one second?) has passed. We are going to have to use one of the 676 timers with a count variable to test that time has passed (or look for a built in function, if it exists).
Also you shouldn't use goto XYZ unless you absolutely must. And it should be inside the same routine in which it is used. When you go into a routine, the program counter is pushed unto the stack, by jumping out of the routine with a goto doesn't pull the return address from the stack. Do the goto 8 times, and your program crashes because the stack is full.
First, I think the line goto (NORMAL_VOLTAGE) is wrong because NORMAL_VOLTAGE is a define, not a label.
In this case, I would replace goto (NORMAL_VOLTAGE); with a break statement and a flag. You are inside of a loop and the break statement will exit the loop.
C:
// QuickStart_flag defined as a global variable
int1 QuickStart_flag;
void BlinkLED1(void)
{
int x;
for (x=0; x<=9; x++) // Repeat 10 times, count from 0 to 9
{
output_high(L1);
delay_ms(BLINK_DELAY);
output_low(L1);
if ((input(SW1)==1) && (time_elasped()<1000) ) // Quake start hear if SW1 is on any time 1 sec
{
QuickStart_flag;=1;
break;
}
}
}
// we would test for QuickStart_flag elsewhere in code, probably the switch case staement.
// also note that time_elasped() is only an example function that would return the time_elasped, not defined here.
Not sure about that unless its the call 0x3ff. Not sure why the compiler puts that in there.
EDIT: There is no call 0x3ff. It is jumping directly to the return from interrupt, and seems to be crashing at the RETIE instruction. It was working in MPLAB SIM. I'll try it again.
EDIT2: There is a call 0x3ff at instruction 038.
Probably going to have to put the LED1 blink code in the interrupt.
Pseudo code for interrupt routine:
Turn LED1 on
Count # of ms that have passed
Once we reach 1000 (one sec), Turn off LED1
count # of ms that have passed
Once we reach 1000 (one sec), increment LED1count variable, to determine the number of times we have blinked LED1
repeat 10 times
Probably going to have to put the LED1 blink code in the interrupt.
Pseudo code for interrupt routine:
Turn LED1 on
Count # of ms that have passed
Once we reach 1000 (one sec), Turn off LED1
count # of ms that have passed
Once we reach 1000 (one sec), increment LED1count variable, to determine the number of times we have blinked LED1
repeat 10 times
Yes, you would count to 90 at a blink rate of 1 second on and 1 second off for a total of 180 sec or 3 min. The ADC sensing would be done concurrently because the ADC code would be executing, and at a 1 ms time interval, the interrupt would occur.
Yes, you would count to 90 at a blink rate of 1 second on and 1 second off for a total of 180 sec or 3 min. The ADC sensing would be done concurrently because the ADC code would be executing, and at a 1 ms time interval, the interrupt would occur.
There are two ways to do it. Put the code in a interrupt as I suggest, or put the blinkled1 code in with the ADC code. With the interrupt executing at 1 ms, you can count up to 3 min. You'd have to figure out a way to count up to 3 min if you put the blinkled1 code with the ADC code. It's just a matter of how you want to do it. Either way, both sets of code are executing at the same time.
void main()
{
//Timer1 Init
setup_timer_1(T1_INTERNAL | T1_DIV_BY_2); // Use Internal Timer, Prescaler = 1 : 2
set_timer1(60545); // Set Timer1 register to 1 ms @ 4 Mhz
//ADC Init
setup_adc_ports(sAN0);
setup_adc(ADC_CLOCK_DIV_32);
ADFM = 1; //AD Result Right Justified
setup_comparator(NC_NC);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
voltage_type = ProcessMains();
// Quick start here if SW1 is on any time 1 sec
// time_elasped set in interrupt
if ( (QuickStart_flag == 1) && (time_elasped<1) )//&& (voltage_type == LOW_VOLTAGE) )
voltage_type = NORMAL_VOLTAGE;
switch(voltage_type)
{
case HIGH_VOLTAGE:
output_high(BZR); // Create Sound
output_low(RL5); // Relay Off
BlinkLED2();
break;
case LOW_VOLTAGE:
output_high(BZR); // Create Sound
output_low(RL5); // Relay Off
BlinkLED2();
break;
case NORMAL_VOLTAGE:
output_low(BZR);
output_high(RL5);
//BlinkLED1();
output_high(L1);
break;
default:
//We shouldn't get here
while (1)
{
//led1 blink mains normal ,led1 blink & Reads ADC
// both are work in same time. not one by one.
//if led1 blink duration complet then it no blink agen.
if (BlinkMains_flag==0)
{
BlinkLED1();
BlinkMains_flag=1;
}
break;
}
}
} // End Main
void main()
{
//Timer1 Init
setup_timer_1(T1_INTERNAL | T1_DIV_BY_2); // Use Internal Timer, Prescaler = 1 : 2
set_timer1(60545); // Set Timer1 register to 1 ms @ 4 Mhz
//ADC Init
setup_adc_ports(sAN0);
setup_adc(ADC_CLOCK_DIV_32);
ADFM = 1; //AD Result Right Justified
setup_comparator(NC_NC);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
voltage_type = ProcessMains();
// Quick start here if SW1 is on any time 1 sec
// time_elasped set in interrupt
if ( (QuickStart_flag == 1) && (time_elasped<1) )//&& (voltage_type == LOW_VOLTAGE) )
voltage_type = NORMAL_VOLTAGE;
switch(voltage_type)
{
case HIGH_VOLTAGE:
output_high(BZR); // Create Sound
output_low(RL5); // Relay Off
BlinkLED2();
break;
case LOW_VOLTAGE:
output_high(BZR); // Create Sound
output_low(RL5); // Relay Off
BlinkLED2();
break;
case NORMAL_VOLTAGE:
output_low(BZR);
output_high(RL5);
//BlinkLED1();
output_high(L1);
break;
default:
//We shouldn't get here
while (1) // *** START OF ENDLESS LOOP ***
{
//led1 blink mains normal ,led1 blink & Reads ADC
// both are work in same time. not one by one.
//if led1 blink duration complet then it no blink agen.
if (BlinkMains_flag==0)
{
BlinkLED1();
BlinkMains_flag=1;
}
break;
} //*** END OF ENDLESS LOOP ***
}
} // End Main
I don't think so, because your never going to get out of the endless loop. EDIT: In order for the default section to be executed, ProcessMains() would have to return something other than LOW_VOLTAGE, HIGH_VOLTAGE, OR NORMAL_VOLTAGE.
Try this. The LED should blink in the interrupt for 3 mins, and then stop. I also added a delay after the A/D conversion because MPLAB SIM kept complaing that a new conversion should not be started until after 2 TADs have passed. The delay is 5 ms. The interrupt fires every 10 ms. Take a look, and let me know.
Try this. The LED should blink in the interrupt for 3 mins, and then stop. I also added a delay after the A/D conversion because MPLAB SIM kept complaing that a new conversion should not be started until after 2 TADs have passed. The delay is 5 ms. The interrupt fires every 10 ms. Take a look, and let me know.