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

Press button interrupt help

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



Joined: 26 Dec 2014
Posts: 4
Location: Sweden

View user's profile Send private message

Press button interrupt help
PostPosted: Sun Mar 01, 2015 6:32 am     Reply with quote

Hello everyone Very Happy

I need some help with interrupts on PIC16F690.
I want to enable interrupts on PORT RA2,
I am running on the PICkit 2 low PIN count board.

here is my code:

Code:

#include <16F690.h>
/*#include <stdio.h>
#include <stdlib.h>
*/

void init(void);
void run(void);
void button_isr(void);

int main(int argc, char** argv)
{

    init();
    run();
   
}


void init()
{
    enable_interrupts(INT_EXT);
    enable_interrupts(INT_EXT_H2L);
    enable_interrupts(INT_RA2);
    enable_interrupts(GLOBAL);
   
    set_tris_c(0x00);
    set_tris_a(0xff);
}


void run()
{
    output_c(0x00);
}


#int_RA
void button_isr()
{
    clear_interrupt(INT_RA);
    output_c(0xff);
    //clear_interrupt(INT_RA);
}


The ISR never runs when i press the button.
There is some problem with
Code:

#include <stdio.h>
#include <stdlib.h>


The compiler doesn't find there files for some reason so I have commented these out.

I am very greatful about any help with this.
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Sun Mar 01, 2015 8:13 am     Reply with quote

Code:
int main(int argc, char** argv)
{

    init();
    run();
   
}

What do you think happens after your code executes run() ?

In your ISR there's no need to disable interrupts.
Look at some of the CCS examples to see how things are done.

You could try a re-install if the compiler can't find standard files.

Mike
Ttelmah



Joined: 11 Mar 2010
Posts: 19549

View user's profile Send private message

PostPosted: Sun Mar 01, 2015 9:41 am     Reply with quote

and, also, never ever enable an interrupt without a handler. INT_EXT enabled, no handler for this. Will result in code not working.
Chrill3



Joined: 26 Dec 2014
Posts: 4
Location: Sweden

View user's profile Send private message

PostPosted: Sun Mar 01, 2015 10:29 am     Reply with quote

Thanks for the swift reply.


I have now been checking the example code 'ex_butt.c' that i think are similar to my project.
I did also delete
Code:
   
enable_interrupts(INT_EXT);
enable_interrupts(INT_EXT_H2L);


and made an infinite while loop on the run() function, but it didnt help...

here is an example of the code
Code:

/*
 * File:   myTest1.c
 * Author: christian
 *
 * Created on February 22, 2015, 5:44 PM
 */
#include <16F690.h>
/*#include <stdio.h>
#include <stdlib.h>
*/

void init(void);
void run(void);
void button_isr(void);

int main(int argc, char** argv)
{

    init();
    while(1){
    run();
    }
}


void init()
{
    enable_interrupts(INT_RA);
    enable_interrupts(GLOBAL);

    set_tris_c(0x00);
    set_tris_a(0xff);
}


void run()
{
        output_c(0x00);
}


#int_RA
void button_isr()
{   while(1){
    output_c(0xff);
}
}



Best regards
temtronic



Joined: 01 Jul 2010
Posts: 9245
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Mar 01, 2015 11:42 am     Reply with quote

quick comments...

this...
Quote:
int main(int argc, char** argv)

isn't the normal main() format

usually it's...
Code:
main() {
//do stuff here
}

You should look at some of the CCS supplied examples....

also...

this...
Quote:
#int_RA
void button_isr()
{ while(1){
output_c(0xff);
}
}
will stay in the loop forever !

also...
this...
Quote:
/*#include <stdio.h>
#include <stdlib.h>
*/

just delete it all as it's not necessary and 'looks messy'....

and...
Quote:

set_tris_c(0x00);
set_tris_a(0xff);

is not needed, as CCS automatically control the I/O pins when in 'standard' mode( the default).

One item...
Have you sucessfully got a '1Hz LED ' program to run ?



Jay
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Sun Mar 01, 2015 12:05 pm     Reply with quote

As it stands it's difficult to tell whether your code is doing anything or not.
I suggest you make run() flash an LED at say 1Hz, and get the ISR to toggle a different one.

I also prefer to align curly brackets so that the closing one is immediately underneath its opening one (with enclosed code indented).
That way it's easier to tell where a function begins and ends.

So your main becomes:-
Code:
main()
{
   init();
   while(1)
   {
      run();
   }
}


Mike
ELCouz



Joined: 18 Jul 2007
Posts: 427
Location: Montreal,Quebec

View user's profile Send private message

PostPosted: Sun Mar 01, 2015 12:09 pm     Reply with quote

^^ This...

Minimal code structure look like this:

Code:


#include <yourdevice.h> here
#FUSES here

