+ Post New Thread
Page 2 of 2 FirstFirst 1 2
Results 21 to 31 of 31
  1. #21
    Super Moderator
    Points: 30,098, Level: 42
    andre_teprom's Avatar
    Join Date
    Nov 2006
    Location
    Brazil
    Posts
    8,978
    Helped
    1138 / 1138
    Points
    30,098
    Level
    42
    Blog Entries
    9

    Re: Glow LED on specified counter values 0-500 in 89c52 uC

    How to use state machine handling delays with flags?
    By using state machine you would always return to an Idle state instead of being blocked within execution of a Delay function, in addition to the obvious advantage of having a better structured program. As you did, it is not any issue at all if blink two leds is the only thing you have to do but if you need to read for example a key pressed within 1s would not work, so it is time to you get introduced to better practices in coding; make a search on the Web for the keyword FSM ("finite state machice") and you will have insights to apply this approach on your programs.
    --------------------------------------------------------------------------------------------------
    Part of the world that you live in, You are the part that you're giving ( Renaissance )



  2. #22
    Advanced Member level 3
    Points: 3,603, Level: 14
    baileychic's Avatar
    Join Date
    Aug 2017
    Posts
    719
    Helped
    54 / 54
    Points
    3,603
    Level
    14

    Re: Glow LED on specified counter values 0-500 in 89c52 uC

    Try this.

    Code:
    volatile unsigned int Counter = 0;
    volaile unsigned int oldCounter = 0;
    
    void ext0_isr(void) interrupt 0
    { 
    	Counter++;	
    }
    
    main()
    { 
    if((Counter >= 10) && ((Counter % 15) == 10))LED1 = 1;
    elseif((Counter >= 15) && ((Counter % 10) == 0))LED2 = 1;
    delay(1000);
    LED1 = 0;
    LED2 = 0;
    }
    Still this is a blocking code. If you want non-blocking code then put this piece of code in a 1 second timer interrupt without the delay(1000) code that is just the code which is in while(1) loop into timer interrupt code.



    •   AltAdvertisement

        
       

  3. #23
    Advanced Member level 2
    Points: 4,015, Level: 14
    Achievements:
    7 years registered
    imranahmed's Avatar
    Join Date
    Dec 2011
    Location
    Karachi,Pakistan
    Posts
    650
    Helped
    3 / 3
    Points
    4,015
    Level
    14

    Re: Glow LED on specified counter values 0-500 in 89c52 uC

    Quote Originally Posted by andre_teprom View Post
    By using state machine you would always return to an Idle state instead of being blocked within execution of a Delay function, in addition to the obvious advantage of having a better structured program. As you did, it is not any issue at all if blink two leds is the only thing you have to do but if you need to read for example a key pressed within 1s would not work, so it is time to you get introduced to better practices in coding; make a search on the Web for the keyword FSM ("finite state machice") and you will have insights to apply this approach on your programs.
    I am thankful to you and inspired by you for giving good solutions.


    I did not use in code util/delay.h but wrote my own timer0 mode 1 code for approx 100usec.

    Code:
    unsigned int i,x;
    
    void delay(i)          //100usec delay
    	{
    	for(x=0 ; x<=i ; x++){
    	TMOD = 0x01;    // Timer0 mode1
    	TH0 = 0xFF; 	 //initial value for 100usec
    	TL0 = 0xA2;
    	TR0 = 1;      // timer start
    	while(TF0==0);  // check overflow condition
    	TR0 = 0;     // Stop Timer
    	TF0 = 0;    // Clear flag
    	}
    	}
    - - - Updated - - -

    Quote Originally Posted by baileychic View Post
    Try this.

    Code:
    volatile unsigned int Counter = 0;
    volaile unsigned int oldCounter = 0;
    
    void ext0_isr(void) interrupt 0
    { 
    	Counter++;	
    }
    
    main()
    { 
    if((Counter >= 10) && ((Counter % 15) == 10))LED1 = 1;
    elseif((Counter >= 15) && ((Counter % 10) == 0))LED2 = 1;
    delay(1000);
    LED1 = 0;
    LED2 = 0;
    }
    Still this is a blocking code. If you want non-blocking code then put this piece of code in a 1 second timer interrupt without the delay(1000) code that is just the code which is in while(1) loop into timer interrupt code.


    Ok I will do it.
    IMRAN



    •   AltAdvertisement

        
       

  4. #24
    Super Moderator
    Points: 81,029, Level: 69
    Achievements:
    7 years registered
    Awards:
    Most Frequent Poster 3rd Helpful Member

    Join Date
    Apr 2014
    Posts
    16,430
    Helped
    3730 / 3730
    Points
    81,029
    Level
    69

    Re: Glow LED on specified counter values 0-500 in 89c52 uC

    Hi,

    if((Counter >= 10) && ((Counter % 15) == 10))LED1 = 1;
    Is the same as
    if ( (Counter % 15) == 10) LED1 = 1;

    Klaus
    Please don´t contact me via PM, because there is no time to respond to them. No friend requests. Thank you.



    •   AltAdvertisement

        
       

  5. #25
    Super Moderator
    Points: 30,098, Level: 42
    andre_teprom's Avatar
    Join Date
    Nov 2006
    Location
    Brazil
    Posts
    8,978
    Helped
    1138 / 1138
    Points
    30,098
    Level
    42
    Blog Entries
    9

    Re: Glow LED on specified counter values 0-500 in 89c52 uC

    If you want non-blocking code then put this piece of code in a 1 second timer interrupt
    Not a good recommendation to insert pieces of code inside interrupt vectors. As far as possible, the only service to be performed there is the triggering of a flag to be handled in the main() function, which in your provided code misses the enclosing while(1) sentence.
    --------------------------------------------------------------------------------------------------
    Part of the world that you live in, You are the part that you're giving ( Renaissance )


    1 members found this post helpful.

  6. #26
    Advanced Member level 3
    Points: 3,603, Level: 14
    baileychic's Avatar
    Join Date
    Aug 2017
    Posts
    719
    Helped
    54 / 54
    Points
    3,603
    Level
    14

    Re: Glow LED on specified counter values 0-500 in 89c52 uC

    Oops... Yes, forgot to wrap in while(1) loop

    Code:
    volatile unsigned int Counter = 0;
    volaile unsigned int oldCounter = 0;
    
    void ext0_isr(void) interrupt 0
    { 
    	Counter++;	
    }
    
    main()
    { 
    
    while(1) {
    if((Counter % 15) == 10)LED1 = 1;
    elseif((Counter >= 15) && ((Counter % 10) == 0))LED2 = 1;
    delay(1000);
    LED1 = 0;
    LED2 = 0;
    }
    }



  7. #27
    Super Moderator
    Points: 30,098, Level: 42
    andre_teprom's Avatar
    Join Date
    Nov 2006
    Location
    Brazil
    Posts
    8,978
    Helped
    1138 / 1138
    Points
    30,098
    Level
    42
    Blog Entries
    9

    Re: Glow LED on specified counter values 0-500 in 89c52 uC

    Quote Originally Posted by baileychic View Post
    Code:
    void ext0_isr(void) interrupt 0
    { 
    	Counter++;	
    }
    Again, a well-written code ideally do not perform any task in handling interrupts other than triggering flags. In the above case, if during the execution of the program, the interruption changes the value of the Counter variable (which is evaluated several times during the program), the result could be unexpected. Interrupts, particularly external ones, are assynchonous with the code, it can happen at any time, not sure that will be at the beginning of the routine.

    The correct action could be something like:

    Code C - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    void ext0_isr (void) interrupt 0 {
          bExtTimer0Interrupt = true;
          }
     
    main ()
    {
    while (1) {
          if (bExtTimer0Interrupt) {
                Counter ++;
                bExtTimer0Interrupt = false;
                }
          ...
          ...
          }

    We are obviously not talking about a critical life support application, just a led blinker; but if you are going to recommend a code, please do it by adopting good practices.
    Last edited by andre_teprom; 15th February 2020 at 23:31. Reason: fixed error in the code
    --------------------------------------------------------------------------------------------------
    Part of the world that you live in, You are the part that you're giving ( Renaissance )



  8. #28
    Advanced Member level 2
    Points: 4,015, Level: 14
    Achievements:
    7 years registered
    imranahmed's Avatar
    Join Date
    Dec 2011
    Location
    Karachi,Pakistan
    Posts
    650
    Helped
    3 / 3
    Points
    4,015
    Level
    14

    Re: Glow LED on specified counter values 0-500 in 89c52 uC

    Quote Originally Posted by andre_teprom View Post
    By using state machine you would always return to an Idle state instead of being blocked within execution of a Delay function, in addition to the obvious advantage of having a better structured program. As you did, it is not any issue at all if blink two leds is the only thing you have to do but if you need to read for example a key pressed within 1s would not work, so it is time to you get introduced to better practices in coding; make a search on the Web for the keyword FSM ("finite state machice") and you will have insights to apply this approach on your programs.
    I wrote a code using Interrupt of Timer 1 mode 2 generating output of 25us and some state machine look but please let me know how add delay between LED toggling, i.e 1 second delay.

    Code:
    #include 
    volatile unsigned int counter = 0;
    bit flag = 0;
    sbit LED = P2^0;
    unsigned char STATE;
    
    
    void timer1_isr() interrupt 3
    {	
    	flag = 1;			
    }
    
    void main()
    {
        TMOD = 0x20;       //Timer1 mode 2  //  Generating 25us pulse Total time period is 50us
        TH1 = 0XE9;        //Load the timer value
        TR1 = 1;           //turn ON Timer zero
        ET1 = 1;           //Enable TImer1 Interrupt
        EA = 1;            //Enable Global Interrupt bit
        STATE = 0;
        while(1)
        {
    			if(flag)
    				{
    			switch(STATE)
    			{
    			
                            case 0:
    			LED = 1;
    			STATE = 1;
    		        break;
    				
    			case 1:
    			LED = 0;
    			STATE = 0;
    		        break;
    			
                            default:
    			STATE = 0; 
    			break;			
    			}
    	     	              }
    			
    			
        }
    }
    IMRAN



  9. #29
    Super Moderator
    Points: 30,098, Level: 42
    andre_teprom's Avatar
    Join Date
    Nov 2006
    Location
    Brazil
    Posts
    8,978
    Helped
    1138 / 1138
    Points
    30,098
    Level
    42
    Blog Entries
    9

    Re: Glow LED on specified counter values 0-500 in 89c52 uC

    This is an incomplete code, you are not reseting the variable flag anywhere, as well as you are no more incrementing Counter variable which should be used in additioin to other variables, when turn on and off the LED. Draw a flowchart prior to coding, or at least review the code before asking for help.
    --------------------------------------------------------------------------------------------------
    Part of the world that you live in, You are the part that you're giving ( Renaissance )


    1 members found this post helpful.

  10. #30
    Advanced Member level 3
    Points: 3,603, Level: 14
    baileychic's Avatar
    Join Date
    Aug 2017
    Posts
    719
    Helped
    54 / 54
    Points
    3,603
    Level
    14

    Re: Glow LED on specified counter values 0-500 in 89c52 uC

    Post your circuit and also your Keil complete project files.

    Also, mention what is your Crystal frequency, 12MHz, 11.0592MHz,...?


    1 members found this post helpful.

    •   AltAdvertisement

        
       

  11. #31
    Advanced Member level 2
    Points: 4,015, Level: 14
    Achievements:
    7 years registered
    imranahmed's Avatar
    Join Date
    Dec 2011
    Location
    Karachi,Pakistan
    Posts
    650
    Helped
    3 / 3
    Points
    4,015
    Level
    14

    Re: Glow LED on specified counter values 0-500 in 89c52 uC

    This is complete working code thanks for andre_teprom for recommending Finite State Machine Algorithm.

    And also thanks for all thread members.

    The only thing in this code is Timer Interrupt delay I calculated for 25us but microsecond value should be 40000 for (25us x 40000) = 1 sec delay.
    But it was not, it was work with microsecond = 11000. But why

    I am working with 11.0592Mhz Crystal.

    11.0592/12 clock cycles = 921.6~ 922kHz. --->>> 1/922kHz = 1.085us.

    for example: for 25us delay --> 25us/1.085us = 23 -->> 256-23=233 convert to hex --> 0xE9 Timer 1 mode 2 (Auto-Reload).

    Code:
    #include 
    volatile unsigned int counter = 0;
    bit flag = 0;
    sbit LED = P2^0;
    #define LED_OFF 0
    #define LED_ON_WAIT 1
    #define LED_ON 2
    #define LED_OFF_WAIT 3
    #define microseconds 11000
    unsigned char STATE = LED_OFF;
    
    void timer1_isr() interrupt 3
    {	
    	flag = 1;			
    }
    
    void main()
    {
        TMOD = 0x20;       //Timer1 mode 2  //  Generating 25us pulse Total time period is 50us
        TH1 = 0xE9;        //Load the timer value
        TR1 = 1;           //turn ON Timer zero
        ET1 = 1;           //Enable TImer1 Interrupt
        EA = 1;            //Enable Global Interrupt bit
    	  STATE = 0;
        while(1)
        {		
    			switch(STATE)
    			{
    				case LED_OFF:
    					LED = 0;				  
    				  STATE = LED_ON_WAIT;				
    				break;
    					
    				
    				case LED_ON_WAIT:
    				if(counter >= microseconds)
    					{					
    				  STATE = LED_ON;
    					counter = 0;
    				  }		  
    				break;
    					
    				case LED_ON:
    				LED = 1;				  
    				STATE = LED_OFF_WAIT;	
    				break;
    				
    				case LED_OFF_WAIT:
    				if(counter >= microseconds)
    					{					
    				  STATE = LED_OFF;
    					counter = 0;
    				  }	
    				break;
    				
    				default:					
    				break;			
    			}	
    			
    						if(flag == 1)
    							{					
    						if(counter < 65535)  
    							{
    							 counter++;
    							}
    							flag = 0;
    							}
    	  }			
    }
    - - - Updated - - -

    Please find circuit and project file.
    Last edited by imranahmed; 17th February 2020 at 09:38.
    IMRAN



--[[ ]]--