Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[51] Programming in C language for 8051 Micro Controller

Status
Not open for further replies.
I just noticed another fault in your code. Interrupt functions must not use a return statement, they have an implicit return from interrupt (RETI) at the function end. Review the compiler user manual and example programs.

Calling a subroutine (function) from interrupt is possible but not suggested with 8051 due to limited available stack space. You can't call another interrupt function.
 

Hi,

When ever you enabled the interrupt, is it invoking that i.e is it entering to that interrupt handler.
Interrupt code is a special code & it should execute with low latency that's why preferred to avoid loops & function calls in the interrupt code.

- - - Updated - - -

Hi,
Sorry to interrupt you, how you got that helped me symbol please tell me.
 

In my program u can see rpm_start subroutine, in this routine i am enabling Timer 0, and my Timer 0 is used as external interrupt following edge, right?

so when negative edge is occur on Int 0 pin my interrupt subroutine is called, right?
 

Hi,

I observed in your main function after rpm_start function should give the infinite loop for eg: while(1);,
because you should give time to raise interrupt.
 

In my program u can see rpm_start subroutine, in this routine i am enabling Timer 0, and my Timer 0 is used as external interrupt following edge, right?
No. An interrupt function is assigned to a specific interrupt by the interrupt number. You have only interrupt 1 (Timer 0) and no external interrupt function in your code.
 

But interrupt 1 is only enable when on that pin following edge is occur and as counter. so when following edge is occur on Int 0 pin at that time PC is directly go to interrupt sub routine, right?

- - - Updated - - -

I want to take data from interrupt subroutine to main function or other sub routine, then how can i take?
 

Hi,

We can share data b/w interrupt routine and normal sub routine with volatile global variable or else can use function pointer with required parameters it can pass data to the subroutine.
 

I have already tried using volatile global variable but i am not success...
can u provide some example code?
 

look at my code...

In that i am taking C as global variable and that is used in interrupt subroutine and then i am using it to display that data on LCD.

But i am not able to see my data...

so what is wrong with code?

i have checked my LCD routine is working perfactly.
Code:
#include <AT89X55.H>
#include <MATH.H>
//#include <lcd.h>

