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

Interrupt ... Interrupt ... can interrupts be interrupted?

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



Joined: 04 Apr 2005
Posts: 63

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

Interrupt ... Interrupt ... can interrupts be interrupted?
PostPosted: Thu Jun 30, 2005 9:51 am     Reply with quote

I'm trying to write a few lines of code to use interrupts for buffering data in and out of serial port using 16F877A.

I'm using the example codes with CCS.

My question is: Can each interrupt be interrupted by the other one?
here is my code:

any comment?

Code:

/***********************************************************
*     Program: NetMedia.c
*     Authro:  Jahan K Jamshidi
*     Date:    5.25.2005
*     MCU:     16F877A
*     Devices: NetMedia - SitePlayer
*     Description:
         This program will monitor serial data coming in
         from siteplayer and will display data on LCD.
         initial setup will send a request to get IP
         and will display it on LCD.  Then will request
         Status of siteplayer, if stat is 0x80, that means
         a data was posted to site player.
         a few things could happen:
            1. check for known values on memory of site
               player, read them and act accordingly.
            2. update EEPROM with number of hits on page
***********************************************************/

#include <16F877A.H>
#device *=16      // use 16-bit RAM address
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)

// #include "LCDD.c"       //LCD on D Port
#include <LCD.c>

#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7)

#define T_BUFFER_SIZE 64
byte t_buffer[T_BUFFER_SIZE];
byte t_next_in = 0;
byte t_next_out = 0;

#define R_BUFFER_SIZE 64
byte buffer[R_BUFFER_SIZE];
byte r_next_in = 0;
byte r_next_out = 0;

