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

Push Button and Interrupt problem

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



Joined: 26 Feb 2012
Posts: 17

View user's profile Send private message

Push Button and Interrupt problem
PostPosted: Fri May 25, 2012 3:35 pm     Reply with quote

Hello,

I have a problem with my program. It is supposed to go to several "modes" mode 1,2 and 3 when i push a button. It doesn't work, i can't build it successfully. Always the same error:

Code:

Error 51 "shailene.c" Line 55(9,28): A numeric expression must appear here

( this is the line #INT_RB //Interrupt routine)

I think that my ISR is not at the good place but when i move it before or after "main(void)", some other errors appears :

Code:

Warning 204 "shailene.c" Line 45(1,1): Condition always FALSE

*** Error 12 "shailene.c" Line 45(28,34): Undefined identifier   select

*** Error 12 "shailene.c" Line 47(12,18): Undefined identifier   select

*** Error 12 "shailene.c" Line 47(18,24): Undefined identifier   select

Is there any easier way to do that ? I checked the program named PBUTT in the example files of CCS but i don't really understand it.

my version of CCS compiler is : Version 4.068
I use the plugin of CCS in MPLAB version 8.36.00.00

here is the code:



Code:

#include <16F887.h>
#device adc=8
#FUSES NOWDT      // No WDT
#FUSES INTRC      // internal oscillator
#FUSES PUT        //power Up Timer
#FUSES NOPROTECT  //pas de protection en ecriture
#FUSES NODEBUG    //No ICD 
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP      //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD      //eeprom protection
#use delay(internal=8Mhz) //Internal oscillator 8 Mhertz
#define BUTTON_SELECT PIN_B0
#define LED1 PIN_D0
#define LED2 PIN_D1
#define LED3 PIN_D2
#define mode1 0x01010001
#define mode2 0x01011001
#define mode3 0x01101111
#define princp 0x01000000


void init_io()
{
   
    // port A In
    SET_TRIS_A(0x11);   // bit 0 = Out, 1 = In

    // Port B In
    SET_TRIS_B(0x11);   // bit 0 = Out, 1 = In
   
    // port D Out
    SET_TRIS_D(0x00);   // bit 0 = Out, 1 = In
   
    // init Ports
    OUTPUT_A(0x00);
    OUTPUT_C(0x00);
    OUTPUT_D(0x00);
    OUTPUT_E(0x00);
}

void main(void)
{
int8 temp=0;
int8 temps=0;
int8 select=0;
int8 time=0;
enable_interrupts(INT_RB0);
enable_interrupts(GLOBAL);
set_timer0(0);
setup_counters(RTCC_INTERNAL, RTCC_DIV_256 | RTCC_8_BIT);

 
 #INT_RB //Interrupt routine
void RB(void)
{

if (BUTTON_SELECT == 0) {++select;}  // test if the Push Button is maintained and incrementing "select" variable to switch to another mode

if (select > 3) {select==0;}

}

while(true){

if (select==1) {goto_address(mode1);}

if (select==2) {goto_address(mode2);}

if (select==3) {goto_address(mode3);}

}

// mode1 LED1 blink very slowly

while(true) {
time=get_timer0();
if (time==250) {++temps; set_timer0(0);} 
if (select!=1) {goto_address(princp);}
if (temps==150) {output_high(PIN_D7); temps = 0;}
}

//mode2 LED2 turned on if temp >100

   SETUP_ADC(ADC_CLOCK_INTERNAL); //configur ADC converter
   SETUP_ADC_PORTS(sAN0 | VSS_VDD);               
   
 
   while(true)
{
      set_adc_channel(0);//reading AN0
      delay_us(20);// delaiy 20us
      temp=read_adc(); // reading AN0: 0<=temp<=255
         
      if (temp>100) {output_high(LED2);}
    
           else {output_low(LED2);}

      if (select!=1) {goto_address(princp);}
}


//mode3 LED3 turned on continuously

while(true)
{
output_high(LED3);
if (select!=3) {goto_address(princp);}
}
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri May 25, 2012 3:42 pm     Reply with quote

Don't put an interrupt routine in the middle of main(). Put it above main().
WillysJeeps



Joined: 24 May 2012
Posts: 5

View user's profile Send private message

PostPosted: Fri May 25, 2012 3:45 pm     Reply with quote

I think you are missing a } at the end of the main() routine.
Mike Walne



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

View user's profile Send private message

PostPosted: Fri May 25, 2012 4:03 pm     Reply with quote

You're trying to define your RB interrupt routine within main().

Move it outside main().

And you will have to redefine select as global (OR do something else).

Your code still won't work.

If it still does not compile, the error messages should be more comprehensible.

Better use of indentation will make it easier to understand.

Mike
Got-Got



Joined: 26 Feb 2012
Posts: 17

View user's profile Send private message

PostPosted: Fri May 25, 2012 5:07 pm     Reply with quote

Now, the ISR is out of the main() but i don't know how to define "select" as global.

"(OR do something else)." Yes may be but it is the simplest method i found to use a push button for this purpose. I don't see any other way.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri May 25, 2012 5:36 pm     Reply with quote

Look at section 5.1 of this C tutorial. It shows where to place a global
variable:
http://phy.ntnu.edu.tw/~cchen/ctutor.pdf
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri May 25, 2012 5:36 pm     Reply with quote

A few more hints:
Quote:
i don't know how to define "select" as global.
I think I don't understand the question. You already know you need a global variable, which part is it then that you don't understand? How to declare a variable as global is in every textbook on the C language and I'm sure you have looked this up, haven't you?

Code:
#define mode1 0x01010001
Hmmm... I think you tried to define an 8-bit boolean variable but instead you declared a 32-bit hex-variable.
Not possible in most standard C variants, but easy to do in CCS. Check out the CCS manual, and yes, you'll have to find the page yourself.

Code:
if (BUTTON_SELECT == 0)
Again, this is not going to do what you want it to do. The preprocessor will do a direct text replacement and then you get:
Code:
if (PIN_B0 == 0)
Look in the PIC16F887 header file and you will see PIN_B0 is defines as the integer 48 and then your code becomes:
Code:
if (48 == 0)
This is always false...
Look into the CCS manual for the input() function for the proper way to solve this.

Code:
goto_address(mode1)

_never ever_ use the goto instruction in C or any of it's derived family members. It is considered bad programming as it leads to difficult to maintain programs. Every normal program can be written using other program flow instructions like: while, for and switch/case.
Your teacher will subtract points for using goto.
Besides all that, your goto is jumping to the wrong address so it won't work anyway. Jumping to address 'princip' at 0x01000000? The PIC16 doesn't have that much memory! What were you thinking?

Quote:
my version of CCS compiler is : Version 4.068
This is an very old version and not a very good one. Not too bad, but it is still one of the early v4.0 compilers and full of bugs. The compiler started to work again around v4.075. You might run into troubles when you keep using this old version. Not too good a prospect considering the many basic errors you make. When it doesn't work, is it you or the compiler.......?
Mike Walne



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

View user's profile Send private message

PostPosted: Sat May 26, 2012 2:26 am     Reply with quote

My compiler complains, this line has not effect.
Code:
if (select > 3) {select==0;}


By and large you don't have to set TRIS registers, CCS usually takes care of them.

You seem to be trying to set registers in binary, but using hex.


As I understand it, what you want is:-

(1) Operate in mode1 till button pressed, then advance to mode2.
(2) Operate in mode2 till button pressed, then advance to mode3.
(3) Operate in mode3 till button pressed, then return to mode1.

Is this basically correct?



When you press the switch:-

(i) How many times will the switch contact bounce?
(ii) Will each bounce generate an interrupt?
(iii) How will you prevent your system responding to bounce induced interrupts?
(iv) Will the switch contact bounce on release?

Mike
Got-Got



Joined: 26 Feb 2012
Posts: 17

View user's profile Send private message

PostPosted: Sun May 27, 2012 3:35 am     Reply with quote

Ok... i was very far away from the solution. Mike, this is exactly what i want. I though it was the simplest solution but no...

For the switch contact bounce, i'd put a 10 ms delay in the ISR to avoid bouncing but i saw on ccsinfo that is was not recomended to put a delay in an ISR, so i choosed to deal with that later.

Thanks for you tips ckielstra, i will use switch/case or something like that, I saw on the CCS manual that the goto instruction is not recomended but it seems so easy to use.
Mike Walne



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

View user's profile Send private message

PostPosted: Sun May 27, 2012 5:13 am     Reply with quote

There's loads of button type code on this forum.

This is the bones of A WAY to deal with button bounce:-

(1) Use a timer interrupt ISR to sample switch state at ~10ms intervals.
(2) If switch is closed for two successive samples you've got a valid closure.
(3) If switch is open for two successive samples you've got a valid release.

Here's A POSSIBLE outline for a complete program:-
Code:

// declare variables
...
// define ISR routine
...

void mode1(void)
{
  while(select == 1)
  {
   //mode1_code goes here
  ...
  }
}

// define mode2 & mode3 similar to mode1

void main(void)
{
  // initialise_timer_interrupts_etc
  ....
  while(1)
  {
   mode1;
   mode2;
   mode3;
  }
}


Mike
Got-Got



Joined: 26 Feb 2012
Posts: 17

View user's profile Send private message

PostPosted: Tue May 29, 2012 2:23 pm     Reply with quote

Ok it's pretty easy. I wrote a very complicated ( and false) program for nothing.

Thanks a lot for the advices !
Mike Walne



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

View user's profile Send private message

PostPosted: Tue May 29, 2012 2:55 pm     Reply with quote

Quote:
Ok it's pretty easy. I wrote a very complicated ( and false) program for nothing.
No.

Hopefully you have learned something, the hard way, same as the rest of us.

Best of luck.

Mike
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