#use delay (only when you need them, 99.999% of the time)

void main (void){ //void main means MAIN return nothing and also accept nothing (no parameters) no required per se but it's the correct way to do it in C.

//your do stuff once here (inits and all)

  while(true){
  //code loop this is where you do your real stuff ;)
  }

}



This is the minimum required code to make the magic thing happen , enjoy! Smile
_________________
Regards,
Laurent

-----------
Here's my first visual theme for the CCS C Compiler. Enjoy!
ELCouz



Joined: 18 Jul 2007
Posts: 427
Location: Montreal,Quebec

View user's profile Send private message

PostPosted: Sun Mar 01, 2015 12:11 pm     Reply with quote

Mike Walne wrote:
As it stands it's difficult to tell whether your code is doing anything or not.
I suggest you make run() flash an LED at say 1Hz, and get the ISR to toggle a different one.

I also prefer to align curly brackets so that the closing one is immediately underneath its opening one (with enclosed code indented).
That way it's easier to tell where a function begins and ends.

So your main becomes:-
Code:
main()
{
   init();
   while(1)
   {
      run();
   }
}


Mike


dang you beat me to it few mins before Very Happy
_________________
Regards,
Laurent

-----------
Here's my first visual theme for the CCS C Compiler. Enjoy!
Chrill3



Joined: 26 Dec 2014
Posts: 4
Location: Sweden

View user's profile Send private message

PostPosted: Thu Mar 05, 2015 1:23 pm     Reply with quote

Hello thanks for the help

i have changed the code a little bit
Code:

#include <16F690.h>
#use delay(clock=4000000)



void init(void);
void run(void);
void button_isr(void);

int main(void)
{
    init();
    while(1)
    {
    run();
    }
}


void init()
{
    set_tris_a(0x04);
    enable_interrupts(INT_RA3);
    enable_interrupts(GLOBAL);
}


