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_rda And RTC int conflict ?

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



Joined: 13 Oct 2007
Posts: 53
Location: Texas

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

#int_rda And RTC int conflict ?
PostPosted: Tue Jan 15, 2008 7:38 pm     Reply with quote

if i have a interrupt for serial receive and one for the real time clock will the serial receive interrupt bother the rtc interrupt ?
By experimenting i see that it does :( anyone have a good idea how to do this without screwing up my RTC ?
Code:
#int_rda
void serial_isr() {
   char String[10];                           // for user input
   int result = 0;
   printf("Your Command:");
   get_string(String,10);
  }
 



also when doing this strcmp(String,"hi"); i always get "bad expression syntax" error ?





// dont read this --------------------------- below here is solved already
I'm new to interrupts. I just wanted a interrupt to tell me when I'm getting message through the rs232. That way my pic can be doing whatever its supposed to do but when i log onto it via the comm port it will greet me with a small menu and take commands. Afterwords i need it to turn off the interrupt.

As it is now it works but it does not stop. If i log onto the com or restart the pic while logged on and then hit a key it keeps looping the interrupt and printing out to my terminal screen (flooding it).

the interrupt function
Code:
////////////////////////////////////////
// Interrupt on serial RX
////////////////////////////////////////
#int_rda
void serial_isr() {
   printf("got serial rx");
}


In my main
Code:

   // interrupts
   enable_interrupts( GLOBAL );             // use the ints
   enable_interrupts(int_rda);              // int on serial RX


NEVERMIND, IM DUMB
the interrupt is when there is information available all i needed to do was take the string/char coming in to stop it from interrupting
Code:

_________________
Smart people know how stupid they are.
zonemikel



Joined: 13 Oct 2007
Posts: 53
Location: Texas

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

this is what i did
PostPosted: Tue Jan 15, 2008 8:26 pm     Reply with quote

not sure if this is the best method and i know im loosing a little bit of my RTC every time i log in but this is all i can think of.

As soon as rda is tripped it turns rda int off and sets userconnected to 1 then if you exit it will turn the int back on. Im going to also make it so it logs the time the user last was active and if its been more than 10 minutes log that user out, this will prevent the user (me) from staying logged on forever if i forget or am unable to log out (x).

Code:
////////////////////////////////////////
// Interupt on serial RX
////////////////////////////////////////
#int_rda
void serial_isr() {
   disable_interrupts(int_rda);            // stop this int
   UserConnected = 1;                      // make a user
}


and in my main inside the while(1) i have
Code:
if(UserConnected)
   {
         delay_ms(500);                      // let them open their eyes
         printf("\n\r Hello There, You Connected at");
         printf("\n\r Time: %d/%d/%d %d:%d.%d",Months,Days,Years,Hours,Minutes,Seconds);
         printf("\n\r m=menu s=settime x=dissconnect");
         while(UserConnected)
         {
         delay_ms(200);                       // so they dont flood me
         printf("\n\r Your Choice:");          // prompt for item
         get_string(String,10);
         if(String[0] == 's'){SetupTime();}   // setup time (set clock)
         if(string[0] == 'x'){                // disconnect
            UserConnected = 0;                // set user to 0
            enable_interrupts(int_rda);       // resetup interrupt
            }
         }                                       
   }


You might see now why i want to use the strcmp function !! I want to be able to type in commands and not just letters, any ideas ?
_________________
Smart people know how stupid they are.
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Wed Jan 16, 2008 2:58 am     Reply with quote

strcmp will only take variables and not literals. It says the same for strcpy but that is wrong and a little pointless!

Code:

#define MAX_MATCH 10

char match[MAX_MATCH];
strcpy(match, "command");
if (strcmp(match, buf) == 0) {
 // Execute command
}


I have extended this to use an array of commands which I search through to match the input and then use a select on the index of the found command.
Also, I read the input character into a buf within the #INT_RDA and set a flag when '\r' is entered to indicate a command has been entered. Remembering to null terminate the input buf.

Code:

char rs232_buf[80];
byte count = 0;
int1 command_flag;

#INT_RDA
void serial_isr() {
   char c;
   while (kbhit()) { // proberbly NOT required
      c = getc();
      if (c == '\r') {
         disable_interrupts(INT_RDA);
         rs232_buf[count++] = '\0';
         command_flag = true;
         printf("\r\n");
      } else {       
         rs232_buf[count++] = c;
         putc(c); // echo char
      }
   }
}
[/code]
Ttelmah
Guest







PostPosted: Wed Jan 16, 2008 4:16 am     Reply with quote

First key thing, is keep the time spent in any interrupt handler _short_.
The INT_RDA, means that just _one_ charater is waiting to be read. Read that character, and return _quickly_. Your 'demo' code, instead tries to receive a sequence of characters, and will _wait_ till this sequence arrives. As such, it'll interfere with everything else.
Two approaches:
1) _Buffer_ the incoming characters. Look at EX_SISR.
2) Build a 'tree' parser.
For the second, what you do, is receive just _one_ character, and see if it matches the next expected character. If it does, you change 'state' (a 'state machine'), to move to the next search test for the next character. You walk 'down' the branches of the tree, till either you rach the end (with a god match), or something goes wrong, and you have to start searching again. With this, you again return quickly, once the single 'this is a 'good' character, or this is not test has been done.
For your example:
Code:

