Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Break from infinite loop

Status
Not open for further replies.

Samaan

New Member
Hi.

I'm trying to write a program that converts 8 analogue inputs to digital values. I have succeeded in doing so. Now I want to make the conversion stop, when I press the button RB0. But I have tried several methods and failed. If I am not wrong, I'm supposed to use an external interrupt to trigger this. But I have failed in writing a working code for that too. As you can see below in my code, towards the last bit there, after the loop, I want to show the string that says 'COMPLETED' on my LCD. But I cannot seem to break from the adc loop.

Code:
#include <p18F4520.h>
#include <delays.h>
#include <stdio.h>
#include <system4520.h>
#include <adc.h>
#include <pwm.h>

void Write_Voltage(int hex_value)
{
	int t1;
	
	t1 = hex_value/100;
	if(!(t1 == '0'))
	{
		WriteC(getchar(t1));
	}
	else
	{
		WriteC(' ');
	}
	WriteC('.');
	t1 = ((hex_value%100)/10);
	WriteC(getchar(t1));
	t1 = ((hex_value%100)%10);
	WriteC(getchar(t1));
	WriteC(' ');
}

int Timer_Interrupt(int count)
{
		
	TMR0H = count/256;
	TMR0L = count%256;
	
	INTCONbits.TMR0IF = 0;	// reset TMR0 overflow Interrupt Flag
	T0CONbits.TMR0ON = 1; 	// start TMR0

	//wait for overflow i.e. TMR0 interrupt flag
	while(INTCONbits.TMR0IF == 0) // this is Polling
	{
		;
	}
}

void buzz (void)
{
	Delay100TCYx(50);
	OpenPWM1(158);
	SetDCPWM1(50);

	Delay100TCYx(50);
	OpenPWM1(158);
	SetDCPWM1(50);

	SetDCPWM1(0);
}

//int adc (int sample_rate)
void main (void)
{
	char ADC_text[16] = "VOLTAGE   =    ";
	char ADC_text2[16] = "COMPLETED";
//	int adc0, adc1, adc2, adc3, adc4, adc5, adc6, adc7, count;
	int adc0, adc1, adc2, adc3, adc4, adc5, adc6, adc7, count, sample_rate;
	

	// All input ports for the A/D converter
	TRISAbits.TRISA0 = 1;
	TRISAbits.TRISA1 = 1;
	TRISAbits.TRISA2 = 1;
	TRISAbits.TRISA3 = 1;
	TRISAbits.TRISA5 = 1;
	TRISEbits.TRISE0 = 1;
	TRISEbits.TRISE1 = 1;
	TRISEbits.TRISE2 = 1;


	
	// Initializing LCD
	lcd_init();

	//ADCON1 to -15 VREF
	ADCON1 = 0b00000010;

	//Start ADC conversion
	WriteS(ADC_text);

	sample_rate = 20;


	if(sample_rate == 10)
	{
		T0CON = 0x00000001;
		count = 24036;
	}
	else if(sample_rate == 20)
	{
		T0CON = 0x00000010;
		count = 24286;
	}
	else
	{
		T0CON = 0x00000010;
		count = 3036;
	}
	
	while (1)
	{
		// Give the ADC time to get ready.
      	Delay100TCYx (2);
		
		//On A/D converter
		ADCON0bits.GO = 1;

		while (ADCON0bits.GO);
		
		ADCON0 = 0b00000011;
		
		Delay100TCYx (2);
		adc0 = ADRESH;
		
		cursor_set(0,8);
		WriteC('0');
		cursor_set(0,12);
		Write_Voltage((adc0)/0.51);
		Delay100TCYx (100);
		
		
		Timer_Interrupt(count);


		ADCON0 = 0b00000111;	
		
		Delay100TCYx (2);
		adc1 = ADRESH;

		cursor_set(0,8);
		WriteC('1');
		cursor_set(0,12);
		Write_Voltage((adc1)/0.51);
		Delay100TCYx (100);
	
		
		Timer_Interrupt(count);
		

		ADCON0 = 0b00001011;

		
		Delay100TCYx (2);
		adc2 = ADRESH;
		
		cursor_set(0,8);
		WriteC('2');
		cursor_set(0,12);
		Write_Voltage((adc2)/0.51);
		Delay100TCYx (100);
		

		Timer_Interrupt(count);

		
		ADCON0 = 0b00001111;	
		
		Delay100TCYx (2);
		adc3 = ADRESH;

		cursor_set(0,8);
		WriteC('3');
		cursor_set(0,12);
		Write_Voltage((adc3)/0.51);
		Delay100TCYx (100);
		

		Timer_Interrupt(count);


		ADCON0 = 0b00010011;
		
		Delay100TCYx (2);
		adc4 = ADRESH;
		
		cursor_set(0,8);
		WriteC('4');
		cursor_set(0,12);
		Write_Voltage((adc4)/0.51);
		Delay100TCYx (100);
		
		
		Timer_Interrupt(count);
		

		ADCON0 = 0b00010111;	
		
		Delay100TCYx (2);
		adc5 = ADRESH;

		cursor_set(0,8);
		WriteC('5');
		cursor_set(0,12);
		Write_Voltage((adc5)/0.51);
		Delay100TCYx (100);
	
		
		Timer_Interrupt(count);
		

		ADCON0 = 0b00011011;

		
		Delay100TCYx (2);
		adc6 = ADRESH;
		
		cursor_set(0,8);
		WriteC('6');
		cursor_set(0,12);
		Write_Voltage((adc6)/0.51);
		Delay100TCYx (100);
		

		Timer_Interrupt(count);

		
		ADCON0 = 0b00011111;	
		
		Delay100TCYx (2);
		adc7 = ADRESH;

		cursor_set(0,8);
		WriteC('7');
		cursor_set(0,12);
		Write_Voltage((adc7)/0.51);
		Delay100TCYx (100);
		
		Timer_Interrupt(count);
		
		if(((adc0)/0.51) > 350 || ((adc1)/0.51) > 350 
		|| ((adc2)/0.51) > 350 || ((adc3)/0.51) > 350 
		|| ((adc4)/0.51) > 350 || ((adc5)/0.51) > 350 
		|| ((adc6)/0.51) > 350 || ((adc7)/0.51) > 350)
		{
			buzz();
		}
	}
	
	clear_screen();
	WriteS(ADC_text2);

}

