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

INT_RB problem - pic18f2550
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Pichuqy_1



Joined: 03 Aug 2010
Posts: 38

View user's profile Send private message MSN Messenger

INT_RB problem - pic18f2550
PostPosted: Thu Feb 21, 2019 4:40 pm     Reply with quote

Hi all. I have a problem to use the interrupt for status change in port B, with pic18f2550.
The problem is, I can not detect the falling edge of the signal. I'm using four buttons on the pins 4,5,6,7. The interruption runs correctly, but I never detect the falling edge.
Try simulating it several times and I get the same result.

To put it in other terms, the program never enters to #elif HIGHTOLOW.

I took the code to deal with this interruption from the forum.

Can someone help me find out what's going on?
Code:

#include <18f2550.h>
#device  ICD   =  TRUE      
//#device HIGH_INTS=TRUE                          
#fuses HS,MCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,NOUSBDIV,PLL5,CPUDIV1,NOVREGEN,NOPBADEN,NOPUT,DEBUG
#use delay(clock=20000000)

#byte UCFG = 0xF6F                               
#bit UTRDIS = UCFG.3                            
//#use fast_io(B)

#define _FLEX_LCD
#define LCD_DB4   PIN_C1
#define LCD_DB5   PIN_C0
#define LCD_DB6   PIN_B2
#define LCD_DB7   PIN_B3
 
#define LCD_RS    PIN_A1
#define LCD_RW    PIN_A2
#define LCD_E     PIN_A0


#include "flex_lcd.c"
#include "internal_eeprom.c"
#include "ds1307.c"
#include "ds1307_configuracion.c"
#include "TMR.c"
//#include "convercion_int_char.c"

#define LOWTOHIGH TRUE
#define HIGHTOLOW FALSE

int16 overflow_timer0;
int falla_general=0;
int bandera_backlight=0;
int bandera_TMR1,bandera_TMR2,bandera_TMR3,bandera_TMR4,bandera_TMR5,bandera_TMR6;
int int_rb_1=0;
int current;
static int last=0;
//int dbutton4, dbutton5, dbutton6, dbutton7;


#INT_RB                                     
void detect_rb_change(void)
{
   
 
 //  set_tris_b(0xF0);
   current=input_b();   

   #if LOWTOHIGH   
   if ((!bit_test(last,4))&&(bit_test(current,4))&&(bandera_backlight==0)&&(int_rb_1==1))
   dbutton4=4;
   if ((!bit_test(last,5))&&(bit_test(current,5))&&(bandera_backlight==0)&&(int_rb_1==1))
   dbutton5=5;
   if ((!bit_test(last,6))&&(bit_test(current,6))&&(bandera_backlight==0)&&(int_rb_1==1))
   dbutton6=6;
   if ((!bit_test(last,7))&&(bit_test(current,7))&&(bandera_backlight==0)&&(int_rb_1==1))
   dbutton7=7;
 
  #elif  HIGHTOLOW
   if ((!bit_test(current,4))&&(bit_test(last,4))&&(bandera_backlight==0)&&(int_rb_1==1))
   dbutton4=4;
   if ((!bit_test(current,5))&&(bit_test(last,5))&&(bandera_backlight==0)&&(int_rb_1==1))
   dbutton5=5;
   if ((!bit_test(current,6))&&(bit_test(last,6))&&(bandera_backlight==0)&&(int_rb_1==1))
   dbutton6=6;
   if ((!bit_test(current,7))&&(bit_test(last,7))&&(bandera_backlight==0)&&(int_rb_1==1))
   dbutton7=7;
   #endif
   
   last=current;
 
  }



    
