Interrupt break in mid of loop or at any where you want to

Go To Last Post
39 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Friends i need your help,

condition is. i used timer interrupt and call it in every 50 ms or something, then after all conditions and situations it comes to an point where i want that my loop will end and start main program from where i want to start.

but whenever i call that main function loop (the function i m calling from main during interrupt on going) it remains in interrupt routine but working as main (like endless interrupt loop) beacuse the function i'm calling is endless in main. and coz of this i can't call another interrupt.

hope i did good to elaborate my sitaution.

please help

thank you.

This topic has a solution.

Manish verma

Last Edited: Tue. Aug 29, 2017 - 05:09 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No idea what you are talking about, show your code. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Please provide a minimal code example that can be compiled and provide more detail on what you want the code to accomplish.

Typically, you do not want to call any functions from within an ISR. Just set a flag within the ISR and then on return from the ISR let the main loop take action based upon the flag being set (or not).

David (aka frog_jr)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ISR (TIMER1_OVF_vect)    // Timer1 ISR

{

   unsigned char val;

  

   if(PINA!=0x1f)             // if button pressed 

        {

val=PINA;                    // button number or pin number stored

button(val);                // value passed to a function

        }

      TCNT1 = 63974;

}

Manish verma

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Did you not read post #3 ?

frog_jr wrote:
Please provide a minimal code example that can be compiled

The code you provided cannot be compiled because it is incomplete.

 

provide more detail on what you want the code to accomplish.

missing

 

you do not want to call any functions from within an ISR

You are calling a function from within your ISR - don't do that!

 

Instead:

Just set a flag within the ISR and then on return from the ISR let the main loop take action based upon the flag being set (or not).

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