void run()
{
    while(1)
    {
        delay_ms(1000);

/*this is for manually polling port A3, but event I press the push button, the led doesnt flash/*
        if(input(PIN_A3))
        {
            output_c(5);
            delay_ms(5000);
        }
       
        output_c(0x00);
        delay_ms(1000);
        output_c(0xff);
    }
}

//the ISR never runs, even if I press the pressbutton on RA3???
#INT_RA
void button_isr()
{   while(1)
    {
        output_c(0x7);
        delay_ms(500);
        output_c(0x00);
        delay_ms(500);
    }
}




The ISR never runs even I press the push button on RA3, it doesnt work with polling either. I have measured the push button with a multimeter and checked the RA3 port voltage level also, everything seems to be OK.

the int main(){} function is OK regarding to C language conventions.

with best regards
Christian
Ttelmah



Joined: 11 Mar 2010
Posts: 19549

View user's profile Send private message

PostPosted: Thu Mar 05, 2015 2:54 pm     Reply with quote

int main is not really right, but doesn't matter.

The point is that most programs are run 'inside' another environment (called from another program or OS etc.), so can return a value to this.
When writing for the PIC, you are writing the entire code, so there is nothing for a value to be returned to, and it is pointless to try to return anything.
The same applies for arguments to the function, where a program called from the command line has these to arrive into the C code, but in CCS you don't.

There are a huge number of problems with what you are trying to do.

First, your interrupts will be disabled almost all the time. This is because of using delays both inside and outside the interrupt. A search here will find the limitations of this. Then there is the whole concept of using interrupts to detect a button. Not good. Buttons in the real world, do not go neatly on/off. They 'bounce', making and breaking several times. To use interrupts you need to have hardware debounce circuitry on the signals. Otherwise you are better off scanning the buttons using a timer 'tick' interrupt, and using a counter to verify that the button is genuinely on or off. Then I suspect your hardware may not actually be giving the required signal. How is the button wired?. Then you are setting the line you are trying to use for the button as an output.... You are setting TRIS to 4. 00000100 in binary. Only RA2 is set as an input.
ELCouz



Joined: 18 Jul 2007
Posts: 427
Location: Montreal,Quebec

View user's profile Send private message

PostPosted: Thu Mar 05, 2015 3:21 pm     Reply with quote

Chrill3 wrote:
Hello thanks for the help

i have changed the code a little bit
Code:

#include <16F690.h>
#use delay(clock=4000000)



void init(void);
void run(void);
void button_isr(void);

int main(void)
{
    init();
    while(1)
    {
    run();
    }
}


void init()
{
    set_tris_a(0x04);
    enable_interrupts(INT_RA3);
    enable_interrupts(GLOBAL);
}


void run()
{
    while(1)
    {
        delay_ms(1000);

/*this is for manually polling port A3, but event I press the push button, the led doesnt flash/*
        if(input(PIN_A3))
        {
            output_c(5);
            delay_ms(5000);
        }
       
        output_c(0x00);
        delay_ms(1000);
        output_c(0xff);
    }
}

//the ISR never runs, even if I press the pressbutton on RA3???
#INT_RA
void button_isr()
{   while(1)
    {
        output_c(0x7);
        delay_ms(500);
        output_c(0x00);
        delay_ms(500);
    }
}




The ISR never runs even I press the push button on RA3, it doesnt work with polling either. I have measured the push button with a multimeter and checked the RA3 port voltage level also, everything seems to be OK.

the int main(){} function is OK regarding to C language conventions.

with best regards
Christian



Also I don't see any fuses in there...

You need them to properly instruct the 16F690 which type of oscillator to use...

They are other important fuses but they can be skipped...

Don't forget CCS C compiler is not C standard compliant!!

Some functions are proprietary to the CCS Compiler also...
_________________
Regards,
Laurent

-----------
Here's my first visual theme for the CCS C Compiler. Enjoy!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Mar 05, 2015 4:58 pm     Reply with quote

Here is a demo program which shows how to debounce a push-button
switch by polling it in an interrupt routine which runs every 10 ms.
This program will display a 'P' in a terminal window (ex. TeraTerm)
each time you press the push-button. Example (pressed it 5 times):
Quote:

Start: PPPPP

Code:

#include <18F4520.h>
#fuses INTRC_IO, BROWNOUT, PUT, NOWDT
#use delay(clock=4M)
#use rs232(baud=9600, UART1, ERRORS)

// This pushbutton must have a pull-up (4.7K or 10K, etc)
// on the PIC pin, and the other end of the switch must
// go to ground.  The idle state will be at Vdd, and the
// "pushed" state of the button will be at ground.
#define  BUTTON_PIN   PIN_B0

// Example of external circuit for pushbutton
//
//            +5v
//             |
//             <
//             > 4.7K       
//             <         ___ Pushbutton switch 
// To          |        _|_|_
// PIC -----------------o   o------
// pin                            |             
//                               --- GND
//                                -   
//

//----------------------------------------------
// The Timer0 preload value calculated below will
// will give a Timer0 interrupt rate of 100 Hz.
// This is intended for a PIC oscillator of 4 to 20 MHz.
// The code below saves you from having to manually
// calculate the Timer0 preload value. It's done for you.

#define FOSC getenv("CLOCK")  // Get PIC oscillator frequency


#if(FOSC < 21000000)
  #define TIMER0_PRELOAD (256 - (FOSC/4/256/100))
#else
  #error Oscillator frequency is too high:  FOSC
#endif

//----------------------------------------------
// Setup Timer0 to provide a 10ms tick for the pushbutton
// debounce interrupt.

void timer0_init(void)
{
setup_timer_0(T0_INTERNAL | T0_DIV_256 | T0_8_BIT);
set_timer0(TIMER0_PRELOAD);
clear_interrupt(INT_TIMER0);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
}
//------------------------------
// This global value is how the debounce interrupt
// routine communicates with the code in main()
// to inform it if the button has been pushed.

int8 button_pressed = FALSE;

//------------------------------
// The button pin is polled every 10ms in this interrupt
// routine. This assumes the "bounce" period for the
// button is less than 10 ms.  Usually this will be the
// case, except for very cheap, sloppy switches.

#int_timer0
void timer0_isr(void)
{
int8 current_value;
static int8 previous_value = 1;  // Idle state of button is a logic high

set_rtcc(TIMER0_PRELOAD); // Reload Timer0 for 10ms rate

current_value = input(BUTTON_PIN);  // Read the button

// Look for a falling edge, which indicates the
// button has been pushed.
if((previous_value == 1) && (current_value == 0))
   button_pressed = TRUE;   

previous_value = current_value;  // Save current value for next time
}


//===================================
void main()
{
printf("Start: ");

timer0_init();

while(TRUE)
  {
   if(button_pressed == TRUE)
     {
      button_pressed = FALSE;  // Clear the button pushed flag

      // Display a 'P' in TeraTerm every time the button is pushed.
      putc('P');   
     }

  }
}

This post has an alternative method of debouncing a push-button switch,
that does not use a timer interrupt:
http://www.ccsinfo.com/forum/viewtopic.php?t=53622&start=7

Edit: 'previous_value' must be a static variable.


Last edited by PCM programmer on Fri Jul 12, 2019 12:42 am; edited 1 time in total
Chrill3



Joined: 26 Dec 2014
Posts: 4
Location: Sweden

View user's profile Send private message

PostPosted: Sat Mar 14, 2015 4:19 pm     Reply with quote

Hi everyone

thanks for all help.
I had to right click on project and go to set configuration -> costumize and -> PICkit2 -> mark the 3 state on 'release on reset'.
everything work perfectly now Smile
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