//#separate                                          
{
setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);                  //104 ms overflow
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);                    //3,4 s overflow



   clear_interrupt(int_rb);                              
                                    
   enable_interrupts(INT_EXT);                           
   enable_interrupts(INT_RB);                           
   enable_interrupts(INT_RTCC);
   disable_interrupts(INT_TIMER1);
    enable_interrupts(GLOBAL);
   ext_int_edge( H_TO_L );                              
   set_timer1(0x00);
   set_timer0(0x00);   

   port_b_pullups(TRUE);                                 
   set_tris_b(0xF0);
   delay_us(10);

UTRDIS = 1;                                          

//int16 cuenta_pulsador=0;                               
overflow_timer1=0;

//int con_hours, con_inicio1,con_inicio2;
int resultado_TMR1=0;
int resultado_hora_actual;

output_high(PIN_C2);                                 

lcd_init();
ds1307_init(DS1307_OUT_ON_DISABLED_HIHG | DS1307_OUT_ENABLED | DS1307_OUT_1_HZ);

//enable_interrupts(int_ext);
//ext_int_edge(L_TO_H);
//enable_interrupts(GLOBAL);




while(1)
{
delay_ms(250);
enable_interrupts(INT_RTCC);                     //Habilitamos timmer 0
disable_interrupts(INT_TIMER1);                     //Habilitamos timmer 1


int_rb_1=1;
overflow_timer1=0;                              //se pone a cer la variable del tamier 1
//overflow_timer0=0;




if(dbutton7==7) {
dbutton7=0;       
CONFIGURACION_ENCENDIDO_APAGADO();
         
      }


if(dbutton4==4) {
dbutton4=0;       
CONFIGURACION_DS1307();
         
      }
   


ds1307_get_time();                               
ds1307_get_date();                               
lcd_gotoxy(4,1);
printf(lcd_putc,"\f%1s-%1s-20%1s\n",date_char,month_char,year_char);
lcd_gotoxy(5,2);
printf(lcd_putc,"%1s:%1s:%1s",hours_char,minutes_char,seconds_char); //23:59:59


resultado_TMR1 = hora_TMR1_inicio + minutos_TMR1_INICIO;
resultado_hora_actual = hours + minutes;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


if((hora_TMR1_inicio == hours) && (minutos_TMR1_INICIO == minutes) && (bandera_TMR1 == 0)&& (hora_TMR1_inicio != 255)){
                  output_high(PIN_C7);
                  bandera_TMR1 = 1;
                                                                                           }                                                   

if((hora_TMR1_stop == hours) && (minutos_TMR1_stop == minutes) && (bandera_TMR1 == 1)){
                  output_low(PIN_C7);
                  bandera_TMR1 = 0;
                                                                  }   

//////////////////////////////////////////////////////////////////////////////////////////////////////////

if((hora_TMR2_inicio == hours) && (minutos_TMR2_INICIO == minutes) && (bandera_TMR2 == 0)&& (hora_TMR2_inicio != 255)){
                  output_high(PIN_C7);
                  bandera_TMR2 = 1;
                                                                                           }                                                   

if((hora_TMR2_stop == hours) && (minutos_TMR2_stop == minutes) && (bandera_TMR2 == 1)){
                  output_low(PIN_C7);
                  bandera_TMR2 = 0;
                                                                 }
////////////////////////////////////////////////////////////////////////////////////////////////////////////

if((hora_TMR3_inicio == hours) && (minutos_TMR3_INICIO == minutes) && (bandera_TMR3 == 0) && (hora_TMR3_inicio != 255)){
                  output_high(PIN_C7);
                  bandera_TMR3 = 1;
                                                                    }                                                   

if((hora_TMR3_stop == hours) && (minutos_TMR3_stop == minutes) && (bandera_TMR3 == 1)){
                  output_low(PIN_C7);
                  bandera_TMR3 = 0;
                                                                    }
////////////////////////////////////////////////////////////////////////////////////////////////////////////

if((hora_TMR4_inicio == hours) && (minutos_TMR4_INICIO == minutes) && (bandera_TMR4 == 0)&& (hora_TMR4_inicio != 255)){
                  output_high(PIN_C7);
                  bandera_TMR4 = 1;
                                                                    }                                                   

if((hora_TMR4_stop == hours) && (minutos_TMR4_stop == minutes) && (bandera_TMR4 == 1)){
                  output_low(PIN_C7);
                  bandera_TMR4 = 0;
                                                                    }

                                                                                                                                                                              
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



      
   }
 

}
temtronic



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