sfr lcd_data_pin=0xA0;  // data port P2
sbit rs=P3^7; // Register select pin
sbit rw=P3^6; // Read write pin
sbit en=P3^5; // Enable pin

	unsigned long c,d,frequency,rpm_count,rpm;
	unsigned char d1,d2,d3,d4,d5,pulse_ov,pulse_count,lo_count;

	void delay(unsigned int msec)    //delay function
		{
			int i,j;
			for(i=0;i<msec;i++)
			for(j=0;j<1275;j++);
		}
	void lcd_command(unsigned char comm) // function to send command to LCD
		{
			lcd_data_pin=comm;
			en=1;
			rs=0;
			rw=0;
			delay(1);
			en=0;
		}
	void lcd_data(unsigned char disp)    // function to send data on LCD
		{
			lcd_data_pin=disp;
			en=1;
			rs=1;
			rw=0;
			delay(1);
			en=0;
		}

	lcd_dataa(unsigned char *disp)    // function to send string to LCD
		{
			int x;
			for(x=0;disp[x]!=0;x++)
				{
					lcd_data(disp[x]);	

				}
		}

	void lcd_ini()     //Function to inisialize the LCD
		{
			lcd_command(0x38);   
			delay(5);
			lcd_command(0x0C);       
			delay(5);

		}

		void bitsep16()
		{
			
			d = c/10;
			d1 = c%10;		// LSB
			c = d/10;
			d2 = d%10;		// LSB-1
			d = c/10;
			d3 = c%10;		// LSB-2
			c = d/10;
			d4 = d%10;		// MSB+1
			d5 = d/10;		// MSB

			d1 = d1+0x30;
			d2 = d2+0x30;
			d3 = d3+0x30;
			d4 = d4+0x30;
			d5 = d5+0x30;
		}
		void lcd()
		{

		//	c = rpm;
			bitsep16();

			lcd_command(0xC0);
			delay(5);

			lcd_data_pin=0x52;
			en=1;
			rs=1;
			rw=0;
			delay(1);
			en=0;

			lcd_data_pin=0x50;
			en=1;
			rs=1;
			rw=0;
			delay(1);
			en=0;

			lcd_data_pin=0x4D;
			en=1;
			rs=1;
			rw=0;
			delay(1);
			en=0;

			lcd_data_pin=0x3a;
			en=1;
			rs=1;
			rw=0;
			delay(1);
			en=0;

			lcd_data_pin=d4;
			en=1;
			rs=1;
			rw=0;
			delay(1);
			en=0;

			lcd_data_pin=d3;
			en=1;
			rs=1;
			rw=0;
			delay(1);
			en=0;
	
			lcd_data_pin=d2;
			en=1;
			rs=1;
			rw=0;
			delay(1);
			en=0;

			lcd_data_pin=d1;
			en=1;
			rs=1;
			rw=0;
			delay(1);
			en=0;

			lcd_data_pin=0x20;
			en=1;
			rs=1;
			rw=0;
			delay(1);
			en=0;

			lcd_data_pin=0x20;
			en=1;
			rs=1;
			rw=0;
			delay(1);
			en=0;

			lcd_data_pin=0x20;
			en=1;
			rs=1;
			rw=0;
			delay(1);
			en=0;

			lcd_data_pin=0x20;
			en=1;
			rs=1;
			rw=0;
			delay(1);
			en=0;

			lcd_data_pin=0x20;
			en=1;
			rs=1;
			rw=0;
			delay(1);
			en=0;

			lcd_data_pin=0x20;
			en=1;
			rs=1;
			rw=0;
			delay(1);
			en=0;

			lcd_data_pin=0x20;
			en=1;
			rs=1;
			rw=0;
			delay(1);
			en=0;

			lcd_data_pin=0x20;
			en=1;
			rs=1;
			rw=0;
			delay(1);
			en=0;
			
		}
	void ISR_Timer0(void) interrupt 1
		{
			TF0 = 0x00;
			pulse_count = pulse_count++;

			if (pulse_count == 1)
				{
					pulse_ov = 0x00;
					TH1 = 0x00;
					TL1 = 0X00;
					TR1 = 1;
				}

			else
				{
					TR1 = 0;
					TR0 = 0;
					rpm_count = (65536*pulse_ov)+(256*TH1)+TL1;
					rpm = ((0x36ee8000/rpm_count)*0x3c)/0x3e8;
					pulse_count = 0;
					pulse_ov = 0;

					c = rpm;
		
			return;
				}		
			
		}

	void ISR_Timer1(void) interrupt 3
		{
			TF1 = 0;
			pulse_ov = ++pulse_ov;
			return;
		}

	void rpm_start()
		{
			pulse_ov = 0x00;
			pulse_count = 0x00;
			TH1 = 0x00;
			TL1 = 0x00;
			ET1 = 1;
			ET0 = 1;
			EA  = 1;
			TR0 = 1;
		}

	void main()
		{
			P1 = 0x00;
			lcd_ini();
			TMOD = 0x16;
			T2CON = 0x01;	

			IT0 = 0;
		//	IE0 = 1;
			EX0 = 1;
			EA = 1;

			rpm_start();
			lcd();
		}
 

But interrupt 1 is only enable when on that pin following edge is occur and as counter. so when following edge is occur on Int 0 pin at that time PC is directly go to interrupt sub routine, right?
You have been asking about external interrupt rather than counter interrupt. I see now that Timer0 is configured as counter. It will trigger the interrupt when the counter overflows from all '1' to '0', not on each counter input event.
 

Hi,

Which global variable are you taken & what it is getting highlight it, then i can understand your problem.
 

Which global variable are you taken & what it is getting highlight it, then i can understand your problem.

u can see in below code i have used Red color highlight...

Code:
#include <AT89X55.H>
#include <MATH.H>
//#include <lcd.h>

