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

2 INT_EXT Problem

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



Joined: 23 Apr 2005
Posts: 73

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

2 INT_EXT Problem
PostPosted: Sat May 21, 2005 3:26 am     Reply with quote

I have a program that updates an LCD every time a button is pressed (I have 2 connected to the INT_EXT and INT_EXT1 pins). Unfortunately the interrupts only seem to work sporadically. Sometimes they both work, sometimes not at all (this is most of the time) and ocasionally only one works! When I say that these happen occasionally I mean between powerups of my circuit. I know immediately which interrupts will work upon powerup. The frustrating part is that some of the time it works, so I really don't know what to change. Could it be that I have too much in my ISR's? I used to have less code in them and the interrupts worked every time. All of the LCD stuff works fine. Here is my code:
Code:

#include <18F1220.h>
#fuses NOWDT,NOPROTECT,NOLVP,NOMCLR,INTRC_IO //CCPBO
#use delay(clock=8000000)
#include "lcdporta.c"

#define LCD_COMMAND 0
#define LCD_DISPLAY 1
#define LCD_CG_RAM 0x40

int leftArrowPos = 17;
int rightArrowPos = 18;

#int_ext
void move_right()
{
   if(input(PIN_B0))
   {
      if(leftarrowpos + 1 != rightarrowpos)
      {
         printf(lcd_putc,"\fAuto      D\1\2\2\2\2\2\2\2\2\2\2\3\7");
         printf(lcd_putc,"\nManual");
         leftarrowpos += 1;
         lcd_gotoxy(leftarrowpos,2);
         printf(lcd_putc,"\5");
         lcd_gotoxy(rightarrowpos,2);
         printf(lcd_putc,"\5");
      }

      else
      {
         printf(lcd_putc,"\fAuto      D\1\2\2\2\2\2\2\2\2\2\2\3\7");
         printf(lcd_putc,"\nManual");
         leftarrowpos = 12;
         lcd_gotoxy(leftarrowpos,2);
         printf(lcd_putc,"\5");
         lcd_gotoxy(rightarrowpos,2);
         printf(lcd_putc,"\5");
      }
   }
   clear_interrupt(int_ext);
}

#int_ext1
void move_left()
{
   if(input(PIN_B1))
   {
      if(rightarrowpos - 1 != leftarrowpos)
      {
         printf(lcd_putc,"\fAuto      D\1\2\2\2\2\2\2\2\2\2\2\3\7");
         printf(lcd_putc,"\nManual");
         rightarrowpos -= 1;
         lcd_gotoxy(rightarrowpos,2);
         printf(lcd_putc,"\5");
         lcd_gotoxy(leftarrowpos,2);
         printf(lcd_putc,"\5");
      }

      else
      {
         printf(lcd_putc,"\fAuto      D\1\2\2\2\2\2\2\2\2\2\2\3\7");
         printf(lcd_putc,"\nManual");
         rightarrowpos = 23;
         lcd_gotoxy(rightarrowpos,2);
         printf(lcd_putc,"\5");
         lcd_gotoxy(leftarrowpos,2);
         printf(lcd_putc,"\5");
      }
   }
   clear_interrupt(int_ext1);
}
.
.
.
.
void main()
{
   output_a(0x00);
   output_b(0x00);
   enable_interrupts(int_ext);
   enable_interrupts(int_ext1);
   enable_interrupts(global);
   clear_interrupt(int_ext);
   clear_interrupt(int_ext1);
   lcd_init();
   Store_Custom_Char();
   printf(lcd_putc,"\fAuto      D\1\2\2\2\2\2\2\2\2\2\2\3\7");
   printf(lcd_putc,"\nManual          \5\5");
   while(true);
}

Any ideas?
Bryan



Joined: 23 Apr 2005
Posts: 73

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

PostPosted: Sat May 21, 2005 3:35 am     Reply with quote

Also, I am already nearing the memory limit on my PIC. When I compile, I have used 77% or so of ROM. Is there a way to take more advantage of the PIC's memory (I saw a post about this for one of the 16 series PICs) with some sort of software instruction or do I need to buy a PIC with more memory? I have a lot more to do for this project, so I need more memory one way or the other...
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

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

PostPosted: Sat May 21, 2005 6:37 am     Reply with quote

Code:
   output_b(0x00);


