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.

PIC16F628A - sleep in interupt routine.

Status
Not open for further replies.

Blueteeth

Well-Known Member
Hi, its been a while :)

Ok, I have a battery powered project that uses 3 software UART receivers - connected to three sensors on different pins. The hardware UART is used for an RF module, and the sensors only respond when 'pinged' so I can receive them one at time. The software simply pings each sensor at a time, gathers results from each, then sends these via an RF transciever - it them goes to sleep. The only way to wake it up is a pushbutton connected to thre MCLR pin. This means it spends much of its time asleep, a button press wakes itup, it does its job an goes back to sleep - very simple.

I would like to implement a 'timeout' function in case a connection to one of the sensors is damaged. Currently, because I'm using a basic software UART, it simple continuously waits for a start bit in each of the UART routines. This means the unit remains 'powered up' and uses precious current should a fault condition occur.

I've thought about using the watchdog timer, but that would wake it up from sleep every so often, and because of current consumption, I would prefer it to remain in sleep mode until the MCLR pin is pulled low (hardware reset). Plus, as I'm using three of these UARTS, constantly checking a timer (like a TMR0 overflow) woudl have to be in many many places in the code.

So, I'm thinking of setting up timer0 (or any of the timers) to provide an interrupt after a timeout period, then, inside the interrupt routine it raises a flag to indicate a timeout condition then 'jumps' (using the goto instruction) to the end of the code where it powers down and sleeps. - I realize this is very bad practice (not returning form interrupt, or any subroutines) but my thinking is, once sent to sleep it can *only* wake up with a hardware reset.

I know the hardware reset forces the PC to 0x0000, but does the stack clear upon reset? My fears are, as I'm calling subroutines quite often (and returning from them), if inside one of these subs, the interrupt pings but goes straight to the end of the code (then sleep) than I'll have two addresses in the stack. If these aren't cleared upon a hard reset after sleep, then I'll get a stack overflow.

Any idea's on implementing a timeout for a software UART? I'm writing in assembly (original project was done 7 years ago lol). It is fairly unique in that should a timeout occur, then it just has to go to the error routine (flashing LED's) then sleep - without needing to store anything from that session.

EDIT:
Ok, I just realised that I'm dumb - for every call the stack gets an address popped in, last address that goes is is the first one out, so sending the code to another part with 'goto', then sending it to sleep won't matter - because the only thing that can wake it up is a reset. And as code will always call a subroutine first, the latest address will be the one available, any remaining return addresses will be discarded or over written. So it should work just fine.

I didn't delete the post because there may be other ways for creating a 'timeout' for software UART's, and others may benefit from any replies here.
 
Last edited:
Hardware reset does reset the stack and so I can't see anything wrong in what you propose.

Mike.
 
Yes a hardware reset clears the stack pointer.
If I was to implement a timeout instead of using up a peripheral reource I'd just include in the loop where the chip waits for a communication a counter, it'd have to be 16 bit, and increment it every loop, if it gets to a predetermined value or just rolls over then create an exception and handle the error.
If you dont want to bomb out during an interrupt (which isnt best practice as if you want to change the code later you might leg yourself up) you can use a bit to flag the error, set the bit in the interrupt and then when the inetrrupt returns poll the bit, if its set then clear it and bomb out.
 
Thanks for the answers guys - as you can tell I realized that it doesn't *really* matter in this case, but I its always good to get some other views on it - as you pointed out Dr Pepper, its not best practice and I have been stung by using such techniques before. Being called by the customer a few years after a contract for a firmware upgrade/modification and have to revisit it along with all the 'bugs/quirks' I put in it >.<

Incrementing a counter every time one waits for a start bit would be nice (along with perhaps a small delay), and I'll keep that in mind for future projects - but for this one the sensors respond anywhere between 15 and 140ms, so with an increment loop whilst checking for start bit, that's say...er.. 4/5 instructions. At 4Mhz, 1us instruction, a 16-bit counter would provide over one second timeout, handy. Plus for convenience, I guess I would only have to check if the upper byte is zero, assuming one preloads the counter with the correct integer.

Setting flags in interrupt routines is what I usually do, especially when using many interrupt sources (one PIC18 project I had used 12...ugh) and I should only have to check that flag whilst waiting for a start bit. The timer will only be turned off once a full packet has been received (only 9 bytes).

Cheers guys
 
Being lazy and fudging software has got me a few times, after you've spent hours staring at the screen looking for a bug you start to write code with some structure.

You could also use the watchdog timer to do this, though that makes things complex if your using .asm.

I'm working on a program now that transmits 18 bytes rs232, and also transmits 4 bytes old fashioned 5 bit teletype, the code uses 3no 8 bit registers just for flags, defining each one with a meaningfull name makes mplabs debug tool very useable.
 
The watchdog timer would have been ideal, however, as this project spends vast majority of its time in sleep, which can be for days at a time, the watchdog would wake it up regularly.

So upon wakeup, I would have to check if that pinged, and send it back to sleep. Sure it'll only wake up for a few instructions, but if I set the timeout to a second, that's once a second. It'll be a tiny duty cycle but still trying to keep the power consumption down here :)

Breaking up bytes to individual flags owns (!!). The biggest project I did used 4-5 bytes and you're right, naming them makes it 'not impossible' to see whats happening.
 
Other later pics you can enable/disable the watchdog during runtime, so you could shut everything down during sleep.
 
Last edited:
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top