Hope to hear from you guys soon.
Thanks.
 
Hi.

I'm trying to write a program that converts 8 analogue inputs to digital values. I have succeeded in doing so. Now I want to make the conversion stop, when I press the button RB0. But I have tried several methods and failed. If I am not wrong, I'm supposed to use an external interrupt to trigger this. But I have failed in writing a working code for that too. As you can see below in my code, towards the last bit there, after the loop, I want to show the string that says 'COMPLETED' on my LCD. But I cannot seem to break from the adc loop.

Code:
#include <p18F4520.h>
#include <delays.h>
#include <stdio.h>
#include <system4520.h>
#include <adc.h>
#include <pwm.h>

void Write_Voltage(int hex_value)
{
	int t1;
	
	t1 = hex_value/100;
	if(!(t1 == '0'))
	{
		WriteC(getchar(t1));
	}
	else
	{
		WriteC(' ');
	}
	WriteC('.');
	t1 = ((hex_value%100)/10);
	WriteC(getchar(t1));
	t1 = ((hex_value%100)%10);
	WriteC(getchar(t1));
	WriteC(' ');
}

int Timer_Interrupt(int count)
{
		
	TMR0H = count/256;
	TMR0L = count%256;
	
	INTCONbits.TMR0IF = 0;	// reset TMR0 overflow Interrupt Flag
	T0CONbits.TMR0ON = 1; 	// start TMR0

	//wait for overflow i.e. TMR0 interrupt flag
	while(INTCONbits.TMR0IF == 0) // this is Polling
	{
		;
	}
}

void buzz (void)
{
	Delay100TCYx(50);
	OpenPWM1(158);
	SetDCPWM1(50);

	Delay100TCYx(50);
	OpenPWM1(158);
	SetDCPWM1(50);

	SetDCPWM1(0);
}