const char keyword[]="command";

#INT_RDA
void char_received(void) {
   static int8 charno=0; //note _static_
   char rcvd;
   rcvd=getc();
   while (true) {
       if (rcvd==keyword[charno++]) {
           //here character matches
           if (keyword[charno]=='\0) {
              //here we have reached the end of the command string
              //do what you want....
              charno=0;  //restart searching
           }
           break; //exit test
       }
       else {
           if (charno==1) {
               //Here have failed on the first character
               charno=0;
               break;
           }
           else {
               //doesn't match, so start try again
               charno=0;
               //note this _retries_ the incoming character, against the first
               //test character
           }
       }
    }
}

Now, this is a rather 'oversimplified' version, looking for just one command, but it shows the approach. The interrupt checks just the single received character, against the next character in the test strng. If the next test character is the 'null' character,then the whole string has been matched.
In common with a lot of things of this sort, the commands look long, but in execution terms, the _time_ involved is short, which is what matters in the interrupt.

Best Wishes
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Wed Jan 16, 2008 4:30 am     Reply with quote

Ttelmah

My code does not wait for a specific sequence of characters and will not WAIT for anything. It reads any and all chars in the input buffer and transfers them to my buffer. it sets a flag when end of line is returned.

You have contradicted yourself.
you said the ISR should retrieve the character and exit. YOU have an infinate loop which scans a (single) keyword. Although this will only ever do 2 iterations it is still a waste of time.

If there are more than 1 keyword then your routine (when modified) will slow down quite quickly as it has to check the first char of each keyword and then if more than one keyword matches on the first char has to somehow check the second char of each of those and so on!
SET



Joined: 15 Nov 2005
Posts: 161
Location: Glasgow, UK

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Wed Jan 16, 2008 8:01 am     Reply with quote

Wayne_ wrote:

Quote:
Code:
char rs232_buf[80];
byte count = 0;
int1 command_flag;

#INT_RDA
void serial_isr() {
   char c;
   while (kbhit()) { // proberbly NOT required
      c = getc();
      if (c == '\r') {
         disable_interrupts(INT_RDA);
         rs232_buf[count++] = '\0';
         command_flag = true;
         printf("\r\n");
      } else {       
         rs232_buf[count++] = c;
         putc(c); // echo char
      }
   }
}


Pretty much the approach I use - using kbhit is a good idea for processors that may have FIFO buffering and fast baud rates, so its more portable code. I would probably move the 'printf("\r\n")' out of the ISR though.

The difference between this code and Ttelmah's is that this code looks for CR terminated strings, and then parses them, while Ttelmah's looks for valid start characters, so it parses as chars are received - I think each approach has it's place Smile
Ttelmah
Guest







PostPosted: Wed Jan 16, 2008 9:19 am     Reply with quote

Wayne_ wrote:
Ttelmah

My code does not wait for a specific sequence of characters and will not WAIT for anything. It reads any and all chars in the input buffer and transfers them to my buffer. it sets a flag when end of line is returned.

You have contradicted yourself.
you said the ISR should retrieve the character and exit. YOU have an infinate loop which scans a (single) keyword. Although this will only ever do 2 iterations it is still a waste of time.

If there are more than 1 keyword then your routine (when modified) will slow down quite quickly as it has to check the first char of each keyword and then if more than one keyword matches on the first char has to somehow check the second char of each of those and so on!


get_string, _waits_ for a terminated string...

No, I say that the ISR should be _quick_. The handler a shown, does one test to see if the character matches the 'current' character in the array. If it does, it then tests if the next array character is zero. Total time about 20 machine instructions. If no match, then it tests again against the first character. As I say, it looks complex, but except for the array accesses, is fast code.
In fact you can make the code very fast for multiple keywords. What you do, is have the keyword array in alphabetic order, and have a row/column index. When a new character arrives, it tests the row/column on the array. If the match succeeds if moves one right (along the row), if the match fails, it moves down one row. If it hits the '\0' when it moves right, the row number is the command number matched. If the test character is lower than the current character, when it moves down, it moves down again.
I have such a system, handling comms at over 500Kbaud, on a system with five other interrupts in use, and some of these have been running reliably for over 8 years, without 'missing a beat' (or a character...).

Best Wishes
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Wed Jan 16, 2008 10:24 am     Reply with quote

SET

I have already moved that printf and I removed the kbhit test as well as it is not required in this context.

Re-examining the code due to this thread sure helps improve things, a bit.
SET



Joined: 15 Nov 2005
Posts: 161
Location: Glasgow, UK

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Wed Jan 16, 2008 10:56 am     Reply with quote

