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 support@ccsinfo.com

Problem using the external interrupt (Rb0) with a PIC16F877

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



Joined: 17 Mar 2008
Posts: 6

View user's profile Send private message

Problem using the external interrupt (Rb0) with a PIC16F877
PostPosted: Thu Mar 27, 2008 11:09 am     Reply with quote

Hello everyone.

I'm working with a 16F877 using the Tmr1 and Rb0 interrupts. The Tmr1 interrupt works well all the time. However, the external interrupt only works once.

Here's the code for the interrupt

Code:
#include "C:\Micro C\Complex test\complex.h"
#include <lcdlib.c>
#include <kbdlib.c>
int starter, i, weight, j;
char keypress, keylcd1, keylcd2, keylcd3, hour1, hour2, min1, min2;
#int_EXT
void EXT_isr()
{
   starter = true;
}
#int_timer1
void TIMER1_isr()
{
   i=++i;
   if(i==2){
   min2=++min2;
   if(min2==':')
   {
      min1=++min1;
      min2='0';
   }
   if(min1=='6')
   {
      min1='0';
      hour2=++hour2;
   }
   if(hour2=='3'&&hour1=='1')
   {
      hour1='0';
      hour2='1';
   }
   i=0;
   }
}
void main()
{
   lcd_init();
   kbd_init();
   port_b_pullups(true);
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(FALSE);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   enable_interrupts(int_ext);
   enable_interrupts(int_timer1);
   enable_interrupts(global);

   //USER CODE
   min2='0';
   min1='0';
   hour2='0';
   hour1='1';
   setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_8 );
   i=0;
   do{
   while(starter != true){
      lcd_putc('\f');
      lcd_putc(hour1);
      lcd_putc(hour2);
      lcd_putc(':');
      lcd_putc(min1);
      lcd_putc(min2);
      if((hour1=='1'&&hour2=='2')||hour1=='0')
      {
      lcd_putc(" am\n");
      }
      else
      {
      lcd_putc(" pm\n");
      }
      lcd_putc("Sistema Activo");
      delay_ms(250);
      if(hour1=='0'&&hour2=='4')
      {
      disable_interrupts(GLOBAL);
      lcd_putc("\fJornada\n");
      lcd_putc("Finalizada");
      do{
      delay_ms(500);
      }while(true);
      }
   }
   clear_interrupt(int_ext);
   starter = 0;
   lcd_putc("\fBienvenido...\n");
   delay_ms(3000);
   lcd_putc("Espere");
   delay_ms(250);
   lcd_putc('.');
   delay_ms(250);
   lcd_putc('.');
   delay_ms(250);
   lcd_putc('.');

   setup_adc_ports(RA0_ANALOG);
   setup_adc(ADC_CLOCK_INTERNAL);
   set_adc_channel(0);
   weight = read_adc();
   if(weight<75)
   {
   lcd_putc("\fTipo\n");
   lcd_putc("Liviano");
   delay_ms(2000);
   lcd_putc("\fCodigo de\n");
   lcd_putc("Confirmacion:");
   lcd_putc("\f350\n");
   }
   if(weight>=75&&weight<=150)
   {
   lcd_putc("\fTipo\n");
   lcd_putc("Pesado");
   delay_ms(2000);
   lcd_putc("\fCodigo de\n");
   lcd_putc("Confirmacion:");
   lcd_putc("\f658\n");
   }
if(weight>=150)
   {
   lcd_putc("\fTipo\n");
   lcd_putc("Extra Pesado");
   delay_ms(2000);
   lcd_putc("\fCodigo de\n");
   lcd_putc("Confirmacion:");
   lcd_putc("\f999\n");
   }
   do{
   lcd_gotoxy(1,2);
   for(j=0;j<=2;++j)
   {
      do{
      keypress=kbd_getc();
      }while(keypress==0);
      lcd_putc(keypress);
   }
   delay_ms(500);
   keylcd1=lcd_getc(1,2);
   keylcd2=lcd_getc(2,2);
   keylcd3=lcd_getc(3,2);
   if(keylcd1!=lcd_getc(1,1)||keylcd2!=lcd_getc(2,1)||keylcd3!=lcd_getc(3,1))
   {
   lcd_gotoxy(1,2);
   lcd_putc("Erroneo");
   delay_ms(1500);
   lcd_gotoxy(1,2);
   lcd_putc("       ");
   lcd_gotoxy(1,2);
   }
   else
   {
   lcd_gotoxy(1,2);
   lcd_putc("Confirmado");
   }
   delay_ms(1500);
   }while(keylcd1!=lcd_getc(1,1)||keylcd2!=lcd_getc(2,1)||keylcd3!=lcd_getc(3,1));
   lcd_putc("\fBuen viaje");
   delay_ms(2000);
   lcd_putc('\f');
   }while(hour1!='0'&&hour2<='4');
   disable_interrupts(GLOBAL);
   lcd_putc("\fJornada\n");
   lcd_putc("Finalizada"); 
}


And here's the .h:
Code:
#include <16F877.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES XT                       //Crystal osc <= 4mhz
#FUSES PUT                      //Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected
#FUSES NODEBUG                  //No Debug mode for ICD

#use delay(clock=4000000)



As you can see, the large piece of code will repeat as long as "starter" is false. The only way to make "starter" true is by pressing a switch on Rb0, thus triggering the interrupt. Once that is done, the program moves forward until a point where it goes back to wait until Rb0 is pressed again.

Now here's the deal. It works wonderfully but only once. Once the program returns to "while(starter != true)", even if you hit the button with a hammer, it won't trigger the interrupt again...

