by Brendon Archibald [websales optusnet.com.au]
Source Code for 16F648A (Verified)
Source Code for 16F628A (Verified)
The purpose of this project was to create a five minute timer that beeps and restarts when it reaches zero. It would be used by psychologists when conducting surveys with patients, no such commercial product was available.
Whilst this project was designed with a purpose in mind it was also an experiment to see what can be done with PICs and as an educational device when teaching myself about code.
The original code/project was by Bruce Gennette and Stan Ockers and is available at
http://www.piclist.com/techref/microchip/cntdn/index.htm (Many thanks to Stan for the well commented code.)
Whilst Stan's code was a good template there were several things I needed it to do to fulfil my needs:
The result is a very useful timer that can run off a pair of AAA batteries and fits in a small case. A bonus of an internal 4Mhz oscillator and extra pins enabled me to do away with the crystal and 4511 decoder. The accuracy of the internal oscillator is not great but will suffice for my applications, I wouldn't suggest this projects use for very accurate timing sequences or for long time counts i.e.. Hours.
Whilst I have used the 16F648A for this project example it was only because that's what I had, a cheaper option would be the 16F628A as the code will fit without a problem.
Oh yeah I almost forgot the disclaimer, I am not an "accredited software engineer" nor do I proclaim to be an expert of any kind in electronic engineering. I'm just a tinkering technician dabbling in assembly code and the bumper sticker "Don't follow me I'm lost too" comes to mind. Any pain, damage, expense or loss is NOT my responsibility, especially the expense part. Having said that I am fully aware that this code could be be done a lot better even using the other timers available in the 16F6X8 series, not to mention my very crappy code.
When power is applied the first stored count time is displayed on the four 7 segment displays.
The two buttons control all functions of the timer, the START button is 4 fold:
1: A short press will start or stop the countdown
2: A long press will turn the timer off or activate SLEEP (Power off)
3: Whilst off or in SLEEP mode a short press will turn the timer on.
4: Whilst in SET mode it will increment the segment (i.e.. Choose time)
The other button is the SET button which has 3 functions:
1: A short press whilst not counting will select 1 of 15 presets (All settable)
2: A long press whilst not counting will enable SET mode for that preset showing the tens of minutes to be set
3: Whilst in SET mode a short press will change to the next digit to be set until all digits are set where it will lock it in
Under normal operation a press of the START button will initiate the countdown, when zero is reached the piezo element will emit a short series of beeps. (The duration and number of which can be easily set in code)
When the beeps have stopped the count will reset to the last preset value and restart the countdown, this will continue until the STOP button is pressed where the display will reset to the last preset value.
If, whilst in this state, no activity is detected on any of the buttons for approximately 2 minutes then an auto power off routine will activate initiating 2 short beeps before enabling the sleep function.
Although the circuit shows an output for "count in progress" this has been omitted in the code for two reasons:
1: The output would not function correctly at 2.4Volts so I decided against it, something to do with device constraints.
2: We live in an age where things that are taken for granted are used to abhorrent ends and I didn't want to part of that.
If you really want the output feature its still in the code but its up to you to change it, DON'T ask me I wont help you with that.
The majority of the code using the presets hasn't changed from Stan's code, just some of the bank selections to make the eeprom routines function in the 16F648A.
This is why there is still 15 presets even though both the 16F6X8's have heaps more eeprom, I figured 15 yeah why not if you want more you can but how many presets does one really need.
The timing routines are as per Stan's code so look there, the only difference is that I have changed the interrupt.
In fact I found an error in Stan's code, the interrupt didn't restore the W register upon exiting, W_TEMP was never recalled.
This caused me lots of issues with lock ups until I found it, kept thinking I made a mistake.
The majority of the changes between my code and stan's consists of program directives to suit the 16F648A and then I made a bunch of changes as I started to understand how the code worked.
Firstly I made Stan's code auto restart that was easy, then my samples arrived and I think that's when I migrated Stans code code to the 16F648A. No, this wasn't as easy as I thought it would be, it didn't work even with the directives etc correct for the new uP. Turns out the eeprom uses different bank selection to the 16F84A hmmm..... more reading, fixed that.
Then I added a zero bit blanking routine to least the significant digits to make the display more appealing.
At some stage I implemented the SLEEP command which was simple enough, then I had to wake it up. This was also simple to achieve with the INTCON RBIE - wake on PORTB command. i.e.. START button wakes uP. As a direct result I realized that an auto shutdown routine could be implemented and this also was added.
Knowing that the 16F6X8 series had more I/O pins I worked towards obtaining more pins. The balanced speaker output drive was reduced to one pin and moved. The Select and set functions were combined to reduce switches and pins. Once I had at least 7 spare I/O pins I implemented a lookup table to do the job of the 4511 decoder.
This was not easy at all for a beginner but I love a challenge, after lots of reading and a post on Microchip forums I had it solved.
After all of that it was left for a while until a friend tried to use it at which point I noticed that he was having trouble setting it. He said it was to rush rush, I agreed and changed the code to use the two buttons to set the preset times, sorry Stan.
I don't intend to go into long descriptions of the code used like Bruce did , even though he did a great job. Honestly without it I would have been stuffed, read it then read it again. I have commented the ASM file reasonably well, but I'm sure there are errors there too. I commend both Stan ockers and or Bruce Gennette on a good piece of work and wonder if the interrupt issue was on purpose somehow. As was in the original text "The moral ... just because something looks like it is working doesn't mean it actually is." I have followed the SUGGESTED MODIFICATIONS albeit in a different direction but the premise is still there.
I welcome anyone to do what I did and improve this project, LCD etc or just clean it up. For example what can it do if both buttons are pressed at the same time?
I have noticed that the code is all over the place in Notepad however when loaded into MPASM it looks perfect.
Hi stan thanks for the work you did. If you go to format in Notepad and select Word wrap the code looks goodBrendon Archibald replies: Thanks for that gogo although I'm not Stan, he did the original project. Yes wordwrap cleans it up a little but it still displays better in MPLAB. Further comments are welcome and I dont mind being contacted directly.+
Thank You Again
|file: /Techref/microchip/cntdn/restart.htm, 9KB, , updated: 2008/12/2 01:04, local time: 2020/7/5 06:35,
|©2020 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?|
<A HREF="http://massmind.org/techref/microchip/cntdn/restart.htm"> Brendon Archibald's Psychoanalytical (restarting countdown) Timer</A>
|Did you find what you needed?|
Welcome to massmind.org!
Welcome to massmind.org!