Quote:
I have already moved that printf and I removed the kbhit test as well as it is not required in this context.

Re-examining the code due to this thread sure helps improve things, a bit.


I agree, good code is rarely 'write once' Smile
zonemikel



Joined: 13 Oct 2007
Posts: 53
Location: Texas

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

PostPosted: Wed Jan 16, 2008 12:10 pm     Reply with quote

I dont get it. If the object is to keep your interrupts as short as possible than whats wrong with my code. All it does upon the interrupt is disable the interrupts and set a variable (userconnected) to 1 then i can take care of the users input in the main so its not holding up the other interrupts.
Code:

////////////////////////////////////////
// Interupt on serial RX
////////////////////////////////////////
#int_rda
void serial_isr() {
   disable_interrupts(int_rda);            // stop this int
   UserConnected = 1;                      // make a user
}


Wouldnt that be faster than any code to actually get strings from this function ? once user connected is 1 it will catch that in my main

THIS IS IN MAIN()
Code:
if(UserConnected)
   {
         delay_ms(500);                      // let them open their eyes
         printf("\n\r Hello There, You Connected at");
         printf("\n\r Time: %d/%d/%d %d:%d.%d",Months,Days,Years,Hours,Minutes,Seconds);
         printf("\n\r m=menu s=settime x=dissconnect");
         while(UserConnected)
         {
         delay_ms(200);                       // so they dont flood me
         printf("\n\r Your Choice:");          // prompt for item
         get_string(String,10);
         if(String[0] == 's'){SetupTime();}   // setup time (set clock)
         if(string[0] == 'x'){                // disconnect
            UserConnected = 0;                // set user to 0
            enable_interrupts(int_rda);       // resetup interrupt
            }
         }                                       
   }

so the serial rx interrupt is not enabled again until the user disconnects that way it wont use the interrupt to do anything besides connect/disconnect a user all the string handling or anything else will be done in the main where it will not interfere with my Clock (because i have a interrupt based clock running also)

Note: im not trying to be arrogant or anything im just trying to explain my code to the best of my knowledge so someone can point out whats wrong with it ? Thanks for all your input so far !
_________________
Smart people know how stupid they are.
SET



Joined: 15 Nov 2005
Posts: 161
Location: Glasgow, UK

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Thu Jan 17, 2008 9:52 am     Reply with quote

Zonemikel, there is nothing wrong with your code, it just does a slightly different job to the other examples. Yours 'wakes up' on a key press, then waits for the user to type a command (terminated by CR). As long as your users are 'well behaved' and only type when they see the prompt then it will work.
zonemikel_guest
Guest







PostPosted: Thu Jan 17, 2008 1:00 pm     Reply with quote

Ok, yes since it will only be me using it i should be ok. Also if you type the wrong char it wont crap out on you it will just ignore it. It seems to be working pretty well

let me check it . . .
ya just logged on and the time is current, its been running for about two days now.

I need to make it so if the user does not disconnect they will be logged off after a while.

I will print out all the code posted in this thread and look it over with care. Thanks for all your help(s).

mike
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Fri Jan 18, 2008 2:56 am     Reply with quote

Yes, your code should be fine. My first post to this was to show you where the problem is with using strcmp.
I also through in the code showing how I read the serial port incase you found it usefull. It has been done many ways and will continue to be implimented in different ways.
nirayo



Joined: 23 Feb 2009
Posts: 10

View user's profile Send private message

Re: #int_rda And RTC int conflict ?
PostPosted: Wed Aug 19, 2009 2:03 am     Reply with quote

zonemikel wrote:
if i have a interrupt for serial receive and one for the real time clock will the serial receive interrupt bother the rtc interrupt ?
By experimenting i see that it does :( anyone have a good idea how to do this without screwing up my RTC ?
Code:
#int_rda
void serial_isr() {
   char String[10];                           // for user input
   int result = 0;
   printf("Your Command:");
   get_string(String,10);
  }
 



also when doing this strcmp(String,"hi"); i always get "bad expression syntax" error ?





// dont read this --------------------------- below here is solved already
I'm new to interrupts. I just wanted a interrupt to tell me when I'm getting message through the rs232. That way my pic can be doing whatever its supposed to do but when i log onto it via the comm port it will greet me with a small menu and take commands. Afterwords i need it to turn off the interrupt.

As it is now it works but it does not stop. If i log onto the com or restart the pic while logged on and then hit a key it keeps looping the interrupt and printing out to my terminal screen (flooding it).

the interrupt function
Code:
////////////////////////////////////////
// Interrupt on serial RX
////////////////////////////////////////
#int_rda
void serial_isr() {
   printf("got serial rx");
}


In my main
Code:

   // interrupts
   enable_interrupts( GLOBAL );             // use the ints
   enable_interrupts(int_rda);              // int on serial RX


NEVERMIND, IM DUMB
the interrupt is when there is information available all i needed to do was take the string/char coming in to stop it from interrupting
Code:


you can use the #priority dirctive, and set which one will be handled first, if both accure at the same time
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