This instruction will write a 0 to portb. Since standard_IO is by default this will also make all of portb outputs. But you are using RB0 & RB1 as inputs. Where do you set that up? Look in the manual or help file at set_tris functions. Also, by default the compiler clears the interrupt flags so that is not necessary in your interrupt handler. Also, I wouldn't make my interrupts that big. Set a flag in the interrupt and process the flag in the main loop.
ckielstra



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

View user's profile Send private message

PostPosted: Sat May 21, 2005 10:30 am     Reply with quote

Bryan wrote:
Also, I am already nearing the memory limit on my PIC. When I compile, I have used 77% or so of ROM. Is there a way to take more advantage of the PIC's memory (I saw a post about this for one of the 16 series PICs) with some sort of software instruction or do I need to buy a PIC with more memory? I have a lot more to do for this project, so I need more memory one way or the other...
As a rule of thumb I design my projects with 50% of free memory space in mind. Then when the project continues new features are added until finally all memory will be used. If you are now already at 77% of ROM, then something in your design is wrong or you are using a processor with a much too small memory size. The 18F1220 has only 4kb of memory sufficient for 2048 instructions. This is one of the smallest memory sizes in the PIC18 series and might have been a warning to you... Without knowing the details of your project I can't say whether the 4kb memory size is large enough.

The option you are referring to for the PIC16 series is probably the #device *16 option? There is no such magical parameter for the PIC18 because the PIC18 has a more efficient memory handling by default.

One suggestion: Applications handling text output tend to use a lot of memory for storing the texts. You might consider storing al text data in an external memory device like serial Flash or Fram.

In your posted code I see four times an almost equal code sequence, a huge optimization can be achieved here by implementing one or more generic functions.

Consider buying one of the larger chips, for smaller projects its a lot cheaper to spend a few more dollars on hardware than hours in development to make the application fit tight memory restrictions.
Bryan



Joined: 23 Apr 2005
Posts: 73

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

PostPosted: Sat May 21, 2005 9:09 pm     Reply with quote

I took out the port clear instructions (output_a(0x00) and output_b(0x00)) plus used flags in the ISRs as you had suggested Mark and everything works great now. I was under the impression though that in standard IO mode the PIC senses what you are trying to do and adjusts the tristate buffers appropriately. Is that incorrect?

Amazingly (to me anyway), adding code in the ISR's takes up MUCH more memory than just adding it in main. When I condensed that code into one display refresh function and put all the event handling inside the main loop when triggered by flags, my memory usae dropped from around 80% to 29%! Now, after adding a lot more code I still have only used 39% of ROM. Looks like I will end up hitting the target you suggested ckielstra at approximately 50% ROM usage by the time everything is coded in. Thanks for the help guys!
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

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

PostPosted: Sat May 21, 2005 9:23 pm     Reply with quote

It is true that the input() function with standard IO will set the pin to be an input but you have it inside an ISR routine that will only get called if the pin is already configured as an input.
Bryan



Joined: 23 Apr 2005
Posts: 73

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

PostPosted: Sat May 21, 2005 9:29 pm     Reply with quote

Ok gotcha. That must have been it. One more question: I need to use an A/D to read in some analog voltages, but the only available A/D port is port AN6 on pin10 and it isn't working when I hook everything up. I had heard that if you are only going to use one A/D port that it must be AN0. This would shoot down my whole project unfortunately if that is so since I have all of the others used for other things and AN0 MUST be used for my LCD (Unless I were to change to another PIC). Is there any way around this? Here is my A/D setup code, but I'm pretty sure it is correct since I have gotten it to work in the past using AN0:

Code:

void main()
{
   setup_adc_ports(sAN6);
   setup_adc( ADC_CLOCK_INTERNAL );
   set_adc_channel(6);
   setup_timer_0(RTCC_INTERNAL);
   enable_interrupts(INT_RTCC);
   enable_interrupts(int_ext);
   enable_interrupts(int_ext1);
   enable_interrupts(int_ext2);
   enable_interrupts(global);
   lcd_init();
   Store_Custom_Char();
   redisplay();
.
.
.
.
}
Bryan



Joined: 23 Apr 2005
Posts: 73

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

PostPosted: Sat May 21, 2005 9:40 pm     Reply with quote

Please disregard the above, I wasn't seeing the A/D update (I have it outputting to the LCD real time) because in the main loop I only call refresh when an interrupt occurs so I hit one of my buttons and whala, my A/D refreshed. Apparently you can set the A/D to a port besides AN0 when you are only using one. Thanks again for the help!
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