// interrupt to buffer outgoing serial data
#int_tbe
void serial_out_isr(void {
   putc(t_buffer[t_next_out]);
   t_next_out = (t_next_out+1) % T_BUFFER_SIZE;
   if(t_next_in == t_next_out)
      disable_interrupts(int_tbe);
}

void bputc(char c) {
   short restart;
   int ni;
   restart = t_next_in == t_next_out;
   t_buffer[t_next_in] = c;
   ni = (t_next_in + 1) % T_BUFFER_SIZE;
   while (ni == t_next_out);
   t_next_in = ni;
   if (restart)
      enable_interrupts(int_tbe);
}

// interrupt to buffer incoming serial data
#int_rda
void serial_in_isr(void) {
   int t;
   buffer[r_next_in] = getc();
   t = r_next_in;
   r_next_in = (r_next_in + 1) % R_BUFFER_SIZE;
   if (r_next_in == r_next_out)
      r_next_in = t;
}

#define kbhit (r_next_in != r_next_out)

byte bgetc() {
   byte c;
   while (!kbhit);
   c=buffer[r_next_out];
   r_next_out = (r_next_out + 1) % R_BUFFER_SIZE;
   return (c);
}

void main (void) {
   int Click;
   int Stat;
   int IP1,IP2,IP3,IP4;
   enable_interrupts(GLOBAL);
   enable_interrupts(int_rda);
   lcd_init();
   lcd_putc("Jahan Web Server");
   delay_ms(100);
   // get IP and show on LCD
   bputc(0xD3);      // next 3 = get IP address
   bputc(0xE6);
   bputc(0xFF);
   IP1 = bgetc();
   IP2 = bgetc();
   IP3 = bgetc();
   IP4 = bgetc();
   lcd_gotoxy(0,2);
   printf(lcd_putc,"%u.%u.%u.%u ",IP1,IP2,IP3,IP4);
   while (1) {
      bputc(0x10);          // get status
      Stat = bgetc();
      if (Stat != 0x00) {   // if 0x00 nothing has changed since last time
         lcd_gotoxy(0,3);
         printf(lcd_putc,"Stat: %U     ",Stat);
      }
      // if form submitted, check other stuff and get values.
      if (Stat == 0x80) {   // D7=1 of status byte = form submit
         output_high(PIN_A0);          // blink
         Click = read_eeprom(0x00);    // read clicks from EEPROM
         delay_ms(50);
         Click++;
         write_eeprom(0x00,Click);     // update clicks on EEPROM
         delay_ms(100);
         bputc(0x80);                  // next 3 = put click back on
         bputc(0x00);                  // memory location 0 to be display
         bputc(Click);                 // on the site by siteplayer
         lcd_gotoxy(0,4);
         printf(lcd_putc,"Clicks: %u",Click);   //show it on LCD
         output_low(PIN_A0);           // end blink
      }
   }
}

Ttelmah
Guest







PostPosted: Thu Jun 30, 2005 10:09 am     Reply with quote

No.
The interrupst will always be treated sequentially. The interrupt flags for the individual interrupts can still be set inside an interrupt, so as soon as the first interrupt exits, if the flag is set, the other code will get called.
There are exceptions on the latter (18) chips, but not on the 16 chips.
However it is important to realise that provided the response time of each handler is kept short, so that all the handlers can be executed in less time that the shortest interval between events, everything will be OK.
At the 'cost' of an extra storage location, you can speed up the handlers significantly, by storing the count seperately. This then allows much faster testing for the buffer being empty/full etc.. Also, if the buffers are binary multiples (as yours are, 16, 32, 64 bytes etc.), it is faster to just use '&' to calculate the remainder, than to use the modulus function.
So the line:
ni = (t_next_in + 1) % T_BUFFER_SIZE;

will be faster as:

ni=((t_next_in + 1) & (T_BUFFER_SIZE-1));

Best Wishes
jahan



Joined: 04 Apr 2005
Posts: 63

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

PostPosted: Thu Jun 30, 2005 11:16 am     Reply with quote

Thankx for help.

I have a quick question about:
Code:

void bputc(char c)
...
restart = t_next_in == t_next_out;
...


is this correct?

does it to do == first then =
restart = (tnext_in == t_text_out)

or the other way around?
bfemmel



Joined: 18 Jul 2004
Posts: 40
Location: San Carlos, CA.

View user's profile Send private message Visit poster's website

PostPosted: Thu Jun 30, 2005 11:31 am     Reply with quote

Quote:
is this correct?

does it to do == first then =
restart = (tnext_in == t_text_out)

or the other way around?


This is basic C, Chapter 2 in K&R. The comparison operator, "==", has higher precedence than the assignment operator, "=", so the parenthesis are not required although if in doubt you should use them. They sometimes do make the code more readable.
Code:

restart = (tnext_in == t_text_out);

// is the same as

restart = tnext_in == t_text_out;


- Bruce
jahan



Joined: 04 Apr 2005
Posts: 63

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

PostPosted: Thu Jun 30, 2005 12:15 pm     Reply with quote

second part:

Code:

void bputc(char c) {
   short restart;
   int ni;
   restart = t_next_in == t_next_out;
   t_buffer[t_next_in] = c;
   ni = (t_next_in + 1) % T_BUFFER_SIZE;
   while (ni == t_next_out);          // ******** HERE ****
   t_next_in = ni;
   if (restart)
      enable_interrupts(int_tbe);
}


see ********** HERE ********* above ...
doesn't the code get "stuck" in a loop if ni is always equal to t_next_out?
Guest








PostPosted: Thu Jun 30, 2005 12:26 pm     Reply with quote

Quote:
doesn't the code get "stuck" in a loop if ni is always equal to t_next_out?


It's a circular buffer so you are waiting for a byte to be sent out until you can put another byte into the buffer. This is only going to happen when the buffer is full. The variable t_next_out is changed in the serial_out_isr() interrupt routine.

Confused I thought this was your code?

- Bruce
jahan



Joined: 04 Apr 2005
Posts: 63

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

PostPosted: Thu Jun 30, 2005 12:30 pm     Reply with quote

the part of NetMedia is mine.
as I mentioned earlier,
Quote:
I'm using the example codes with CCS.


Thank you for your help ... 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