CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Interrupt and two different output

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Sebastian



Joined: 01 Dec 2003
Posts: 21
Location: Milan Italy

View user's profile Send private message Send e-mail

Interrupt and two different output
PostPosted: Tue Sep 30, 2014 10:53 am     Reply with quote

Hi all

I have written this little program to manage two outputs alternately at the touch of a button. Needless to say, so the interrupt routine is not functional.
Do you have any tips to handle this little problem?
Code:

#if defined(__PCH__)
#include <18F458.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#endif

#include <input.c>
#define     GPI1       PIN_D1
#define     GPI2       PIN_D2
#define    BUTTON       PIN_B0

#define  GPI1ON 1
#define  GPI2ON 2

int GPI_CTRL;
           
#INT_EXT
void ext_isr()
            {
            while(!input(BUTTON));
            delay_ms(100);
            GPI_CTRL++;
if (GPI_CTRL==1) {
 
                output_high(GPI1);
                delay_ms(50);
                output_low(GPI1);
                 }
else if (GPI_CTRL==2)
                 {
                output_high(GPI2);
                delay_ms(50);
                output_low(GPI2);
                GPI_CTRL=0;
                 }
}

void main()    {
                GPI_CTRL=0;
                port_b_pullups(TRUE);
                set_tris_D(0x00);
                ext_int_edge(H_TO_L);
                enable_interrupts(INT_EXT);
                enable_interrupts(GLOBAL);
                }


thanks in advance Embarassed
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Sep 30, 2014 11:37 am     Reply with quote

Try changing your program design to a timer tick based approach.
Read these threads for ideas:
http://www.ccsinfo.com/forum/viewtopic.php?t=52279
http://www.ccsinfo.com/forum/viewtopic.php?t=17189
http://www.ccsinfo.com/forum/viewtopic.php?t=35429
Ttelmah



Joined: 11 Mar 2010
Posts: 19539

View user's profile Send private message

PostPosted: Tue Sep 30, 2014 2:33 pm     Reply with quote

and, as a general comment on the program, what happens to a CCS program, when it drops 'off the end'?.
Sebastian



Joined: 01 Dec 2003
Posts: 21
Location: Milan Italy

View user's profile Send private message Send e-mail

PostPosted: Mon Oct 06, 2014 9:58 am     Reply with quote

Thank you Ttelmath , PCM programmer for the encouragement !!!

I do not have the experience to tell you if this goes in the right direction !
This code is a collage of your examples and only for test !
Suggestions Rolling Eyes


Code:

#if defined(__PCH__)
#include <18F458.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,BROWNOUT,PUT
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#endif


#define     GPI1       PIN_D1
#define     GPI2       PIN_D2
#define    BUTTON      PIN_B0
#define TICK_MS ((5000 * 256 * 256 ) / (20000000/4)) //13,1072Msec
#define TASK1_TIMER_VALUE (1/TICK_MS)
#define TASK2_TIMER_VALUE (2/TICK_MS)
#define  GPI1ON 1
#define  GPI2ON 2

char gc_old_button_status = input_b();
int GPI_CTRL=0;
int16 task1_timer;
int16 task2_timer;
//-----------------------
void timer_tick(void);
void task1(void);
void task2(void);

void main()
{
// Setup Timer0 so it rolls over at a 76,29 Hz rate.
// This gives a timer tick of approximately 13,1072Msec.
// All tasks (together) must execute in less than 13,1072Msec.
setup_timer_0(RTCC_DIV_256);

task1_timer = TASK1_TIMER_VALUE;
//task2_timer = TASK2_TIMER_VALUE;


while(1)
  {
   task1();
  // task2();

   timer_tick();
  }

}

void task1(void)
{
char new_status;


if(task1_timer)
   return;
else
  task1_timer = TASK2_TIMER_VALUE;
GPI_CTRL++;
new_status = input_b();    // Read the buttons

if(new_status != gc_old_button_status)
  {
   
switch (GPI_CTRL) {

    case GPI1ON :
                output_high(GPI1);
                delay_ms(2);
                output_low(GPI1);

       break;

case GPI2ON :
                output_high(GPI2);
                delay_ms(2);
                output_low(GPI2);
                  GPI_CTRL=0;
       break;

   }

gc_old_button_status = new_status;
}

}