//int adc (int sample_rate)
void main (void)
{
	char ADC_text[16] = "VOLTAGE   =    ";
	char ADC_text2[16] = "COMPLETED";
//	int adc0, adc1, adc2, adc3, adc4, adc5, adc6, adc7, count;
	int adc0, adc1, adc2, adc3, adc4, adc5, adc6, adc7, count, sample_rate;
	

	// All input ports for the A/D converter
	TRISAbits.TRISA0 = 1;
	TRISAbits.TRISA1 = 1;
	TRISAbits.TRISA2 = 1;
	TRISAbits.TRISA3 = 1;
	TRISAbits.TRISA5 = 1;
	TRISEbits.TRISE0 = 1;
	TRISEbits.TRISE1 = 1;
	TRISEbits.TRISE2 = 1;


	
	// Initializing LCD
	lcd_init();

	//ADCON1 to -15 VREF
	ADCON1 = 0b00000010;

	//Start ADC conversion
	WriteS(ADC_text);

	sample_rate = 20;


	if(sample_rate == 10)
	{
		T0CON = 0x00000001;
		count = 24036;
	}
	else if(sample_rate == 20)
	{
		T0CON = 0x00000010;
		count = 24286;
	}
	else
	{
		T0CON = 0x00000010;
		count = 3036;
	}
	
	while (1)
	{
		// Give the ADC time to get ready.
      	Delay100TCYx (2);
		
		//On A/D converter
		ADCON0bits.GO = 1;

		while (ADCON0bits.GO);
		
		ADCON0 = 0b00000011;
		
		Delay100TCYx (2);
		adc0 = ADRESH;
		
		cursor_set(0,8);
		WriteC('0');
		cursor_set(0,12);
		Write_Voltage((adc0)/0.51);
		Delay100TCYx (100);
		
		
		Timer_Interrupt(count);


		ADCON0 = 0b00000111;	
		
		Delay100TCYx (2);
		adc1 = ADRESH;

		cursor_set(0,8);
		WriteC('1');
		cursor_set(0,12);
		Write_Voltage((adc1)/0.51);
		Delay100TCYx (100);
	
		
		Timer_Interrupt(count);
		

		ADCON0 = 0b00001011;

		
		Delay100TCYx (2);
		adc2 = ADRESH;
		
		cursor_set(0,8);
		WriteC('2');
		cursor_set(0,12);
		Write_Voltage((adc2)/0.51);
		Delay100TCYx (100);
		

		Timer_Interrupt(count);

		
		ADCON0 = 0b00001111;	
		
		Delay100TCYx (2);
		adc3 = ADRESH;

		cursor_set(0,8);
		WriteC('3');
		cursor_set(0,12);
		Write_Voltage((adc3)/0.51);
		Delay100TCYx (100);
		

		Timer_Interrupt(count);


		ADCON0 = 0b00010011;
		
		Delay100TCYx (2);
		adc4 = ADRESH;
		
		cursor_set(0,8);
		WriteC('4');
		cursor_set(0,12);
		Write_Voltage((adc4)/0.51);
		Delay100TCYx (100);
		
		
		Timer_Interrupt(count);
		

		ADCON0 = 0b00010111;	
		
		Delay100TCYx (2);
		adc5 = ADRESH;

		cursor_set(0,8);
		WriteC('5');
		cursor_set(0,12);
		Write_Voltage((adc5)/0.51);
		Delay100TCYx (100);
	
		
		Timer_Interrupt(count);
		

		ADCON0 = 0b00011011;

		
		Delay100TCYx (2);
		adc6 = ADRESH;
		
		cursor_set(0,8);
		WriteC('6');
		cursor_set(0,12);
		Write_Voltage((adc6)/0.51);
		Delay100TCYx (100);
		

		Timer_Interrupt(count);

		
		ADCON0 = 0b00011111;	
		
		Delay100TCYx (2);
		adc7 = ADRESH;

		cursor_set(0,8);
		WriteC('7');
		cursor_set(0,12);
		Write_Voltage((adc7)/0.51);
		Delay100TCYx (100);
		
		Timer_Interrupt(count);
		
		if(((adc0)/0.51) > 350 || ((adc1)/0.51) > 350 
		|| ((adc2)/0.51) > 350 || ((adc3)/0.51) > 350 
		|| ((adc4)/0.51) > 350 || ((adc5)/0.51) > 350 
		|| ((adc6)/0.51) > 350 || ((adc7)/0.51) > 350)
		{
			buzz();
		}
	}
	
	clear_screen();
	WriteS(ADC_text2);

}

Hope to hear from you guys soon.
Thanks.

Hi Samaan. Welcome to ETO! :)

You could use an interrupt for this, but in this case it might be easier to simply poll RB0. Is this C18? If so, you could simply say "if(PORTBbits.RB0==1) break;" to break out of the loop. If you put that "if" within the loop, if it reads true even once, it will break out of the loop and continue to the end of the program.

Hope this helps.
Regards,
Der Strom
 
Is this C18? If so, you could simply say "if(PORTBbits.RB0==1) break;" to break out of the loop. If you put that "if" within the loop, if it reads true even once, it will break out of the loop and continue to the end of the program.

If you do this, you might not see anything different happening because when you break out from the loop the execution continues to the end of the program memory and resets the microcontroller (and eventually enters the infinite loop again).

Now I want to make the conversion stop, when I press the button RB0. But I have tried several methods and failed.
I believe you may have succeeded in breaking out from the loop. You just have not seen the results because the chip resets so fast.

Try adding another infinite loop after "WriteS(ADC_text2);" call to the end of your main-function. This is fast and dirty solution, but if it works, you have located the problem.
 
Last edited:
If you do this, you might not see anything different happening because when you break out from the loop the execution continues to the end of the program memory and resets the microcontroller (and eventually enters the infinite loop again).


I believe you may have succeeded in breaking out from the loop. You just have not seen the results because the chip resets so fast.

Hmm, good point. I forgot the chip resets automatically. You can change that by putting a while(1); at the end--it gets stuck in an infinite loop, doing nothing, until the chip is reset manually.
 
Place this in your loop:

Code:
if(_RB0){
    WriteS(ADC_text2);
    while(1);
}

You can even turn off all interrupts and sleep (instead of the while(1)), if your micro supports it.

As long as your switch is active high.

Not sure if "_RB0" will work for you, it works in C32.
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top