non waking delay routine

Status
Not open for further replies.

desijays

New Member
Hello everyone,

I am using a PIC16F877A micro controller. Im using timer0 to generate a 10ms delay and I have configured the timer0 to generate a software interrupt when the delay is over. But in the mean time I want the pic to be doing nothing else. That is, I want the pic to be idle. I don't know what to do. I can't use the sleep instruction cos when I do, there is no clock generation from the oscillator and so the timer does not work while asleep.

I am aware that I can use timer1 to accomplish the same thing when it receives its clocks from an external source,because then, I can use the 'sleep' instruction.

But I would like to know if I can do the same thing using timer0. Or is there any work-around or hack?

Thank you
 
Timer1 can have a 32KHz crystal which is very low power and runs during sleep. Or you could set the watchdog timer to wake it up, won't be 10ms though.
 
desijays said:
But in the mean time I want the pic to be doing nothing else.

You can't. The PIC has to do something once the clock is ticking.

However, you can ask it to check a bit in one of the register files. If the bit is 1, then please check it again, and again.....so if the bit is 1, then the PIC will check it forever and doesn't has time to do other things.

Now when the 10ms is up and the timer0 overflow interrupt happens, then inside the interrupt handling routine, you simply changes that register bit to zero and return. Now the PIC checks the bit and find it to be zero, so it can move on to do something else.
 
Code:
/-\
 |
 |
See eblc1388 suggestion above.

Code:
INITIALIZER:
                 ;TRIS OR GPIO
                 ;INTERRUPTS
                 ;PERIPHALS
                 CALL START_TIMER
;===MAIN====================
MAIN:
                 NOP
                 GOTO MAIN

ENDMAIN:
'===END OF MAIN==============
START_TIME:
                 ;CLEAR TIMER FLAGS
                 ;INITIALIZE TIME
                 ;ENABLE GLOBAL INTERRUPT
                 ;ENABLE TIMER INTERRUPT
                 ;START TIMER
                 RETURN
 
Last edited:
Code:
                 ORG            0x4    ;This is the ISR routine that executes when
                 GOTO          ISR    ;when TMR0 flips from 0xFF to 0x00

INITIALIZER:
                 ;TRIS OR GPIO
                 ;INTERRUPTS
                 ;PERIPHALS
                 CALL START_TIMER
;===MAIN====================
MAIN:
                 
                 BCF           PORTB,0            

                 NOP                     
                 GOTO MAIN

                 BSF           PORTB,1
                 
ENDMAIN:
'===END OF MAIN==============
START_TIME:
                 ;CLEAR TIMER FLAGS
                 ;INITIALIZE TIME
                 ;ENABLE GLOBAL INTERRUPT
                 ;ENABLE TIMER INTERRUPT
                 ;START TIMER
                 RETURN

ISR:
                BCF            INTCON,2
                RETFIE

Donnie, you will have to pardon me for paraphrasing your code !!

In the above code if you observe the label MAIN it can be seen that the statement "BSF PORTB,0" never gets executed. That is because, when the interrupt occurs the PC increments to the next statement before going to the interrupt. And in the above case the next statement is always either the "GOTO MAIN" or the "BCF PORTB,0" depending on when the interrupt occurs.

But I believe the code to set or clear the bit can be included in the interrupt instead of leaving it outside the ISR. In that case what you said will work I believe. Its in times like these I wish the PIC16F877A had a bit toggling instruction.

I remember hearing that it is important to keep the ISR as short as possible. That was the motive to have the bit setting and clearing code outside the ISR.

I'll give elbc's suggestion a try though, like you said. I get the feeling that might work.
 
Last edited:

I never thought about that. Well, thank you. I'll give it a try.
 
desijays said:
Its in times like these I wish the PIC16F877A had a bit toggling instruction.

It doesn't have one for a very good reason.

One can toggle a single bit or bit(s) in W using a single XORLW instruction, or any bit(s) in a file register with the XORWF instruction which requires you to first load the position of bit(s) to be toggled in W first. But it takes only a total of two instructions.
 
Thank you elbc. It worked on the MPLAB simulator. Although I don't know why it didn't work on my development board. I was trying to switch on and switch off an LED at 100ms interval using TMR0 and software interrupt. On the simulator it worked fine but on the board it didn't.

And again I don't think there was a problem with the board. Because when I uploaded a software version of the delay on to the 'mc', it worked flawlessly.

ill check again.
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…