+ Post New Thread
Results 1 to 15 of 15
  1. #1
    Full Member level 3
    Points: 2,135, Level: 10
    Achievements:
    7 years registered

    Join Date
    Sep 2011
    Posts
    165
    Helped
    1 / 1
    Points
    2,135
    Level
    10

    Create Mode function in PIC Microcontroller

    Hi all, I am creating a system that allow LED to light up in few different mode.
    microcontroller = 16F628A
    compiler = MikroC

    my PIC microcontroller also connected to 16x2 LCD to display current mode.

    This program currently have a problem that everytime i changed the mode with INT, the result only reflect after one full cycle. Is there anyway to make it change right after i pressed the INT button?
    I tried to use reset so that it can scan the condition (set in EEPROM in this case) but i fail to compile the asm code.

    my code is as below:

    Code:
     // Mode change for LED
     // LED output at B3
     // INT button at B0
    
     int mode1;
     int modecount;
     signed int i = 0;
    
    sbit LCD_RS at RA0_bit;
    sbit LCD_EN at RA1_bit;
    sbit LCD_D4 at RB4_bit;
    sbit LCD_D5 at RB5_bit;
    sbit LCD_D6 at RB6_bit;
    sbit LCD_D7 at RB7_bit;
    sbit LCD_RS_Direction at TRISA0_bit;
    sbit LCD_EN_Direction at TRISA1_bit;
    sbit LCD_D4_Direction at TRISB4_bit;
    sbit LCD_D5_Direction at TRISB5_bit;
    sbit LCD_D6_Direction at TRISB6_bit;
    sbit LCD_D7_Direction at TRISB7_bit;
     
     
     
     char message1[] = "Mode 1";
     char message2[] = "Mode 2";
     char message3[] = "Mode 3";
     char message4[] = "Unicorn Banshee HG";
    
    
    
     
    void main()
    {
    
         CMCON = 0x07;
         TRISA = 0; // To configure PORTC as output port
         TRISB = 0x01;
         OPTION_REG.INTEDG = 1; // Set Rising Edge Trigger for INT
         INTCON.GIE = 1; // Enable The Global Interrupt
         INTCON.INTE = 1; // Enable INT
    
         PWM1_Init(5000);            // Initialize PWM frequency
         PWM1_Set_Duty(127);
         PWM1_Start();
         mode1 = 0x00;
    
         Lcd_Init();        // Initialize LCD
         Lcd_Cmd(_LCD_CLEAR);               // Clear display
         Lcd_Cmd(_LCD_CURSOR_OFF);  // OFF cursor
         Lcd_Cmd(0x01);               // Clear display
         Lcd_Cmd(0x03); //cursor home
    
    
         while(1)
             // Loop:
              {
    
                  if( eeprom_read(0) == 0x01) // Mode2
    
                  {
                      Lcd_out(1,1,message4);
                      Lcd_out(2,1,message2);
                      for(i = 0; i < 256; i += 250)
                       {
                       PWM1_Set_Duty(i);
    
                       Delay_ms(200);
                       }
                       for(i = 250; i >= 0; i -= 250)
                       {
                       PWM1_Set_Duty(i);
                       Delay_ms(200);
                       }
                  }
    
                  else if (eeprom_read(0) == 0x02)     // Mode 3
    
                  {
                       Lcd_out(1,1,message4);
                      Lcd_out(2,1,message3);
                       for(i = 0; i < 256; i += 5)
                       {
                       PWM1_Set_Duty(i);
    
                       Delay_ms(140);
                       }
                       for(i = 253; i >= 0; i -= 5)
                       {
                       PWM1_Set_Duty(i);
                       Delay_ms(120);
                       }
                  }
                  else if (eeprom_read(0) == 0x03)     // Mode 4
    
                  {
                       PORTB.F1 = 1;
                       delay_ms(500);
                       PORTB.F1 = 0;
                       delay_ms(500);
                  }
    
                  else // Default mode1
                  {
                  Lcd_out(1,1,message4);
                  Lcd_out(2,1,message1);
                  mode1 = 0x00;
                  for(i = 0; i < 256; i += 250)
                       {
                       PWM1_Set_Duty(i);
    
                       Delay_ms(1000);
                       }
                       for(i = 250; i >= 0; i -= 250)
                       {
                       PWM1_Set_Duty(i);
                       Delay_ms(1000);
                       }
    
                  }
              }
      }
    
      void interrupt() //  ISR
           {
               INTCON.INTF=0;
               // mode1 +1;
    
               modecount = 0x01;
               mode1 = mode1 + modecount;
               eeprom_write(0,mode1);
               //goto Loop;
               // asm 
               //  {
               //    reset;
               //   }
    
               delay_ms(50);
    
               
               }
    Last edited by KlausST; 23rd October 2017 at 17:16. Reason: corrected quote to code tags

    •   AltAdvertisement

        
       

  2. #2
    Advanced Member level 2
    Points: 3,115, Level: 13
    baileychic's Avatar
    Join Date
    Aug 2017
    Posts
    622
    Helped
    49 / 49
    Points
    3,115
    Level
    13

    Re: Create Mode function in PIC Microcontroller

    Timer interrupts have to be used for modes. If large delays are executing then even if you use INTx pin to detect mode change then it will only get applied after the Delay_ms(1000) gets executed. You can use while() which tests for mode and you can change mode in TNTx interrupt. If mode changes then program execution comes out of the loop and enters next valid mode loop.


    1 members found this post helpful.

  3. #3
    Full Member level 3
    Points: 2,135, Level: 10
    Achievements:
    7 years registered

    Join Date
    Sep 2011
    Posts
    165
    Helped
    1 / 1
    Points
    2,135
    Level
    10

    Re: Create Mode function in PIC Microcontroller

    Quote Originally Posted by baileychic View Post
    Timer interrupts have to be used for modes. If large delays are executing then even if you use INTx pin to detect mode change then it will only get applied after the Delay_ms(1000) gets executed. You can use while() which tests for mode and you can change mode in TNTx interrupt. If mode changes then program execution comes out of the loop and enters next valid mode loop.
    Hi, thanks for reply.
    TNTx is timer interrupt?
    I actually learned the basic of timer interrupt before but in this case i wondering how should i do it because timer interrupt duration is set with the TMR1H and TMR1L.
    I though make a "reset" function at interrupt actully. which when i trigger the interrupt to change state, the PIC is reset and scan the condition again. but i implement the ASM code:

    asm{

    reset;

    }
    The MikroC compiler comes out an error which cant recognize the reset function.



  4. #4
    Advanced Member level 2
    Points: 3,115, Level: 13
    baileychic's Avatar
    Join Date
    Aug 2017
    Posts
    622
    Helped
    49 / 49
    Points
    3,115
    Level
    13

    Re: Create Mode function in PIC Microcontroller

    Sorry, it is not TNTx. It is INTx only. In INTx interrupt change the modes and use while() loops with condition to test modes. One loop for one mode. Still if Delays inside while loops are executing then mode test will be done after delay executes.


    1 members found this post helpful.

  5. #5
    Super Moderator
    Points: 77,067, Level: 67
    Achievements:
    7 years registered
    Awards:
    Most Frequent Poster 3rd Helpful Member

    Join Date
    Apr 2014
    Posts
    15,616
    Helped
    3558 / 3558
    Points
    77,067
    Level
    67

    Re: Create Mode function in PIC Microcontroller

    Hi,

    I donīt see a debounce function in your code. Do you have hardware debounce.
    You need one of both.

    ****
    Only a couple of modes are defined. EEPROM_Value 0x01, 0x02, 0x03, all others are processed as MODE0.

    Why donīt you limit the EEPROM value to 0x01 to 0x03?
    for example: If mode1 = 4 then mode1 = 1 (pseudocode)

    Klaus


    1 members found this post helpful.

    •   AltAdvertisement

        
       

  6. #6
    Full Member level 3
    Points: 2,135, Level: 10
    Achievements:
    7 years registered

    Join Date
    Sep 2011
    Posts
    165
    Helped
    1 / 1
    Points
    2,135
    Level
    10

    Re: Create Mode function in PIC Microcontroller

    Quote Originally Posted by baileychic View Post
    Sorry, it is not TNTx. It is INTx only. In INTx interrupt change the modes and use while() loops with condition to test modes. One loop for one mode. Still if Delays inside while loops are executing then mode test will be done after delay executes.
    ok. but if that is the case how should i set the interrupt timer TMR1H and TMR1L?
    actually i did one project before is using timer interrupt to select which LED to blink. and TMR1H and TMR1L is the duration of blink.
    but i am not sure how to implement it in this case.

    Quote Originally Posted by KlausST View Post
    Hi,

    I donīt see a debounce function in your code. Do you have hardware debounce.
    You need one of both.

    ****
    Only a couple of modes are defined. EEPROM_Value 0x01, 0x02, 0x03, all others are processed as MODE0.

    Why donīt you limit the EEPROM value to 0x01 to 0x03?
    for example: If mode1 = 4 then mode1 = 1 (pseudocode)

    Klaus
    Hi. Thank you very much for reminding the debounce. I will add into my code.

    for the EEPROM value limitation, do you mean i set an "if" condition in the interrupt function as your example?



  7. #7
    Super Moderator
    Points: 77,067, Level: 67
    Achievements:
    7 years registered
    Awards:
    Most Frequent Poster 3rd Helpful Member

    Join Date
    Apr 2014
    Posts
    15,616
    Helped
    3558 / 3558
    Points
    77,067
    Level
    67

    Re: Create Mode function in PIC Microcontroller

    Hi,

    Yes, in the interrupt function.

    Btw: is the interrupt level_triggered or edge_triggered?

    *******
    An idea:
    Maybe you could set up a timer to time out every 20ms (or any other useful value)
    Make the main loop to run according this value.
    Instead of using busy delay routines you can just count loops.
    Then you don't need a debounce function.
    Example for a 1 s blink: use a counter set it to 24 and decrement it every run. When zero: toggle LED and set it to 24.

    This enables you to do a lot of things at virtually the same time.
    It's more PLC style with a fixed timing.

    Klaus


    1 members found this post helpful.

    •   AltAdvertisement

        
       

  8. #8
    Full Member level 3
    Points: 2,135, Level: 10
    Achievements:
    7 years registered

    Join Date
    Sep 2011
    Posts
    165
    Helped
    1 / 1
    Points
    2,135
    Level
    10

    Re: Create Mode function in PIC Microcontroller

    Quote Originally Posted by KlausST View Post
    Hi,

    Yes, in the interrupt function.

    Btw: is the interrupt level_triggered or edge_triggered?

    *******
    An idea:
    Maybe you could set up a timer to time out every 20ms (or any other useful value)
    Make the main loop to run according this value.
    Instead of using busy delay routines you can just count loops.
    Then you don't need a debounce function.
    Example for a 1 s blink: use a counter set it to 24 and decrement it every run. When zero: toggle LED and set it to 24.

    This enables you to do a lot of things at virtually the same time.
    It's more PLC style with a fixed timing.

    Klaus

    Hi.
    I am how sure whether it is level triggered or state triggered. May I know how can i check this?

    And i had modified one of the condition as below:

    Code:
    if( eeprom_read(0) == 0x01) // Mode2
                  {
                  Lcd_out(1,1,message4);
                  Lcd_out(2,1,message2);
                      for( k=0; k < 10; k++ )
                      {
                       for(i = 0; i < 256; i += 250)
                       {
                       PWM1_Set_Duty(i);
    
                       Delay_ms(100);
                       }
                       }
                       for (k >= 10; k < 20; k++)
                       {
                          for(i = 250; i >= 0; i -= 250)
                       {
                       PWM1_Set_Duty(i);
                       Delay_ms(100);
                       }
                       }
                       for ( k >= 20; k <21; k = 0)
                       {
                       return;
                       }
                  }
    is it you suggest something like this?
    This code still have one problem which is after several times of blinking. It stop, and I can't change the mode anymore.
    Last edited by KlausST; 29th October 2017 at 08:20. Reason: corrected tags



  9. #9
    Advanced Member level 2
    Points: 3,115, Level: 13
    baileychic's Avatar
    Join Date
    Aug 2017
    Posts
    622
    Helped
    49 / 49
    Points
    3,115
    Level
    13

    Re: Create Mode function in PIC Microcontroller

    Quote Originally Posted by alpha91 View Post
    Hi.
    I am how sure whether it is level triggered or state triggered. May I know how can i check this?
    INTEDG_bit value or INTEDGx_bit value.
    Last edited by andre_teprom; 29th October 2017 at 09:43. Reason: fixed QUOTE


    1 members found this post helpful.

  10. #10
    Super Moderator
    Points: 77,067, Level: 67
    Achievements:
    7 years registered
    Awards:
    Most Frequent Poster 3rd Helpful Member

    Join Date
    Apr 2014
    Posts
    15,616
    Helped
    3558 / 3558
    Points
    77,067
    Level
    67

    Re: Create Mode function in PIC Microcontroller

    Hi,

    It seems you posted the wrong code....at least it has nothing to do with my recommendations.

    Klaus


    1 members found this post helpful.

  11. #11
    Full Member level 3
    Points: 2,135, Level: 10
    Achievements:
    7 years registered

    Join Date
    Sep 2011
    Posts
    165
    Helped
    1 / 1
    Points
    2,135
    Level
    10

    Re: Create Mode function in PIC Microcontroller

    Quote Originally Posted by baileychic View Post
    INTEDG_bit value or INTEDGx_bit value.
    Sorry, i dont know how to check this. Can you guide me? i am still beginner in PIC programming.


    is it you suggest something like this?
    This code still have one problem which is after several times of blinking. It stop, and I can't change the mode anymore.[/QUOTE]

    Quote Originally Posted by KlausST View Post
    Hi,

    It seems you posted the wrong code....at least it has nothing to do with my recommendations.

    Klaus
    Hi, this is one of the mode. I didnt post the whole code.
    I thought you were saying that breakdown the long delay into shorter then using counter to count the repeat times.
    I think i misunderstand then.

    What if everytime after interrupt i reset the PIC? will it works? since i use EEPROM to record the mode value.



  12. #12
    Super Moderator
    Points: 77,067, Level: 67
    Achievements:
    7 years registered
    Awards:
    Most Frequent Poster 3rd Helpful Member

    Join Date
    Apr 2014
    Posts
    15,616
    Helped
    3558 / 3558
    Points
    77,067
    Level
    67

    Re: Create Mode function in PIC Microcontroller

    Hi,


    An idea:
    Maybe you could set up a timer to time out every 20ms (or any other useful value)
    --> I donīt see this in your code.

    Make the main loop to run according this value.
    --> I donīt see this in your code.
    At the beginnin of the main loop you need to wait for the timer event.
    It shouldnīt be a problem to wait until the timer flag is set. Then clear the flag and run the main routine


    Instead of using busy delay routines you can just count loops.
    --> You still use busy waits.
    Donīt use delay_ms at all - it just consumes processing power and it canīt do anything else druing this time.


    Klaus



  13. #13
    Full Member level 3
    Points: 2,135, Level: 10
    Achievements:
    7 years registered

    Join Date
    Sep 2011
    Posts
    165
    Helped
    1 / 1
    Points
    2,135
    Level
    10

    Re: Create Mode function in PIC Microcontroller

    An idea:
    Maybe you could set up a timer to time out every 20ms (or any other useful value)
    --> I donīt see this in your code.

    Make the main loop to run according this value.
    --> I donīt see this in your code.
    At the beginnin of the main loop you need to wait for the timer event.
    It shouldnīt be a problem to wait until the timer flag is set. Then clear the flag and run the main routine


    Instead of using busy delay routines you can just count loops.
    --> You still use busy waits.
    Donīt use delay_ms at all - it just consumes processing power and it canīt do anything else druing this time.
    oh. I though i using the 100ms is what you mean in the first conditions.
    sorry, i have no idea on how to make a main loop to time out. Do you mean using interrupt timer?
    Last edited by alpha91; 31st October 2017 at 15:42.



    •   AltAdvertisement

        
       

  14. #14
    Super Moderator
    Points: 77,067, Level: 67
    Achievements:
    7 years registered
    Awards:
    Most Frequent Poster 3rd Helpful Member

    Join Date
    Apr 2014
    Posts
    15,616
    Helped
    3558 / 3558
    Points
    77,067
    Level
    67

    Re: Create Mode function in PIC Microcontroller

    Hi,

    Do you mean using interrupt timer?
    As already said:
    set up a timer to time out every 20ms
    It just sets a flag when timed out.
    No need to generate an interrupt --> No need or an ISR.

    Iīm not familiar with PICs, therefore I donīt know the name of the flag. But the function is similar in almost all microcontrollers.


    Klaus


    2 members found this post helpful.

  15. #15
    Full Member level 3
    Points: 2,135, Level: 10
    Achievements:
    7 years registered

    Join Date
    Sep 2011
    Posts
    165
    Helped
    1 / 1
    Points
    2,135
    Level
    10

    Re: Create Mode function in PIC Microcontroller

    Quote Originally Posted by KlausST View Post
    Hi,



    As already said:

    It just sets a flag when timed out.
    No need to generate an interrupt --> No need or an ISR.

    Iīm not familiar with PICs, therefore I donīt know the name of the flag. But the function is similar in almost all microcontrollers.


    Klaus
    Alright. Thanks a lot.
    I try to find out how should i set the timer then.
    Thank you.



--[[ ]]--