Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Problem with Keil C51 serial interrupt as it slows down the program

Status
Not open for further replies.

GrandAlf

Advanced Member level 2
Joined
Mar 9, 2002
Messages
520
Helped
47
Reputation
92
Reaction score
6
Trophy points
1,298
Location
UK
Activity points
4,730
Using the Atmel 89S8253 I found I needed to closely monitor the serial port. Not really used interrupts to any great degree as I always feel they are more difficult to debug. Rather surprisingly I find that after setting up an interrupt on 4 using 1 it worked ok, but the rest of the program ran really slowly I guess about 20% of normal speed. Tried it with different timers with same result. I found that running a separate task to monitor the port was much quicker. I am using delays and watchdog in the prog, and wonder if this would have any bearing. I found this quite odd, and wonder if this is normal behavior. Using Ke*l compiler btw. Any comments welcome.
 

keil c51 interrupt

Program running slow could be one of the following:
Your interrupt happens too frequently
Your interrupt routine is trying to do too much and therefore using 80% of processing time.
Delays in the prog should make no difference
watchdog might be resetting the processor?? Try turning it off. I usually only enable it after I have done my final testing, otherwise it might mask bugs
 

keil c 8051 interrupt example

Thanks for the advice, I will try and disable the WD and see what happens. I know it should only cost a few clock cycles in theory. Probably just done something stupid. Hi vanessa99, welcome to the board. Try and ask or answer questions, rather than just "hello".
 

interrupt 4 c51

the serial interrupt is not a problem

but always keep the interrupt simple and small so your application will not get effected

and also the interrupt occurrence period will effects the program execution time

so check your code and tell what is the actual problem is
 

    GrandAlf

    Points: 2
    Helpful Answer Positive Rating
keil watchdog interrupt

WD should olny take the cycles that you spend updating it. Apart from that it should not have any affect unless it is timing out and reseting your processor. What language are you using?
 

c51 serial

I am using Keil C51 C
I have done this just as a test.

unsigned char test; // declared outside of function
// Serial + global interrupts enabled

static void serial_isr (void) interrupt 4 using 2
{
if (TI) return;//Can I do this to ignore transmit ints ?
if (RI) test = SBUF;
}

Even with no serial activity the whole program runs very slow. Do not really understand, or am I missing something obvious here.
 

c51 global variable

It been a long time since I worked with 8051 but I think that you must set TI = 0 & RI = 0 in your interrupt routine even if you choose to ignore the data.
Disable the WD. Also make sure that your stack is not overflowing.
If this does not help perhaps you should show your code so that people can figure out where the problem is
 

    GrandAlf

    Points: 2
    Helpful Answer Positive Rating
serial interrupt in keil

Thanks for the info. I missed out resetting RI, just a typo on my part, it is there in the actual code. Will try again and reset TI, to see what happens. Just trying the basic routine first before putting it in the main code.
 

serial on c51

GrandAlf said:
I am using Keil C51 C
I have done this just as a test.


static void serial_isr (void) interrupt 4 using 2
{
if (TI) return;//Can I do this to ignore transmit ints ?
if (RI) test = SBUF;
}
try this:
Code:
void serial_isr (void) interrupt 4 
{
    if (RI) 
    {
         RI=0;
         test=SBUF;
    }
    if (TI) TI=0;
}
you need to clear the flags even if you do not use the data.
Otherwise the interrupt will be reentered after on asm code execute

usbman

Added after 52 minutes:

GrandAlf said:
I am using Keil C51 C
I have done this just as a test.


static void serial_isr (void) interrupt 4 using 2
{
if (TI) return;//Can I do this to ignore transmit ints ?
if (RI) test = SBUF;
}
try this:
Code:
void serial_isr (void) interrupt 4 
{
    if (RI) 
    {
         RI=0;
         test=SBUF;
    }
    if (TI) TI=0;
}
you need to clear the flags even if you do not use the data.
Otherwise the interrupt will be reentered after on asm code execute

usbman
 

    GrandAlf

    Points: 2
    Helpful Answer Positive Rating
sbuf serial interrupt

Thanks Guys for all your help. That seems to be the root of the problem, further reading confirms that you need to clear both. As I need to use printf within the prog at some point, I assume I will now need to disable/enable ES at the beginning/end of each print string.
 

keil 8051 serial interrupt programming

depending on how often data arrives the way to do it is to create a FIFO that gets written to by the interrupt and read by your main loop. You should always declare variables used in this way as "volatile" You need to make sure that your data in the FIFO is not overwritten by incoming data. If the data comes in faster than what you read / process it then you need some sort of handshaking on your comms port
 

c51 code with process

That is my ultimate intention. Just trying a simple setup to prove concept. Not really working as expected to date. What I am trying to do is to receive occasional single bytes on SI and then format and print them on SO with printf. As I am running at 300 baud, it takes a little while to print, so the idea was to buffer, so not to miss any that came in during the print process. All works fine until I try and use interrupts, which then appears to work, then just crashes on me. I am edging close to using my available memory, and wonder if that may be the problem. Will not run rtos tasks either, probably same reason. Will just have to keep at it.

Added after 23 minutes:

As I am using an externally declared variable as I need to pass the value, cannot use isr's as a function with return of course. this may be causing the problem. Will have to think of another way.
 

serial c51 gets

Be careful of using functions like printf in the interrupt. Not all of the library functions are re-entrant so they will cause problems in interrupts. Try do the formating with your own code and try avoid using the library code. Then at least you will know exactly what the code is doing in your interrupt. Make sure that you have enough stack allocated.
Do a Google search for a keil c51 serial interrupt example - you should find many
 

c51 serial library for 8051

Thats good advice and much appreciated. I have managed now to get the rtos to do pretty much what I want, so have abandoned the interrupt method for the time being. I have learnt a few more things due to everyones assistance, and am most grateful.
 

bug keil external interrupt

After a lot of messing about I find I cannot use rtos or interrupt because of ram limitations. As an alternative, I have decided to try a serial read routine, that is called around every 50ms. The idea is to set up a global array, then write to that, subsequently then read it later in main. example code is just to show the idea:

//outside of functions
unsigned char idata code[80];

//Data numeric value between 1 and 80 Data same as position i.e if sbuf 50 it would go to pos 50

void store_data (void)// called frequently
{
unsigned char index;
if (RI)
index = SBUF;
{code [index] = SBUF;//Puts Sbuf value in code
RI = 0;
}}

Now in main, I have a loop that reads through all 80 locations, and if it finds one >0 puts the value into a global variable, then acts upon it, and carries on the process until no more valid numbers. Between each read iteration, the store_data function is called. Appear to be writing ok, but when read, all appear to be 0. I have tried making the array volatile, no difference though. Am I doing something fundamently wrong here?. Advice appreciated.

Added after 5 minutes:

This is not working code, brackets wrong to start with. ust to show general idea
 

c51 serial port

O.K, I solved it.

If you do the RI condition test in main it works. Very strange!
 

09-c51-a

yes yes i too found out the error at first glance :D
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top