sfr lcd_data_pin=0xA0;  // data port P2
sbit rs=P3^7; // Register select pin
sbit rw=P3^6; // Read write pin
sbit en=P3^5; // Enable pin

	[COLOR="#FF0000"]unsigned long c,d,frequency,rpm_count,rpm;[/COLOR]
	unsigned char d1,d2,d3,d4,d5,pulse_ov,pulse_count,lo_count;

	void delay(unsigned int msec)    //delay function
		{
			int i,j;
			for(i=0;i<msec;i++)
			for(j=0;j<1275;j++);
		}
	void lcd_command(unsigned char comm) // function to send command to LCD
		{
			lcd_data_pin=comm;
			en=1;
			rs=0;
			rw=0;
			delay(1);
			en=0;
		}
	void lcd_data(unsigned char disp)    // function to send data on LCD
		{
			lcd_data_pin=disp;
			en=1;
			rs=1;
			rw=0;
			delay(1);
			en=0;
		}

	lcd_dataa(unsigned char *disp)    // function to send string to LCD
		{
			int x;
			for(x=0;disp[x]!=0;x++)
				{
					lcd_data(disp[x]);	

				}
		}

	void lcd_ini()     //Function to inisialize the LCD
		{
			lcd_command(0x38);   
			delay(5);
			lcd_command(0x0C);       
			delay(5);

		}

		void bitsep16()
		{
			
			[COLOR="#FF0000"]d = c/10;[/COLOR]
			d1 = c%10;		// LSB
			c = d/10;
			d2 = d%10;		// LSB-1
			d = c/10;
			d3 = c%10;		// LSB-2
			c = d/10;
			d4 = d%10;		// MSB+1
			d5 = d/10;		// MSB

			d1 = d1+0x30;
			d2 = d2+0x30;
			d3 = d3+0x30;
			d4 = d4+0x30;
			d5 = d5+0x30;
		}
		void lcd()
		{

		//	c = rpm;
			bitsep16();

			lcd_command(0xC0);
			delay(5);

			lcd_data_pin=0x52;
			en=1;
			rs=1;
			rw=0;
			delay(1);
			en=0;

			lcd_data_pin=0x50;
			en=1;
			rs=1;
			rw=0;
			delay(1);
			en=0;

			lcd_data_pin=0x4D;
			en=1;
			rs=1;
			rw=0;
			delay(1);
			en=0;

			lcd_data_pin=0x3a;
			en=1;
			rs=1;
			rw=0;
			delay(1);
			en=0;

			lcd_data_pin=d4;
			en=1;
			rs=1;
			rw=0;
			delay(1);
			en=0;

			lcd_data_pin=d3;
			en=1;
			rs=1;
			rw=0;
			delay(1);
			en=0;
	
			lcd_data_pin=d2;
			en=1;
			rs=1;
			rw=0;
			delay(1);
			en=0;

			lcd_data_pin=d1;
			en=1;
			rs=1;
			rw=0;
			delay(1);
			en=0;

			lcd_data_pin=0x20;
			en=1;
			rs=1;
			rw=0;
			delay(1);
			en=0;

			lcd_data_pin=0x20;
			en=1;
			rs=1;
			rw=0;
			delay(1);
			en=0;

			lcd_data_pin=0x20;
			en=1;
			rs=1;
			rw=0;
			delay(1);
			en=0;

			lcd_data_pin=0x20;
			en=1;
			rs=1;
			rw=0;
			delay(1);
			en=0;

			lcd_data_pin=0x20;
			en=1;
			rs=1;
			rw=0;
			delay(1);
			en=0;

			lcd_data_pin=0x20;
			en=1;
			rs=1;
			rw=0;
			delay(1);
			en=0;

			lcd_data_pin=0x20;
			en=1;
			rs=1;
			rw=0;
			delay(1);
			en=0;

			lcd_data_pin=0x20;
			en=1;
			rs=1;
			rw=0;
			delay(1);
			en=0;
			
		}
	void ISR_Timer0(void) interrupt 1
		{
			TF0 = 0x00;
			pulse_count = pulse_count++;

			if (pulse_count == 1)
				{
					pulse_ov = 0x00;
					TH1 = 0x00;
					TL1 = 0X00;
					TR1 = 1;
				}

			else
				{
					TR1 = 0;
					TR0 = 0;
					rpm_count = (65536*pulse_ov)+(256*TH1)+TL1;
					rpm = ((0x36ee8000/rpm_count)*0x3c)/0x3e8;
					pulse_count = 0;
					pulse_ov = 0;

					[COLOR="#FF0000"]c = rpm;[/COLOR]
		
			return;
				}		
			
		}

	void ISR_Timer1(void) interrupt 3
		{
			TF1 = 0;
			pulse_ov = ++pulse_ov;
			return;
		}

	void rpm_start()
		{
			pulse_ov = 0x00;
			pulse_count = 0x00;
			TH1 = 0x00;
			TL1 = 0x00;
			ET1 = 1;
			ET0 = 1;
			EA  = 1;
			TR0 = 1;
		}

	void main()
		{
			P1 = 0x00;
			lcd_ini();
			TMOD = 0x16;
			T2CON = 0x01;	

			IT0 = 0;
		//	IE0 = 1;
			EX0 = 1;
			EA = 1;

			rpm_start();
			lcd();
		}
 

yes it is working properly...i have check using on off LED...
 

Hi,
Just write infinite loop like while(1); at the end of main function & another one don't use return statement in the interrupt handler.
 

Why i have to write infinite loop in main function?
 

Hi,
It is a fundamental concept after main function, program exit from it and control return to the operating system, but in program still doing some process with interrupt handler.

That's why instead of returning the control to the OS, we should be ideal or hold the processor. It can done with infinite loop.
 
Last edited:

can u please provide some detail tutorial for ISR with return type?
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top