So, what am I missing in the code? Thanks in advice.


Last edited by ZeroF877A on Fri Mar 28, 2008 7:02 am; edited 3 times in total
Ttelmah
Guest







PostPosted: Thu Mar 27, 2008 11:19 am     Reply with quote

How can it _ever_ return to the 'while(starter != true)'?.
It'll never go past the:
Code:

      do{
      delay_ms(500);
      }while(true);
      }


This is a 'forever' loop. it'll never exit, so the code will never go back and wait for 'starter'again....

Best Wishes
ZeroF877A



Joined: 17 Mar 2008
Posts: 6

View user's profile Send private message

PostPosted: Thu Mar 27, 2008 11:24 am     Reply with quote

Quote:
if(hour1=='0'&&hour2=='4')
{
disable_interrupts(GLOBAL);
lcd_putc("\fJornada\n");
lcd_putc("Finalizada");
do{
delay_ms(500);
}while(true);
}


That forever loop is intended. It'll only happen IF(hour1=='0'&&hour2=='4'). Which doesn't happen yet. And I've tested that part, it works perfectly fine, it's supposed to be an endless loop when the "timer" reaches 04. Thanks for the help anyway =D


EDIT: It DOES return to the 'while(starter != true)', since it's a LCD refresh loop (I'm emulating a 'real time' clock [1 minute per second] using tmr1). And after the rest of the code is executed it returns to showing the 'current time'. It refreshes properly and all. Goes ahead and displays "Jornada Finalizada" via LCD AND THEN it goes into the infinite loop, which is intended to be sort of the end of the program.
Matro
Guest







PostPosted: Thu Mar 27, 2008 12:06 pm     Reply with quote

Ttelmah is right!
This loop
Code:

do{
delay_ms(500);
}while(true);

is endless.
So the application will stay here ... and that's all.

Matro
Matro
Guest







PostPosted: Thu Mar 27, 2008 12:09 pm     Reply with quote

Moreover, when the ext interrupt is triggered, the code will goes out the
Code:

while(starter != true)

loop and then execute
Code:

starter = false;

And after...
What's happening?

Matro
ZeroF877A



Joined: 17 Mar 2008
Posts: 6

View user's profile Send private message

PostPosted: Thu Mar 27, 2008 12:21 pm     Reply with quote

After the loop ends when starter = true, the "starter = false" is written so the moment I return to that specific area, it won't just go ahead again and execute the rest of the program.

Also, Matro. That endless loop only happens IF something else happens first.

Check the {}'s in the code and see for yourself.

Anyways, the problem seems to have miraculously solved by itself...
Matro
Guest







PostPosted: Thu Mar 27, 2008 12:27 pm     Reply with quote

The question about the endless loop is : Why write it like you did it when you can just write :
while(1);
since nothing happens in the loop.

Check that NOLVP is present among your #FUSES directives.
If you want more help, please post a complete "compilable" code with fuses.

Matro.
ckielstra



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

View user's profile Send private message

PostPosted: Thu Mar 27, 2008 9:37 pm     Reply with quote

Quote:
If you want more help, please post a complete "compilable" code with fuses.
And may I add to that to please use a correct indentation. Now at least three seasoned programmers (Me, Ttelmah and Matro) overlooked your problem because of bad formatting.
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Fri Mar 28, 2008 1:24 am     Reply with quote

I'm reluctant to jump in on this since the person with the issue seems to believe in their code more than the reality that their code didn't work.

Coding an RTC for most coders is a basic task that is accomplished without
the issues presented by ZeroF877A's code.
The enable_interrupts (GLOBAL) is missing in the snippet of code given as well as the initialization of the variable starter.

Now ZeroF877A's faith in his/her code has according to ZeroF877A resulted in a miracle.... it was self repairing. Wish we all could be as blessed.
ZeroF877A



Joined: 17 Mar 2008
Posts: 6

View user's profile Send private message

PostPosted: Fri Mar 28, 2008 7:00 am     Reply with quote

Douglas Kennedy wrote:
I'm reluctant to jump in on this since the person with the issue seems to believe in their code more than the reality that their code didn't work.



If you see your code working as you designed it to work on a physical MCU (except for the interrupt part), you're bound to think it's functional, no? I've been working with these MCU for nearly 10 months now (used to work in assembly), so it's not like I don't know what I'm doing.

Anyway, I might add that I had to replace the PIC with a new one, and change the wiring in my board for it to work. The code works perfectly fine, and if anyone is still reluctant about it, I can upload a video to prove it.
Guest








PostPosted: Fri Mar 28, 2008 8:54 am     Reply with quote

ZeroF877A wrote:
Douglas Kennedy wrote:
I'm reluctant to jump in on this since the person with the issue seems to believe in their code more than the reality that their code didn't work.



If you see your code working as you designed it to work on a physical MCU (except for the interrupt part), you're bound to think it's functional, no? I've been working with these MCU for nearly 10 months now (used to work in assembly), so it's not like I don't know what I'm doing.

Anyway, I might add that I had to replace the PIC with a new one, and change the wiring in my board for it to work. The code works perfectly fine, and if anyone is still reluctant about it, I can upload a video to prove it.

Unfortunately, it seems that Douglas was right. We can have looked for a solution during hours since your hardware was bad... That is the first thing to check if you never successfully run a software on it. :-/
Personnaly I work with µC and program in embedded C and ASM for years. And I always produce code with a proper indentation and a lot of comments. It makes my job easier and the one of my colleagues too. ;-)
See you!

Matro
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