View user's profile Send private message

PostPosted: Thu Feb 21, 2019 6:07 pm     Reply with quote

you have ...
#define HIGHTOLOW FALSE
so your elif won't execute....

at least that's how I read it.

As an aside, I don't think that PIC actually has h2l, l2h options for the 'Interrupt-on-change' so you can't decode which did fire the interrupt.

Jay
Pichuqy_1



Joined: 03 Aug 2010
Posts: 38

View user's profile Send private message MSN Messenger

PostPosted: Thu Feb 21, 2019 8:08 pm     Reply with quote

Thank you very much for your answer Jay. I had already put #define HIGHTOLOW TRUE in the program and even then it did not work either.

If I keep pressing any button, the interruption is executed when I press and when I stop pressing. That is why I can deduce that it is possible to read the falling edge.

Thank you. Laughing
temtronic



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

View user's profile Send private message

PostPosted: Thu Feb 21, 2019 8:46 pm     Reply with quote

just some comments..

OK, I read the datasheet(2550 is skinny 4550).. and IOC is different that 'edge detect'.
Seems this PIC can only do 'IOC' BUT there's a note about you having to wait 1 cycle other wise the flag keeps getting set.

I'd change this...
current=input_b();

#if LOWTOHIGH

to this...
current=input_b();
delay_us(5); //added delay as per datasheet...
#if LOWTOHIGH

See if it does anything...

There could be the nasty hardware 'debounce' problem. If you have just a mechancal pushbutton to ground and a 10K pullup, you'll get several 101010 transitions, not just a 1-0-1. Adding a small cap ( .68uf) should quench the bounce. Easy to see if you have a scope.

Jay
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Feb 21, 2019 8:53 pm     Reply with quote

My advice is to strip down the program. Get rid of the #if, #elif, and
#endif statements. Remove the code for the edge you don't want to test.
Get rid of all enable_interrupts() for everything except #int_rb.
Get rid of all excess code that has nothing to do with #int_rb. Example:
Quote:
&&(bandera_backlight==0)&&(int_rb_1==1))

Get rid of all ds1307 stuff, etc. Strip the program down. Test it, and
if it still fails, post the new program.

Also, describe your circuit for your switches. What value is the pull-up
resistor ? Are your switches connected the same as this ?
Code:

           +5v
            |
            <
            > 4.7K       
            <         ___  Switch 
To          |        _|_|_
PIC -----------------o   o------
pin B4                         |             
                              --- GND
                               -
Ttelmah



Joined: 11 Mar 2010
Posts: 19497

View user's profile Send private message

PostPosted: Fri Feb 22, 2019 12:22 am     Reply with quote

Also, in what you post you have INT_EXT also enabled, but no handler
for this. This will cause major problems.
Then at the start you try to clear INT_RB. You need to read port B
before doing this, or it can't be cleared.
As PCM_programmer says, test with simpler code first.
temtronic



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

View user's profile Send private message

PostPosted: Fri Feb 22, 2019 6:34 am     Reply with quote

been thinking about this for awhile...
have to agree... you need to 'trim' down your code to JUST the 4 PB->result code.

http://www.ccsinfo.com/forum/viewtopic.php?t=23837&highlight=button++pbp
should be a link to PCM P's 'button' driver.

It works GREAT !!
might be an option ?
Pichuqy_1



Joined: 03 Aug 2010
Posts: 38

View user's profile Send private message MSN Messenger

PostPosted: Fri Feb 22, 2019 10:33 am     Reply with quote