//--------------------------
// This function waits for the hardware timer0
// to count up to 0xFF and roll over to 0x00.
void timer_tick(void)
{
// Wait until the Timer0 rolls over from 0xFF to 0x00.
while(!bit_test(get_timer0(), 7));  // Wait until MSB goes high
while(bit_test(get_timer0(), 7));  // Wait until Timer rolls over to 0

if(task1_timer)
   task1_timer--;

}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Oct 06, 2014 12:07 pm     Reply with quote

I would throw out your whole code and just start over again.
You must write code that you can understand. If you can't understand
what you're writing, then write something that's more simple.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Oct 06, 2014 9:41 pm     Reply with quote

I made a really simple program that you should be able to understand.
There are no interrupts involved. There is just a while() loop that runs
every 10 ms. Inside the loop we call a button() function to see if a
button has been pressed. There are two buttons that we check.
I used pins B0 and A4 for the buttons because that's how my board
is built. The reason I used the button() routine is so you don't have to
make the button code. It's already done. You just call the routine.

If a button is pressed, we set the "on" duration for the LED. This is in
10 ms increments. So an "on" duration value of 50 means the LED will
be on for 500 ms.

After checking the buttons, we look at the led duration timer variables.
If they are positive, we decrement them. After we have gone through
the while() loop the required number of times (50, for an LED "on"
duration of 500 ms), the led duration timer will have been decremented
down to 0, so then we turn off the LED.

This program was tested on a PicDem2-Plus (old non-rohs version)
with CCS compiler vs. 5.028.

The button() routine is in the link below. Save the button routine code
as button.c and put it in your project directory. Do not use the button
demo program. You only want the button.c code. It's the 2nd program
in this post:
http://www.ccsinfo.com/forum/viewtopic.php?t=23837

Code:

#include <18F4520.h>
#fuses HS,NOWDT,PUT,BROWNOUT,PUT,NOLVP
#use delay(clock=20M)

// Your LEDs are on these two pins.
#define LED1_PIN  PIN_B1
#define LED2_PIN  PIN_B2

// Define Bvar variables for the buttons.
// The button() function requires this.
int8 button1 = 0;   // For the button on pin B0
int8 button2 = 0;   // For the button on pin A4
#include "button.c"


//===================================
void main()
{
int8 led1_timer;   // 0 to 2550 ms led on time
int8 led2_timer;   // 0 to 2550 ms led on time


while(TRUE)
  {
   if(button(PIN_B0, 0, 50, 10, button1, 1))   
     {
      output_high(LED1_PIN);
      led1_timer = 20;   // Turn on LED1 for 200 ms
     }


   if(button(PIN_A4, 0, 50, 10, button2, 1))   
     {
      output_high(LED2_PIN);
      led2_timer = 75;   // Turn on LED2 for 750 ms
     }

     
   if(led1_timer)
      led1_timer--;
   else
      output_low(LED1_PIN);


   if(led2_timer)
      led2_timer--;
   else
      output_low(LED2_PIN);


   delay_ms(10);
  }

}



Your buttons should be connected to the PIC with a circuit as shown below.
Each button should have its own separate circuit like this:
Code:

           +5v
            |
            <
            > 4.7K       
            <         ___ Push button switch 
To          |        _|_|_
PIC -----------------o   o------
pin                            |             
                              --- GND
                               -   
Sebastian



Joined: 01 Dec 2003
Posts: 21
Location: Milan Italy

View user's profile Send private message Send e-mail

PostPosted: Tue Oct 07, 2014 12:53 am     Reply with quote

Thanks PCM programmer
You're really gentle, carefully read your advice.
I'm sorry but I'm not a programmer.
Thanks again for your time! Razz
Sebastian



Joined: 01 Dec 2003
Posts: 21
Location: Milan Italy

View user's profile Send private message Send e-mail

PostPosted: Tue Oct 07, 2014 7:36 am     Reply with quote

I tried to compile the project with the file button.c but returns

A #DEVICE REQUIRED BEFORE THIS LINE

Quote:

#define read_bit_var(x) bit_test(*(int8 *)(x >> 3), x & 7)


What's the reason ? Rolling Eyes
I use MPLABX2.00 and CCS 5.027
stinky



