Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

PIC16F877A prevent queuing interrupts.

Status
Not open for further replies.
It should work as is. Are you typing the OK before the LEDs have stopped flashing? Try waiting.

For code tags, I just type them [ code] to begin and [/ code] (without the spaces) at the end.

Mike.
 
I think I know what may be the problem, try changing this bit,
Code:
            if(buff[0]=='O' && buff[1]=='K'){ //are they OK?
                flag=1; //yes so set flag
            }else{ //no so deal with it
To
Code:
            if(buff[0]=='O' && buff[1]=='K'){ //are they OK?
                flag=1; //yes so set flag
                count=0;
            }else{ //no so deal with it

Mike.
 
Last edited:
Copied. Tomorrow I will check this. once more i will share with you the conditions that im facing.

The 1st time I write OK.. i little few later the led process starts. after i wait it to finish, i write again OK. but nothing happends. then again i write OK and still nothing, and finally in the 3rd time i write OK. and the process starts again. i will be able to reply you during the next hours but i wont be able to make fixes since i ll be out of my house. Let me know if you think of something, i ll still trying to figure it out by myself also.
 
on second thoughts this shouldn't mater. The received values will just scroll through the buffer and get recognised by the test.
If you don't reset 'count' to 0 then on the next keypress it'll just continue to increment and overrun the char buff[2], likely trashing the 'count' and 'flag' variables.

The isr should check to make sure 'count' is < 2 before adding the char to 'buff', otherwise bad things will happen.
 
If you don't reset 'count' to 0 then on the next keypress it'll just continue to increment and overrun the char buff[2], likely trashing the 'count' and 'flag' variables.

The isr should check to make sure 'count' is < 2 before adding the char to 'buff', otherwise bad things will happen.
thats what i noticed some kind of overflow.. but i thought that when he used count-- he was decreasing the counter back to its initial position .. hmm
 
but i thought that when he used count-- he was decreasing the counter back to its initial position
Yes, but only if count == 2, and if you don't reset count then that only happens once every 256 key presses (but since 'count' gets trashed then who knows when that actually happens).
 
Yes, but only if count == 2, and if you don't reset count then that only happens once every 256 key presses (but since 'count' gets trashed then who knows when that actually happens).
i see, how you would suggest fixing this issue in the existing code ? should I declade count=0 at the end or something ? .
 
how you would suggest fixing this issue in the existing code
Rewrite the isr so that count never exceeds the size of the input buffer, and if you decrement count make sure it's not 0 before you decrement it. If you want to use the 'flag' variable, then post #22 should work ok. I'm not sure about bothering to decrement it at all...

PS - I just noticed count is an unsigned int, so it'll take a lot more than 256 for it to wrap. It'll still get trashed, though.
 
Code:
void interrupt ISR()
{
   if(RCIF)
   {
       buff[a] = RCREG;  /* read received byte from serial buffer */
       a++;
       
       if(RCSTAbits.OERR)  /* check if any overrun occur due to continuous reception */
       {           
           CREN = 0;
           NOP();
           CREN=1;
       }
       status_flag=1;  /* use for new message arrival */
   }

}

I have been searching and I found this model, what do you think about this one? guys ?
 
Code:
void interrupt ISR()
{
   if(RCIF)
   {
       buff[a] = RCREG;  /* read received byte from serial buffer */
       a++;
     
       if(RCSTAbits.OERR)  /* check if any overrun occur due to continuous reception */
       {         
           CREN = 0;
           NOP();
           CREN=1;
       }
       status_flag=1;  /* use for new message arrival */
   }

}

I have been searching and I found this model, what do you think about this one? guys ?
That's basically the start of all usart ISR's... If using a FIFO just change the RCREG read to the next available space in the FIFO..

When you get your head around using FIFO buffers, you'll wonder why you hadn't done it sooner!
 
That's basically the start of all usart ISR's... If using a FIFO just change the RCREG read to the next available space in the FIFO..

When you get your head around using FIFO buffers, you'll wonder why you hadn't done it sooner!
thanks sir. the only thing i think i should fix its to add the null caracter to the end to prevent trash information. also. the error check is necesary ? ..
 
It's always a good idea to check for OERR since that will stop all further receive ints until it is cleared.
The code in #30 isn't much different than the other. It has some of the same buffer overflow issues.

Try searching for 'ring' or 'circular buffer'. That'll get you proper fifo code.
 
All it needs is the little mod I posted above. If the buffer contains OK then set the flag and zero count. If not then scroll the buffer and decrement count. Hence count can never exceed 2.

Mike.
 
Alright, i was taking a good rest of today hehe .. i ll check Mike's fix, also about the circular buffer I still need to test two suggested models from Mike and other known member that they made a simply structure that I saved for later. This is because i want to understand how does it work before applying it, thats why im trying to dominate the basic concept before move further.
 
Here's my version of a circular fifo buffer,
Code:
#define FifoLength 32
unsigned char FifoBuffer[FifoLength];
unsigned char *FifoStart;
unsigned char *FifoEnd;
unsigned char count;

void InitFifo(void){
    FifoStart=FifoBuffer;
    FifoEnd=FifoBuffer;
    count=0;
}

void PutFifo(unsigned char chr){
    *FifoEnd++=chr;
    count++;
    if(FifoEnd==FifoBuffer+FifoLength)      //reached end
        FifoEnd=FifoBuffer;                 //yes so wrap
    if(FifoStart==FifoEnd){                 //is head eating tail?
        //fifo full so deal with it!!
    }
}

unsigned char GetFifo(void){
unsigned char chr;
    while(FifoStart==FifoEnd);              //if fifo empty then wait
    chr=*FifoStart++;
    count--;
    if(FifoStart==FifoBuffer+FifoLength)    //wrapped?
        FifoStart=FifoBuffer;               //yes
    return(chr);
}

unsigned char FifoCount(void){
    return(count);
}

You would call put fifo from your isr and get fifo from your main code - after checking that count > 0.

Mike.
 
The reason why I havent use the model you offered me weeks ago is because i dont dominate the concept, i was working in other stuff of the code so i didnt sit to read a little more, i have more or less an idea of how the circular buffer works but so far in my mind I cant see this "abstract" circular fifo to use it in my applications, I havent asked for more help because i felt that i need to try to figure first at least.

Im aware that the codes calls for the head and the tail but i still need to see how play with them to properly use them as intended.

By the way. Thanks a lot for your time, i appreciate it.
 
Done, the fix is working. Now it will always trigger as soon it gets "OK" no matter if it had a wrong combination before. as long its OK will work. Nice!
 
Thanks Mike, and also thanks to the rest..




Edit : one question, the part of the scroll buffer, will depend on the lenght of the buffer itself ?

thanks
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top