Thank you very much for your advice. I will try the modifications you mentioned and I will publish the results.
The project is about a programmable clock, in which 10 different hours can be configured independently. You can enter the start time, end time, and you can deactivate any time.
I almost have it ready, but this problem appeared with the interruption of the RB port.

The code that I put before, is simplified, since I also use: #INT_EXT, # INT_TIMER1, #INT_RTCC.

https://ibb.co/z7VWS6c
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Feb 22, 2019 11:21 am     Reply with quote

Your schematic is missing the series resistor for your LED D3.
temtronic



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

View user's profile Send private message

PostPosted: Fri Feb 22, 2019 7:15 pm     Reply with quote

Also you need a battery on the DS1307 as well as a 32KHz xtal.

_mclr should be pulled high, not low.... according to your fuse you are using that pin for _mclr.

If you set the SQW out of the DS1307 at 1Hz, you get a nice timed interrupt for your project that allows main() to update the LCD every second.
Pichuqy_1



Joined: 03 Aug 2010
Posts: 38

View user's profile Send private message MSN Messenger

PostPosted: Mon Feb 25, 2019 6:03 pm     Reply with quote

Hello everyone again.

I simplified the code and followed his advice. Even so, the interruption RB is executed twice (I understand that the first time is on the rising edge and the second on the falling edge) but always enters #if LOWTOHIGH. Therefore the same action is executed twice.

When I simulate it using PROTEUS, the #elif code HIGHTOLOW seems not to be enabled. Look at the attached photo. I do not know why...


Code:
#include <18f2550.h>
#device  ICD   =  TRUE      
#fuses HS,MCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,NOUSBDIV,PLL5,CPUDIV1,NOVREGEN,NOPBADEN,NOPUT,DEBUG
#use delay(clock=20000000)

#byte UCFG = 0xF6F                               
#bit UTRDIS = UCFG.3                            
//#use fast_io(B)

#define _FLEX_LCD
#define LCD_DB4   PIN_C1
#define LCD_DB5   PIN_C0
#define LCD_DB6   PIN_B2
#define LCD_DB7   PIN_B3
 
#define LCD_RS    PIN_A1
#define LCD_RW    PIN_A2
#define LCD_E     PIN_A0


#include "flex_lcd.c"
#include "internal_eeprom.c"
#include "ds1307.c"
#include "ds1307_configuracion.c"
#include "TMR.c"


#define LOWTOHIGH TRUE
#define HIGHTOLOW TRUE


int int_rb_1=0;
int current;
static int last=0;