Joined: 05 Mar 2012
Posts: 99
Location: Central Illinois

View user's profile Send private message

PostPosted: Tue Oct 07, 2014 9:24 am     Reply with quote

Most likely that the line that says
Code:
#include "button.c"
is above your main headers. Move that line below the first lines:
Code:
#include <18F4520.h>
#fuses HS,NOWDT,PUT,BROWNOUT,PUT,NOLVP
#use delay(clock=20M)

// Your LEDs are on these two pins.
#define LED1_PIN  PIN_B1
#define LED2_PIN  PIN_B2

// Define Bvar variables for the buttons.
// The button() function requires this.
int8 button1 = 0;   // For the button on pin B0
int8 button2 = 0;   // For the button on pin A4
#include "button.c"                        <---THIS LINE HERE!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Oct 07, 2014 11:49 pm     Reply with quote

Quote:
I tried to compile the project with the file button.c but returns

A #DEVICE REQUIRED BEFORE THIS LINE

There is another reason. In MPLAB X, click on the Project tab on the
far left side of MPLAB X. You should see the following lines in the Project
window as shown below. Click on "Source Files" to show the files:
Code:
Your Project name
  + Header Files
  + Important Files
  + Library Files
  + Linker Files
  + Object Files
  - Source Files
        Your Main Source Filename.c
        Button.c   <-- REMOVE THIS FILE FROM THE LIST.
  + Libraries
  + Loadables

You will notice that Button.c is in the list. Select it with your mouse,
right-click on it, and select "Remove from Project". Do it. Only your
main source file (I don't know what you call it) should be in the list.
Now re-compile and it will probably build with no errors.

In the CCS command line compilers (which you have), only the main
source file for your project should be in the Source Files list. Other
#include files such as Button.c should not be in the list. If they are in
the list, MPLAB X will try to compile them as separate files, and you
will get the "A #device required before this line" error. So remove
button.c from the list and you will get a good build.
Sebastian



Joined: 01 Dec 2003
Posts: 21
Location: Milan Italy

View user's profile Send private message Send e-mail

PostPosted: Wed Oct 08, 2014 1:04 am     Reply with quote

Thanks PCM now compile it's ok !!!
I have a clarification to submit ,

Code:

           +5v
            |
            <
            > 4.7K       
            <         ___ Push button switch 
To          |        _|_|_
PIC -----------------o   o------
pin                            |             
                              --- GND
                               -   


You tell me to connect this abitual circuit i now

In this declaration
Code:

   if(button(PIN_B0, 0, 50, 10, button1, 1))

all the instance must be true to complete if statement !
Downstate is 0!

Considering
Quote:

// Downstate:
// This is the logic level of the button when it's pressed.
// For a circuit with a Normally-Open switch and a pull-up
// resistor, this parameter will be 0.


This means that when i not press button the pin is in the high level +5v
because is pull-upped.
Downstate is to be considered 0
Quote:
For a circuit with a Normally-Open switch and a pull-up resistor, this parameter will be 0.



here is tha question , why in the code i check in this way
Quote:

// Check if the button is pressed. It's pressed if the
// pin value is the same as the "downstate". If it's not
// pressed, then zero the Bvar and return "Not pressed".

Code:

if(pin_value != downstate)
  {
   Bvar = 0;
   return(!action);   
  }

if statement it's true when pin_value is different from downstate and bit_test() function return 1 if pin is high.
I would expect exactly the opposite thing when button it's pressed !
How does it work downstate ?
Rolling Eyes
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Oct 08, 2014 12:43 pm     Reply with quote

Code:
if(pin_value != downstate)
  {
   Bvar = 0;
   return(!action);   
  }

The code shown above checks if the button is not pressed. If it's not
pressed, the code returns !action, which means it returns 0.
So "not pressed" returns 0. That's exactly what you want.

If the button is pressed, then we fall through to this code:
Code:

if(Bvar == 0)       
  {
   if(delay == 0)
      Bvar = 255;     
   else   
      Bvar = delay;   

   return(action); 
  }

And we return "action", which is set to 1. A return value of 1 means
"True", or yes, we did get a keypress.

The code might seem a little hard to understand. That's because it's a
close translation of PicBasic Pro ASM code to CCS.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group