[You are calling a function from within your ISR - don't do that!]

 

yes i am calling a function because i am using 4 buttons and i need every single click to be count without delay.

 

[Just set a flag within the ISR and then on return from the ISR let the main loop take action based upon the flag being set (or not).]

 

Main is busy though because in main i called an endless loop so it never came out of loop and that statement always remains unusable.

Manish verma

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So go back to providing a complete minimal example that illustrates your problem and that people can look at and build for themselves - as requested in #3.

 

We also need a clear description of what you are trying to achieve.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

instead of codes i try to explain u the process ok. lets see if works beacuse source code is dependent of eachother and too long....hope u understand thats y unable to share the minimal code.

Manish verma

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Start->Main->Interuupt intialization->endlessloop->button press-> interrupt call->button sense->count increased->count of 1 button goes conditional high->function call for furmulation->another function call for endless loop->loop requirement end->(now need to exit from interrupt)->and goes to main program endless loop.

 

this is the basic idea hope u get it.

Manish verma

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 2

Read post #2, read post #3, read full AVR datasheet.

It all starts with a mental vision.

Last Edited: Fri. Aug 25, 2017 - 12:02 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

LOL !! really ....i mean if there is any solution there then why i m here asking you guy's..? 

My main moto to ask this question is to get logic and i don't think so that any datasheet gonna give me that but thanks anyways.

Manish verma

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You are the one looking for help, not us. The way to get help is to post your complete code and we'll tell you how to design it better to achieve what you want. Your choice. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Seems like you want to do some bad juju. You REALLY don't want the isr to swap tasks. The 'usual' technique for handling pushbuttons is to use a regular timer interrupt (this looks like you're doing already) but looking at your code snippet, you're reloading TCNT - use the timer CTC mode where the hardware does it for you. In the timer tick isr, you debounce your pushbuttons and put the key presses into a FIFO buffer. You main() code can then read keypresses from the FIFO buffer and process them.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

and coz of this i can't call another interrupt.

I think maybe you've misunderstood the interrupt mechanism.  You don't 'call' interrupts.  They are serviced as they occur.

 

It's going to be really hard to help you if you insist on ignoring the advice you're given by those from whom you've solicited that help. 

 

EDIT: sp

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Sat. Aug 26, 2017 - 03:20 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

staring.net@gmail.com wrote:
instead of codes i try to explain u 

Like clawson in #2, I find you "explanations" incomprehensible.

 

This is probably just down to the language barrier.

 

Therefore the only option left is to use something that is clear & unambiguous and that we all understand - and that would be 'C' source code.

 

Another option, instead of trying to describe how your code runs (or how you want it to run), would be to describe the goal that you're trying to achieve.

 

See: http://www.catb.org/~esr/faqs/sm...

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I write programs that have a LOT going on in the main() endless loop. I have never had the problems you describe. Here is what I do:

 

volatile uint8_t ButtonState;

ISR (TIMER1_OVF_vect)    // Timer1 ISR
{
    ButtonState = PINA;
}

int main(void) {
  //lots of init stuff here

  while(1) {

      if (ButtonState != 0) { //will only happen once every 50 ms
          //process the button push
          ButtonState = 0;  //its been processed
      }  //end if ButtonState

      //rest of stuff that the infinite loop does

  } //end while(1)

}  //end main()

By the way, this is what it looks like when you use the code button that looks like "<>"!

 

As a side note on code execution, you say that you want button pushes processed instantaneously. Yet, the button state is checked only once every 50ms. To me, that sounds like a contradiction. You can check and process a button with your code, and if a button is pushed immediately after the ISR executes, there is still another 50ms until the next time it is checked. That is hardly a recipe for "instantaneous". Besides, human users can barely detect anything faster than 100ms, so 50ms is instantaneous enough for me. Further, the main loop will surely take far less than 50ms to loop, each time. So, the main loop will NOT be the response limiter.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

Last Edited: Fri. Aug 25, 2017 - 05:47 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OP is doing lots wrong, but despite his statement,

he is not calling an ISR.

His "calling" seems to mean "invoking as a result of an interrupt".

 

OP seems unfamiliar with the concept of debouncing.

OP seems to believe he needs a much lower latency than he does.

International Theophysical Year seems to have been forgotten..
Anyone remember the song Jukebox Band?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve wrote:
OP seems unfamiliar with the concept of debouncing.
Which seems to make it an appropriate time to mention Danni's debounce routine

David (aka frog_jr)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

frog_jr wrote:

skeeve wrote:
OP seems unfamiliar with the concept of debouncing.
Which seems to make it an appropriate time to mention Danni's debounce routine

Before introducing the "how to", I'd recommend re-enforcing the "why we do it"...

http://www.ganssle.com/debouncin...

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But, before even that, the OP needs to get some of the concepts of code execution better understood.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

guy's listen i m very newbie here.....and i think i really need lot to learn .....hope u will help me.

 

Manish verma

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

We are trying. Does my example code help at all?

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes they did....but not much.... I'll show you my full code please tell how to improve them and how can I do it another or best way......but I'll be able to share after some time because right now I don't have the codes I've to rewrite them unfortunately.

Manish verma

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

staring.net@gmail.com wrote:
guy's listen i m very newbie here.....and i think i really need lot to learn .....hope u will help me.

 

Re-read post #2

Re-read post #3

Act upon it.

Then we can help.

 

It is obvious you are struggling with programming and you are struggling with English.

If you post a working example including the main() function, then we have a much better idea of what you are trying to do wrong.

Someone here will probably modify it into a reasonably good working example.

Paul van der Hoeven.
Bunch of old projects with AVR's:
http://www.hoevendesign.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Reading between the lines (not that there are that many). I suspect the OP problem is this:

 

void main (void)
{
    init_some_ports_etc();

    for (;;) {

        if (keyDown)
            debounce_and_handleKey() /* Could take 100ms */

        if (UART_Character)
            command_interpeter() /* Could take 100ms */

        take_ADC_reading() /* Takes 500ms */
        flashLED() /* Takes 200ms */

        bleep /* Takes 500ms */
    }
}

Here if he presses a key he has to wait for the calendar to change before its acted upon. Therefore he tries to process the key in his IRQ.

 

Jack Ganssle's site http://www.ganssle.com is an absolute goldmine and remember reading an article on this design problem but cannot find it. Other freaks may remember better than me.

 

Last Edited: Sat. Aug 26, 2017 - 11:41 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

N.Winterbottom wrote:
Here if he presses a key he has to wait for the calendar to change before its acted upon. Therefore he tries to process the key in his IRQ.

???  You are losing me.  Are you referring to the "could take 100 ms"?

 

 

You still need to keep your head about you.  You [real people] don't sit in one place for 100ms.  You generally don't even care about "key down" -- periodically, the states of the inputs are gathered, and entered into the debounce mechanism.   The mechanism grinds up the new states from the input hopper when the handle is cranked.  In the output hopper appears the confirmed/debounced states.  If you have the deluxe model mechanism, then the machine's output also provides you with rising and falling edges, and duration information for inputs held in a certain state.

 

N.Winterbottom wrote:
...if he presses a key...

In general, "he" >>has not<< 'pressed a key' when you see keydown.  It is only important when it is confirmed. 

 

OP hasn't given us any hint on why things need to be done "without delay", and what is considered no delay.  If indeed you are processing high-speed encoder edges, then you need to get ready for the next edge within microseconds and the edges must be clean.  No debounce mechanism.

 

If the switch in question causes a nuclear missile launch when pressed, do you want to launch that missle "without delay" when you see a  noise spike, or do you want to wait for a confirmed-good change of state?

 

If you have a big wall-mounted mushroom-headed e-stop button, then you need a monster debounce -- that is the only device in my experience where 4x 10ms wasn't enough.

 

Nearly all other cases fall between, and you are always 'behind' by the debounce time.  It rarely matters.

 

One can construct hybrid mechanisms that 'guess' at what the state will probably be after debounce.  Example:   An app mostly sleeping waiting for inputs to change, and when they do, send a wireless message.  Intruder alert?  Like that.

 

So when you see the "key down" you awaken.  The radio warmup time might well be as long as the debounce interval, so you start warming it up, guessing that the change of input state will be confirmed.

 

If confirmed, send the message and proceeed as normal.  If not confirmed, shut everything down and go back to sleep.

 

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
??? You are losing me. Are you referring to the "could take 100 ms"?

No I meant each cycle of the OP forever loop takes an excessively long time making his design irresponsive. He'd like to break out of his loop to handle a keypress quicker.

 

I would have thought the OP would have responded by now and we'd know for sure

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

//Well this just an rough program i made in hurry....hope u don't mind.

 

 

#define numberOfButtons 5                 //5 buttons using

#define DATA_PORT PORTB                 // LCD Data PORT

#define ThreePIN        PORTA             //LCD RW, RS, E PIN PORT

#define RS              5

#define RW              6

#define E               7

#define MAX_vehicles    10              //My Variable for MAX LIMIT

#define fix_time        8                   // My variable for Fix time used

#include<avr/io.h>

#include<util/delay.h>

#include<avr/lcd.h>                     //Pre defined library used 

#include<avr/buttonpress.h>         //pre defined library used for putton press

#include<avr/interrupt.h>          //Interrupt library

 

unsigned char counta=0;                // some variables defined

unsigned char countb=0;

unsigned char countc=0; 

unsigned char countd=0;

unsigned char counte=0;

unsigned char gtim[]={7,7,7,7};      //an array for 4 variables 

unsigned char ytim=3;

unsigned char finalvalue;

unsigned char i=0;

 

void button(unsigned char val);

void display();

void firstcycle();

void secondcycle();

void thirdcycle();

void fourthcycle();

void logic();

void timeslicecycle();

void formula(unsigned char current_count, unsigned char i);

void firstlogiccycle();

void secondlogiccycle();

void thirdlogiccycle();

void fourthlogiccycle();

 

ISR (TIMER1_OVF_vect)    // Timer1 ISR                 // calling ISR in every sec ,as if any button presses will be count

{

   unsigned char val;

  

   if(PINA!=0x1f)

        {

val=PINA;                                                         // DATA of PINA stored in val variable

button(val);

        }

      TCNT1 = 63974;

}

 

int main()

{

   DDRA=0xe0;

   PORTA=0x1f;

   DDRB=0xff;

   PORTB=0x00;

   DDRC=0xff;

   PORTC=0x00;

   DDRD=0xff;

   PORTD=0x00;

   

   TCNT1 = 63974;   // for 1 sec at 16 MHz

 

TCCR1A = 0x00;

TCCR1B =(1<<CS12); // Timer mode with 256 prescler

TIMSK = (1 << TOIE1) ;   // Enable timer1 overflow interrupt(TOIE1)

 

   lcd_init();  

   

   send_a_string("WELCOME");     //shows welcome on screen of lcd Ist

   _delay_ms(500);

   send_a_command(0x01);     // clear lcd screen

   

   PORTC=1<<5;                     // make pin 5 high

    sei();                               //interrupt enable

   

   firstcycle();                      //calling endless loop

   

   while(1)

   { 

     

   }

}

void button(unsigned char val)

{

   send_a_command(0x80);

   switch(val)

   {

      case 0x1e:

         counta++;

       if(counta>7)

         {

logic();

         }

      break;

      case 0x1d:

         countb++;

       if(countb>7)

         {

logic();

         }   

      break;

      case 0x1b:

         countc++;

       if(countc>7)

         {

logic();

         }   

      break;

      case 0x17:

         countd++;

      if(countd>7)

         {

logic();

         }  

      break;

      case 0x0f: 

         send_a_command(0x01);

         display();

      break;

   }

}

void display()

{

                    

                  send_a_command(0x80);

                  send_a_string("A=");

         send_a_integer(counta, 3);

                  send_a_string("B=");

         send_a_integer(countb, 3);

               send_a_command(0xc0);

                  send_a_string("C=");

         send_a_integer(countc, 3);

                  send_a_string("D=");

         send_a_integer(countd, 3);

                  send_a_command(0xc0);

                  

}

void firstcycle()

{

    send_a_command(0x01);

    send_a_string("A");

    PORTC=1<<2;

   if(PORTC==1<<2)

   {

     

      PORTD=1<<1;

      PORTC=1<<6|1<<3|1<<2;

      _delay_ms(5000);

      PORTC=1<<6|1<<3|1<<1;

      _delay_ms(3000);

      secondcycle();

   }

}

void secondcycle()

{

   send_a_command(0x01);

   send_a_string("B");

   PORTD=1<<3;

   if(PORTD==1<<3)

   {

      PORTD=1<<3;

      PORTC=1<<0|1<<3|1<<6;

      _delay_ms(5000);

      PORTD=1<<2;

      PORTC=1<<0|1<<3|1<<6;

      _delay_ms(3000);

       PORTD=1<<0;

      thirdcycle();

   }

}

void thirdcycle()

{

    send_a_command(0x01);

   send_a_string("C");

   if(PORTD==1<<0)

   {

      PORTD=1<<0|1<<1;

      PORTC=1<<0|1<<3;

      _delay_ms(5000);

      PORTD=1<<1;

      PORTC=1<<0|1<<3|1<<7;

      _delay_ms(3000); 

      fourthcycle();

      }

}

void fourthcycle()

{

    send_a_command(0x01);

   send_a_string("D");

   PORTC=1<<5;

   if(PINC==1<<5)

   {

      PORTD=1<<1;

      PORTC=1<<6|1<<0|1<<5;

      _delay_ms(5000);

      PORTC=1<<6|1<<0|1<<4;

      _delay_ms(3000);  

      firstcycle();

   }

}

void logic()

   unsigned int one,two;

   one= ( counta>countb ) ? counta : countb;

   two= (countc>countd) ? countc:countd;

   finalvalue=(one>two) ? one:two;

   send_a_integer(finalvalue,2);

   send_a_command(0x01);

   if(finalvalue==counta)

     {

      send_a_string("count high at A"); 

      send_a_command(0x01);

      timeslicecycle();

     }

     else if(finalvalue==countb)

     {

      send_a_string("count high at B");

      send_a_command(0x01);

      timeslicecycle();

     }

     else if(finalvalue==countc)

     {

      send_a_string("count high at C");

      send_a_command(0x01);

      timeslicecycle();

     }

     else if(finalvalue==countd)

     {

      send_a_string("count high at D"); 

      send_a_command(0x01);

      timeslicecycle();

     }

}

  void timeslicecycle()

  {

  formula(counta,0);

        

  formula(countb,1);

  formula(countc,2);

  formula(countd,3);

 

  firstlogiccycle();

  }

  void formula(unsigned char current_count,unsigned char i)

  {

     if((current_count==0)|(current_count==1))

     {

gtim[i]=1;

ytim=2;

send_a_string("i="); send_a_integer(i,2);

send_a_command(0xc0);

        send_a_string("gtim[i]="); send_a_integer(gtim[i],2);

send_a_command(0x01);

     }

     else

     {

     gtim[i]=((fix_time*current_count)/MAX_vehicles);

     ytim=2;

     gtim[i]=gtim[i]-ytim; 

     send_a_string("i="); send_a_integer(i,2);

     send_a_command(0xc0);

     send_a_string("gtim[i]="); send_a_integer(gtim[i],2);

     send_a_command(0x01);

     }

  }

void firstlogiccycle()

{

   PORTC=1<<2;

   if(PORTC==1<<2)      

   { 

      send_a_command(0x01);

      send_a_string("A1");

      PORTD=1<<1;

      PORTC=1<<6|1<<3|1<<2;

      _delay_ms(gtim[0]*1000);

      PORTC=1<<6|1<<3|1<<1;

      _delay_ms(ytim*1000);

      secondlogiccycle();

   }

}

void secondlogiccycle()

   {

      send_a_command(0x01);

      send_a_string("B1");   

      PORTD=1<<3;

      if(PORTD==1<<3)

         {

           PORTD=1<<3;

           PORTC=1<<0|1<<3|1<<6;

           _delay_ms(gtim[1]*1000);

           PORTD=1<<2;

           PORTC=1<<0|1<<3|1<<6;

           _delay_ms(ytim*1000);

           PORTD=1<<0;

           thirdlogiccycle();

         }   

    }

void thirdlogiccycle()

   {

        send_a_command(0x01);

        send_a_string("C1");

        PORTD=1<<0;

        if(PORTD==1<<0)

           {

              PORTD=1<<0|1<<1;

              PORTC=1<<0|1<<3;

              _delay_ms(gtim[2]*1000);

              PORTD=1<<1;

              PORTC=1<<0|1<<3|1<<7;

              _delay_ms(ytim*1000);  

              PORTC=1<<5;

              fourthlogiccycle();

           }

  }

void fourthlogiccycle()

   {

      send_a_command(0x01);

      send_a_string("D1");

      PORTC=1<<5;

      if(PINC==1<<5)

           {

             PORTD=1<<1;

             PORTC=1<<6|1<<0|1<<5;

             _delay_ms(gtim[3]*1000);

             PORTC=1<<6|1<<0|1<<4;

             _delay_ms(ytim*1000);

    counta=0;

             countb=0;

             countc=0;

             countd=0;

     cli();

    firstcycle();

           }

    }

Manish verma

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Please help me with above program, whenever counta|b|c|d any of them goes high i.e above 7, my firstlogiccycle starts but in the end when it completes fourthlogiccycle i want it to go at first logic cycle again but not wanted to remain in interrupt routine. it comes out of routine but after 8 or 10 sec(I don't know why).

Now please help.

Manish verma

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

See post #13 for suggestions. Don't run your functions from the timer isr directly. You do realise that your code really doesn't mean too much to us - there's no comments and how do we know what it is supposed to do? Also, go back and format your code using the <> button on the toolbar - this makes it easier for everyone to read.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

staring.net@gmail.com wrote:

//Well this just an rough program i made in hurry....hope u don't mind.

 

 

#define numberOfButtons 5                 //5 buttons using

#define DATA_PORT PORTB                 // LCD Data PORT

#define ThreePIN        PORTA             //LCD RW, RS, E PIN PORT

#define RS              5

#define RW              6

#define E               7

#define MAX_vehicles    10              //My Variable for MAX LIMIT

#define fix_time        8                   // My variable for Fix time used

#include<avr/io.h>

#include<util/delay.h>

#include<avr/lcd.h>                     //Pre defined library used 

#include<avr/buttonpress.h>         //pre defined library used for putton press

#include<avr/interrupt.h>          //Interrupt library

 

unsigned char counta=0;                // some variables defined

unsigned char countb=0;

unsigned char countc=0; 

unsigned char countd=0;

unsigned char counte=0;

unsigned char gtim[]={7,7,7,7};      //an array for 4 variables 

unsigned char ytim=3;

unsigned char finalvalue;

unsigned char i=0;

 

void button(unsigned char val);

void display();

void firstcycle();

void secondcycle();

void thirdcycle();

void fourthcycle();

void logic();

void timeslicecycle();

void formula(unsigned char current_count, unsigned char i);

void firstlogiccycle();

void secondlogiccycle();

void thirdlogiccycle();

void fourthlogiccycle();

 

ISR (TIMER1_OVF_vect)    // Timer1 ISR                 // calling ISR in every sec ,as if any button presses will be count

{

   unsigned char val;

  

   if(PINA!=0x1f)

        {

val=PINA;                                                         // DATA of PINA stored in val variable

button(val);

        }

      TCNT1 = 63974;

}

 

int main()

{

   DDRA=0xe0;

   PORTA=0x1f;

   DDRB=0xff;

   PORTB=0x00;

   DDRC=0xff;

   PORTC=0x00;

   DDRD=0xff;

   PORTD=0x00;

   

   TCNT1 = 63974;   // for 1 sec at 16 MHz

 

TCCR1A = 0x00;

TCCR1B =(1<<CS12); // Timer mode with 256 prescler

TIMSK = (1 << TOIE1) ;   // Enable timer1 overflow interrupt(TOIE1)

 

   lcd_init();  

   

   send_a_string("WELCOME");     //shows welcome on screen of lcd Ist

   _delay_ms(500);

   send_a_command(0x01);     // clear lcd screen

   

   PORTC=1<<5;                     // make pin 5 high

    sei();                               //interrupt enable

   

   firstcycle();                      //calling endless loop

   

   while(1)

   { 

     

   }

}

void button(unsigned char val)               // button sense and count increment function

{

   send_a_command(0x80);

   switch(val)

   {

      case 0x1e:

         counta++;

       if(counta>7)

         {

logic();

         }

      break;

      case 0x1d:

         countb++;

       if(countb>7)

         {

logic();

         }   

      break;

      case 0x1b:

         countc++;

       if(countc>7)

         {

logic();

         }   

      break;

      case 0x17:

         countd++;

      if(countd>7)

         {

logic();

         }  

      break;

      case 0x0f: 

         send_a_command(0x01);

         display();

      break;

   }

}

void display()

{

                    

                  send_a_command(0x80);                                                //If i want to see how many counts done on all...then

                                                                                                  //      i can press this button (5 button) and it displays all counts on A,B,C,D

                  send_a_string("A=");

         send_a_integer(counta, 3);

                  send_a_string("B=");

         send_a_integer(countb, 3);

               send_a_command(0xc0);

                  send_a_string("C=");

         send_a_integer(countc, 3);

                  send_a_string("D=");

         send_a_integer(countd, 3);

                  send_a_command(0xc0);

                  

}

void firstcycle()

{

    send_a_command(0x01);

    send_a_string("A");                                // this is the first cycle which is called in main and it is endless

                                                               //(1st cycle, 2nd cycle, 3rd cycle, 4th cycle then 1st cycle repeats again and again)

    PORTC=1<<2;

   if(PORTC==1<<2)

   {

     

      PORTD=1<<1;

      PORTC=1<<6|1<<3|1<<2;

      _delay_ms(5000);

      PORTC=1<<6|1<<3|1<<1;

      _delay_ms(3000);

      secondcycle();

   }

}

void secondcycle()

{

   send_a_command(0x01);

   send_a_string("B");

   PORTD=1<<3;

   if(PORTD==1<<3)

   {

      PORTD=1<<3;

      PORTC=1<<0|1<<3|1<<6;

      _delay_ms(5000);

      PORTD=1<<2;

      PORTC=1<<0|1<<3|1<<6;

      _delay_ms(3000);

       PORTD=1<<0;

      thirdcycle();

   }

}

void thirdcycle()

{

    send_a_command(0x01);

   send_a_string("C");

   if(PORTD==1<<0)

   {

      PORTD=1<<0|1<<1;

      PORTC=1<<0|1<<3;

      _delay_ms(5000);

      PORTD=1<<1;

      PORTC=1<<0|1<<3|1<<7;

      _delay_ms(3000); 

      fourthcycle();

      }

}

void fourthcycle()

{

    send_a_command(0x01);

   send_a_string("D");

   PORTC=1<<5;

   if(PINC==1<<5)

   {

      PORTD=1<<1;

      PORTC=1<<6|1<<0|1<<5;

      _delay_ms(5000);

      PORTC=1<<6|1<<0|1<<4;

      _delay_ms(3000);  

      firstcycle();

   }

}

void logic()

   unsigned int one,two;

   one= ( counta>countb ) ? counta : countb;

   two= (countc>countd) ? countc:countd;

   finalvalue=(one>two) ? one:two;

   send_a_integer(finalvalue,2);

   send_a_command(0x01);

   if(finalvalue==counta)                                       // if count goes high then this function determines which

                                                                         //count goes high and according to result it displays on lcd and call timeslie functon

     {

      send_a_string("count high at A"); 

      send_a_command(0x01);

      timeslicecycle();

     }

     else if(finalvalue==countb)

     {

      send_a_string("count high at B");

      send_a_command(0x01);

      timeslicecycle();

     }

     else if(finalvalue==countc)

     {

      send_a_string("count high at C");

      send_a_command(0x01);

      timeslicecycle();

     }

     else if(finalvalue==countd)

     {

      send_a_string("count high at D"); 

      send_a_command(0x01);

      timeslicecycle();

     }

}

  void timeslicecycle()                     //in this function 4 time a function called with different values

                                                  //and in last another function called (name firstlogiccycle)

  {

  formula(counta,0);

        

  formula(countb,1);

  formula(countc,2);

  formula(countd,3);

 

  firstlogiccycle();

  }

  void formula(unsigned char current_count,unsigned char i)

  {

     if((current_count==0)|(current_count==1))

     {

gtim[i]=1;

ytim=2;

send_a_string("i="); send_a_integer(i,2);

send_a_command(0xc0);

        send_a_string("gtim[i]="); send_a_integer(gtim[i],2);     //this function according to data use formula to calculate and store value 

send_a_command(0x01);

     }

     else

     {

     gtim[i]=((fix_time*current_count)/MAX_vehicles);

     ytim=2;

     gtim[i]=gtim[i]-ytim; 

     send_a_string("i="); send_a_integer(i,2);

     send_a_command(0xc0);

     send_a_string("gtim[i]="); send_a_integer(gtim[i],2);

     send_a_command(0x01);

     }

  }

void firstlogiccycle()

{

   PORTC=1<<2;

   if(PORTC==1<<2)      

   { 

      send_a_command(0x01);

      send_a_string("A1");

      PORTD=1<<1;

      PORTC=1<<6|1<<3|1<<2;

      _delay_ms(gtim[0]*1000);                                                         //interrupt service routine endless cycle 1st cycle

      PORTC=1<<6|1<<3|1<<1;

      _delay_ms(ytim*1000);

      secondlogiccycle();

   }

}

void secondlogiccycle()

   {

      send_a_command(0x01);

      send_a_string("B1");   

      PORTD=1<<3;

      if(PORTD==1<<3)

         {

           PORTD=1<<3;

           PORTC=1<<0|1<<3|1<<6;

           _delay_ms(gtim[1]*1000);

           PORTD=1<<2;

           PORTC=1<<0|1<<3|1<<6;

           _delay_ms(ytim*1000);

           PORTD=1<<0;

           thirdlogiccycle();

         }   

    }

void thirdlogiccycle()

   {

        send_a_command(0x01);

        send_a_string("C1");

        PORTD=1<<0;

        if(PORTD==1<<0)

           {

              PORTD=1<<0|1<<1;

              PORTC=1<<0|1<<3;

              _delay_ms(gtim[2]*1000);

              PORTD=1<<1;

              PORTC=1<<0|1<<3|1<<7;

              _delay_ms(ytim*1000);  

              PORTC=1<<5;

              fourthlogiccycle();

           }

  }

void fourthlogiccycle()

   {

      send_a_command(0x01);

      send_a_string("D1");

      PORTC=1<<5;

      if(PINC==1<<5)

           {                                                              //final cycle 

             PORTD=1<<1;

             PORTC=1<<6|1<<0|1<<5;

             _delay_ms(gtim[3]*1000);

             PORTC=1<<6|1<<0|1<<4;

             _delay_ms(ytim*1000);

    counta=0;

             countb=0;

             countc=0;

             countd=0;

     cli();                           // i tried this function to stop ISR but it worked after 8-10 sec later i don't know why.

    firstcycle();                  // this is the main function where i want to go without service routine active

           }

    }


 

Manish verma

Last Edited: Mon. Aug 28, 2017 - 07:20 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why didn't you just edit your previous post? The code is supposed to go green - what button did you press?

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
firstcycle();                      //calling endless loop

Um, not really. You are effectively calling and endless recursion, which will cause stack overflow eventually!

 

PORTC=1<<2;
if(PORTC==1<<2)

PORTD=1<<3;
if(PORTD==1<<3)

PORTC=1<<2;
if(PORTC==1<<2)

PORTD=1<<3;
if(PORTD==1<<3)

PORTD=1<<0;
if(PORTD==1<<0)

PORTC=1<<5;
if(PINC==1<<5)

Some of these look quite strange.

 

General comment - try to improve your coding style:

  • Use macros
  • Try to define reusable functions that take an argument instead of duplicating same code and giving it a slightly different name (like "firstlogiccycle", "secondlogiccycle", etc)
  • Give functions sensible names (for example, what kind of function name is "formula"?!)
  • Avoid repetitive code (make loop and/or function)

/Jakob Selbing

Last Edited: Mon. Aug 28, 2017 - 07:48 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

my friend as i say i did that thing for rough ....and i used some common names to remember where i am and what i m going to do with it.

but in this case i just need to know in last at fourth logic cycle i m using cli(); and calling firstcycle() it remains in ISR for some time how to overcome from that.

Manish verma

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

staring.net@gmail.com wrote:

my friend as i say i did that thing for rough ....and i used some common names to remember where i am and what i m going to do with it.

but in this case i just need to know in last at fourth logic cycle i m using cli(); and calling firstcycle() it remains in ISR for some time how to overcome from that.

Well I am sure your intentions are good, but problem is that anyone else who reads the code will have a hard time understanding it. So that makes it even more difficult to help you.

 

staring.net@gmail.com wrote:

but in this case i just need to know in last at fourth logic cycle i m using cli(); and calling firstcycle() it remains in ISR for some time how to overcome from that.

I just explained that your code will eventually cause stack overflow. Don't you think this is quite serious? Maybe you should fix that? Maybe that is part of the solution to your issue you are seeing ("it remains in ISR for some time")?

/Jakob Selbing

Last Edited: Mon. Aug 28, 2017 - 09:32 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Manish - go and edit your post so the code is formatted correctly.

 

Then read this:

http://www.avrfreaks.net/forum/t...

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

staring.net@gmail.com wrote:
my friend as i say i did that thing for rough

Rough sums it up quite nicely; you seem to code by copy & paste.  However your example does expose the design problem underneath.

 

My supposition above was right though; your background "mainloop" takes 24s so to get some responsiveness to PINA changes you do the extensive handling in the ISR.

 

Where do you go from here?

The articles on http://www.ganssle.com and http://www.embedded.com are probably above your level and would be hard work to follow along.

 

I'm too lazy to write a tutorial - plus it's a lovely sunny bank holiday and I'm not going to spend it in front of the computer.

 

  1. You need to research maintaining a system timer tick - chain other timer variables from that and use them to replace your delays. This can speed up the cycle time of your mainloop.
  2. Learn about a state machine at its simplest level. I.e. The actions of a function depend on the value of a state variable which you modify to cause a different action to occur next time the function is called. a switch-case is commonly used for this programming pattern.
  3. Set a boolean in your ISR and defer the handling of the PINA changes to the mainloop, which will now be fast enough for good responsiveness.

 

Good luck.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

 


I just explained that your code will eventually cause stack overflow. Don't you think this is quite serious? Maybe you should fix that? Maybe that is part of the solution to your issue you are seeing ("it remains in ISR for some time")?


 

how to stop stack overflow ?

Manish verma

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you so much guy's, Now i understand most of it i reduced my codes upto half.

And yes you are right i was repeating codes instead of that i used function with arguments.

Apart from this i put my logic in main while loop which help me to acheive faster process.

 

Manish verma