#INT_RB                                     
void detect_rb_change(void)
{

   current=input_b();   
   delay_us(5);

   #if LOWTOHIGH   
   if ((!bit_test(last,4))&&(bit_test(current,4))
   dbutton4=4;
   if ((!bit_test(last,5))&&(bit_test(current,5))
   dbutton5=5;
   if ((!bit_test(last,6))&&(bit_test(current,6))
   dbutton6=6;
   if ((!bit_test(last,7))&&(bit_test(current,7))
   dbutton7=7;
 
  #elif  HIGHTOLOW
   if ((!bit_test(current,4))&&(bit_test(last,4))
   dbutton4=14;
   if ((!bit_test(current,5))&&(bit_test(last,5))
   dbutton5=15;
   if ((!bit_test(current,6))&&(bit_test(last,6))
   dbutton6=16;
   if ((!bit_test(current,7))&&(bit_test(last,7))
   dbutton7=17;
   #endif
   
   last=current;
 
  }

    
//#separate                                          
void main(void)
{
               
   enable_interrupts(INT_RB);                           
        enable_interrupts(GLOBAL);
   

   port_b_pullups(TRUE);                                 
   set_tris_b(0xF0);
   delay_us(10);

UTRDIS = 1;                                          


lcd_init();
ds1307_init(DS1307_OUT_ON_DISABLED_HIHG | DS1307_OUT_ENABLED | DS1307_OUT_1_HZ);


while(1)
{
delay_ms(250);



if(dbutton7==7) {
dbutton7=0;       
CONFIGURACION_ENCENDIDO_APAGADO();
         
      }


if(dbutton4==4) {
dbutton4=0;       
CONFIGURACION_DS1307();
         
      }
   


ds1307_get_time();                               
ds1307_get_date();                               

lcd_gotoxy(4,1);
printf(lcd_putc,"\f%1s-%1s-20%1s\n",date_char,month_char,year_char);
lcd_gotoxy(5,2);
printf(lcd_putc,"%1s:%1s:%1s",hours_char,minutes_char,seconds_char); //23:59:59
 

}

[img]https://subefotos.com/ver/?f412abc288c1cb4afe564c439e727b86o.jpg[/img]

temtronic



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

View user's profile Send private message

PostPosted: Mon Feb 25, 2019 6:23 pm     Reply with quote

Quote:
When I simulate it using PROTEUS, the #elif code HIGHTOLOW seems not to be enabled. Look at the attached photo. I do not know why...

this...

using PROTEUS

It's very, very well known that PROTEUS is a broken piece of software NOT to be trusted.!

As for the
Quote:
if
do this....
elseif
do that...

Since the first condition is true, it will execute the following code 'do this' then bypasses the 2nd 'if' condition (the 'elseif') and 'do that... is never executed.

Another comment...
I don't see any difference in the 2 groups of tests in 'this' vs 'that'.

Also that PIC can't tell you which edge, only that an 'edge event' has occurred, at least that's how I read the datasheet.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Feb 25, 2019 9:06 pm     Reply with quote

Pichuqy_1 wrote:

Therefore the same action is executed twice.

I'm not sure what you mean by "the same action".

The program will definitely execute the LOWTOHIGH code twice. That's
expected. There are two edges, falling and rising, and each one causes
an interrupt-on-change. Because of your #if-#elseif structure, only the
LOWTOHIGH code will be compiled into the program.

Also, #if LOWTOHIGH only affects what section of code is compiled into
the program. That statement doesn't affect anything when the PIC is
actually running the program. Maybe you were confused by this.

Your code is looking for a low, followed by a high. This low-high sequence
is the rising edge of your pulse. That's what you want it to do.
Code:
                   
                   "High" bit_test(current,4) == True for the current sample
________          __|_____________
       |          |   
       |          |<-- Rising Edge 
       |__________|
                |
              "Low" !bit_test(last,4) == True for the previous sample

When both tests are true, you have detected the rising edge.

The first edge (the falling edge) will not be be detected by this code.
That's what you want (I assume). You want to detect the rising edge.
temtronic



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

View user's profile Send private message

PostPosted: Tue Feb 26, 2019 6:57 am     Reply with quote

I'm thinking you've got 2 problems. 1 hardware, 2nd code.
1)
note:
from CCS, in the FAQ section of the manual...
https://www.ccsinfo.com/faq.php?page=int_ext_button

...they do a delay inside the ISR to handle the pb 'bounce'. All mechanical switches have bounce ( sending several 1-0 transitions) when you use them
2)
you can modify(add to) this example to 'decode' whether the interrupt was from a rising or falling edge.
I'd start with just one pb(say B4) and get the code to work 100% then just copy 3x, edit as needed for b5,6,and 7.
Pichuqy_1



Joined: 03 Aug 2010
Posts: 38

View user's profile Send private message MSN Messenger

PostPosted: Tue Feb 26, 2019 8:43 pm     Reply with quote

I apologize for my English, it is not my native language. Thank you for your answers.

What I interpreted with this code is that, for the falling edge, the #if LOWTOHIGH is executed. And for rising edge the #elif HIGHTOLOW is executed. Am I wrong?

But in this case the segment #if LOWTOHIGH is executed twice, and I can not understand why.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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